summaryrefslogtreecommitdiffstats
path: root/fdk-aac/libAACdec/src
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-11 11:38:02 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2019-11-11 11:38:02 +0100
commit0e5af65c467b2423a0b857ae3ad98c91acc1e190 (patch)
treed07f69550d8886271e44fe79c4dcfb299cafbd38 /fdk-aac/libAACdec/src
parentefe406d9724f959c8bc2a31802559ca6d41fd897 (diff)
downloadODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.tar.gz
ODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.tar.bz2
ODR-AudioEnc-0e5af65c467b2423a0b857ae3ad98c91acc1e190.zip
Include patched FDK-AAC in the repository
The initial idea was to get the DAB+ patch into upstream, but since that follows the android source releases, there is no place for a custom DAB+ patch there. So instead of having to maintain a patched fdk-aac that has to have the same .so version as the distribution package on which it is installed, we prefer having a separate fdk-aac-dab library to avoid collision. At that point, there's no reason to keep fdk-aac in a separate repository, as odr-audioenc is the only tool that needs DAB+ encoding support. Including it here simplifies installation, and makes it consistent with toolame-dab, also shipped in this repository. DAB+ decoding support (needed by ODR-SourceCompanion, dablin, etisnoop, welle.io and others) can be done using upstream FDK-AAC.
Diffstat (limited to 'fdk-aac/libAACdec/src')
-rw-r--r--fdk-aac/libAACdec/src/FDK_delay.cpp173
-rw-r--r--fdk-aac/libAACdec/src/FDK_delay.h152
-rw-r--r--fdk-aac/libAACdec/src/aac_ram.cpp185
-rw-r--r--fdk-aac/libAACdec/src/aac_ram.h147
-rw-r--r--fdk-aac/libAACdec/src/aac_rom.cpp3428
-rw-r--r--fdk-aac/libAACdec/src/aac_rom.h237
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc.cpp1355
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc.h192
-rw-r--r--fdk-aac/libAACdec/src/aacdec_drc_types.h220
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr.cpp1498
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr.h128
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp164
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_bit.h114
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcr_types.h432
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcrs.cpp1551
-rw-r--r--fdk-aac/libAACdec/src/aacdec_hcrs.h176
-rw-r--r--fdk-aac/libAACdec/src/aacdec_pns.cpp361
-rw-r--r--fdk-aac/libAACdec/src/aacdec_pns.h129
-rw-r--r--fdk-aac/libAACdec/src/aacdec_tns.cpp361
-rw-r--r--fdk-aac/libAACdec/src/aacdec_tns.h149
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder.cpp3464
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder.h465
-rw-r--r--fdk-aac/libAACdec/src/aacdecoder_lib.cpp2035
-rw-r--r--fdk-aac/libAACdec/src/arm/block_arm.cpp142
-rw-r--r--fdk-aac/libAACdec/src/block.cpp1260
-rw-r--r--fdk-aac/libAACdec/src/block.h345
-rw-r--r--fdk-aac/libAACdec/src/channel.cpp924
-rw-r--r--fdk-aac/libAACdec/src/channel.h160
-rw-r--r--fdk-aac/libAACdec/src/channelinfo.cpp297
-rw-r--r--fdk-aac/libAACdec/src/channelinfo.h564
-rw-r--r--fdk-aac/libAACdec/src/conceal.cpp2095
-rw-r--r--fdk-aac/libAACdec/src/conceal.h152
-rw-r--r--fdk-aac/libAACdec/src/conceal_types.h203
-rw-r--r--fdk-aac/libAACdec/src/ldfiltbank.cpp276
-rw-r--r--fdk-aac/libAACdec/src/ldfiltbank.h112
-rw-r--r--fdk-aac/libAACdec/src/overlapadd.h120
-rw-r--r--fdk-aac/libAACdec/src/pulsedata.cpp164
-rw-r--r--fdk-aac/libAACdec/src/pulsedata.h150
-rw-r--r--fdk-aac/libAACdec/src/rvlc.cpp1217
-rw-r--r--fdk-aac/libAACdec/src/rvlc.h153
-rw-r--r--fdk-aac/libAACdec/src/rvlc_info.h204
-rw-r--r--fdk-aac/libAACdec/src/rvlcbit.cpp148
-rw-r--r--fdk-aac/libAACdec/src/rvlcbit.h111
-rw-r--r--fdk-aac/libAACdec/src/rvlcconceal.cpp787
-rw-r--r--fdk-aac/libAACdec/src/rvlcconceal.h127
-rw-r--r--fdk-aac/libAACdec/src/stereo.cpp1250
-rw-r--r--fdk-aac/libAACdec/src/stereo.h211
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp439
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_d4t64.h117
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp229
-rw-r--r--fdk-aac/libAACdec/src/usacdec_ace_ltp.h128
-rw-r--r--fdk-aac/libAACdec/src/usacdec_acelp.cpp1296
-rw-r--r--fdk-aac/libAACdec/src/usacdec_acelp.h281
-rw-r--r--fdk-aac/libAACdec/src/usacdec_const.h203
-rw-r--r--fdk-aac/libAACdec/src/usacdec_fac.cpp745
-rw-r--r--fdk-aac/libAACdec/src/usacdec_fac.h191
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpc.cpp1194
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpc.h190
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpd.cpp2029
-rw-r--r--fdk-aac/libAACdec/src/usacdec_lpd.h198
-rw-r--r--fdk-aac/libAACdec/src/usacdec_rom.cpp1504
-rw-r--r--fdk-aac/libAACdec/src/usacdec_rom.h154
62 files changed, 37186 insertions, 0 deletions
diff --git a/fdk-aac/libAACdec/src/FDK_delay.cpp b/fdk-aac/libAACdec/src/FDK_delay.cpp
new file mode 100644
index 0000000..0ab1a66
--- /dev/null
+++ b/fdk-aac/libAACdec/src/FDK_delay.cpp
@@ -0,0 +1,173 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description:
+
+*******************************************************************************/
+
+#include "FDK_delay.h"
+
+#include "genericStds.h"
+
+#define MAX_FRAME_LENGTH (1024)
+
+INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
+ const UCHAR num_channels) {
+ FDK_ASSERT(data != NULL);
+ FDK_ASSERT(num_channels > 0);
+
+ if (delay > 0) {
+ data->delay_line =
+ (INT_PCM*)FDKcalloc(num_channels * delay, sizeof(INT_PCM));
+ if (data->delay_line == NULL) {
+ return -1;
+ }
+ } else {
+ data->delay_line = NULL;
+ }
+ data->num_channels = num_channels;
+ data->delay = delay;
+
+ return 0;
+}
+
+void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
+ const UINT frame_length, const UCHAR channel) {
+ FDK_ASSERT(data != NULL);
+
+ if (data->delay > 0) {
+ C_ALLOC_SCRATCH_START(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
+ FDK_ASSERT(frame_length <= MAX_FRAME_LENGTH);
+ FDK_ASSERT(channel < data->num_channels);
+ FDK_ASSERT(time_buffer != NULL);
+ if (frame_length >= data->delay) {
+ FDKmemcpy(tmp, &time_buffer[frame_length - data->delay],
+ data->delay * sizeof(FIXP_PCM));
+ FDKmemmove(&time_buffer[data->delay], &time_buffer[0],
+ (frame_length - data->delay) * sizeof(FIXP_PCM));
+ FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
+ data->delay * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay], tmp,
+ data->delay * sizeof(FIXP_PCM));
+ } else {
+ FDKmemcpy(tmp, &time_buffer[0], frame_length * sizeof(FIXP_PCM));
+ FDKmemcpy(&time_buffer[0], &data->delay_line[channel * data->delay],
+ frame_length * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay],
+ &data->delay_line[channel * data->delay + frame_length],
+ (data->delay - frame_length) * sizeof(FIXP_PCM));
+ FDKmemcpy(&data->delay_line[channel * data->delay +
+ (data->delay - frame_length)],
+ tmp, frame_length * sizeof(FIXP_PCM));
+ }
+ C_ALLOC_SCRATCH_END(tmp, FIXP_PCM, MAX_FRAME_LENGTH)
+ }
+
+ return;
+}
+
+void FDK_Delay_Destroy(FDK_SignalDelay* data) {
+ if (data->delay_line != NULL) {
+ FDKfree(data->delay_line);
+ }
+ data->delay_line = NULL;
+ data->delay = 0;
+ data->num_channels = 0;
+
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/FDK_delay.h b/fdk-aac/libAACdec/src/FDK_delay.h
new file mode 100644
index 0000000..f89c3a2
--- /dev/null
+++ b/fdk-aac/libAACdec/src/FDK_delay.h
@@ -0,0 +1,152 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef FDK_DELAY_H
+#define FDK_DELAY_H
+
+#include "aac_rom.h"
+
+/**
+ * Structure representing one delay element for multiple channels.
+ */
+typedef struct {
+ INT_PCM* delay_line; /*!< Pointer which stores allocated delay line. */
+ USHORT delay; /*!< Delay required in samples (per channel). */
+ UCHAR num_channels; /*!< Number of channels to delay. */
+} FDK_SignalDelay;
+
+/**
+ * \brief Create delay element for multiple channels with fixed delay value.
+ *
+ * \param data Pointer delay element structure.
+ * \param delay Required delay value in samples per channel.
+ * \param num_channels Required number of channels.
+ *
+ * \return -1 on out of memory, else 0
+ */
+INT FDK_Delay_Create(FDK_SignalDelay* data, const USHORT delay,
+ const UCHAR num_channels);
+
+/**
+ * \brief Apply delay to one channel (non-interleaved storage assumed).
+ *
+ * \param data Pointer delay element structure.
+ * \param time_buffer Pointer to signal to delay.
+ * \param frame_length Frame length of input/output signal (needs to be >=
+ * delay).
+ * \param channel Index of current channel (0 <= channel < num_channels).
+ *
+ * \return void
+ */
+void FDK_Delay_Apply(FDK_SignalDelay* data, FIXP_PCM* time_buffer,
+ const UINT frame_length, const UCHAR channel);
+
+/**
+ * \brief Destroy delay element.
+ *
+ * \param data Pointer delay element structure.
+ *
+ * \return void
+ */
+void FDK_Delay_Destroy(FDK_SignalDelay* data);
+
+#endif /* #ifndef FDK_DELAY_H */
diff --git a/fdk-aac/libAACdec/src/aac_ram.cpp b/fdk-aac/libAACdec/src/aac_ram.cpp
new file mode 100644
index 0000000..e13167d
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_ram.cpp
@@ -0,0 +1,185 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#include "aac_ram.h"
+#include "aac_rom.h"
+
+#define WORKBUFFER1_TAG 0
+#define WORKBUFFER2_TAG 1
+
+#define WORKBUFFER3_TAG 4
+#define WORKBUFFER4_TAG 5
+
+#define WORKBUFFER5_TAG 6
+
+#define WORKBUFFER6_TAG 7
+
+/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all
+ decoder configurations, handles and structs.
+ */
+C_ALLOC_MEM(AacDecoder, struct AAC_DECODER_INSTANCE, 1)
+
+/*!
+ \name StaticAacData
+
+ Static memory areas, must not be overwritten in other sections of the decoder
+*/
+/* @{ */
+
+/*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo
+ which is needed for the decoding of one aac channel. <br> Dimension:
+ #AacDecoderChannels */
+C_ALLOC_MEM2(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo, 1, (8))
+
+/*! The structure CAacDecoderChannelInfo contains the dynamic sideinfo which is
+ needed for the decoding of one aac channel. <br> Dimension:
+ #AacDecoderChannels */
+C_AALLOC_MEM2(AacDecoderChannelInfo, CAacDecoderChannelInfo, 1, (8))
+
+/*! Overlap buffer */
+C_AALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (8))
+
+C_ALLOC_MEM(DrcInfo, CDrcInfo, 1)
+
+/*! The structure CpePersistentData holds the persistent data shared by both
+ channels of a CPE. <br> It needs to be allocated for each CPE. <br>
+ Dimension: 1 */
+C_ALLOC_MEM(CpePersistentData, CpePersistentData, 1)
+
+/*! The structure CCplxPredictionData holds data for complex stereo prediction.
+ <br> Dimension: 1
+ */
+C_ALLOC_MEM(CplxPredictionData, CCplxPredictionData, 1)
+
+/*! The buffer holds time samples for the crossfade in case of an USAC DASH IPF
+ config change Dimension: (8)
+ */
+C_ALLOC_MEM2(TimeDataFlush, INT_PCM, TIME_DATA_FLUSH_SIZE, (8))
+
+/* @} */
+
+/*!
+ \name DynamicAacData
+
+ Dynamic memory areas, might be reused in other algorithm sections,
+ e.g. the sbr decoder
+*/
+
+/* Take into consideration to make use of the WorkBufferCore[3/4] for decoder
+ * configurations with more than 2 channels */
+C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8) * 1024), SECT_DATA_L2,
+ WORKBUFFER2_TAG)
+
+C_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL, WB_SECTION_SIZE, SECT_DATA_L2,
+ WORKBUFFER3_TAG)
+C_AALLOC_MEM(WorkBufferCore4, FIXP_DBL, WB_SECTION_SIZE)
+C_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR,
+ fMax((INT)(sizeof(FIXP_DBL) * WB_SECTION_SIZE),
+ (INT)sizeof(CAacDecoderCommonData)),
+ SECT_DATA_L2, WORKBUFFER6_TAG)
+
+C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1,
+ WORKBUFFER1_TAG)
+
+/* double buffer size needed for de-/interleaving */
+C_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC, (8) * (1024 * 4) * 2,
+ SECT_DATA_EXTERN, WORKBUFFER5_TAG)
diff --git a/fdk-aac/libAACdec/src/aac_ram.h b/fdk-aac/libAACdec/src/aac_ram.h
new file mode 100644
index 0000000..a861e25
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_ram.h
@@ -0,0 +1,147 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef AAC_RAM_H
+#define AAC_RAM_H
+
+#include "common_fix.h"
+
+#include "aacdecoder.h"
+
+#include "channel.h"
+
+#include "ac_arith_coder.h"
+
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcr.h"
+
+/* End of formal fix.h */
+
+#define MAX_SYNCHS 10
+#define SAMPL_FREQS 12
+
+H_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE)
+
+H_ALLOC_MEM(DrcInfo, CDrcInfo)
+
+H_ALLOC_MEM(AacDecoderStaticChannelInfo, CAacDecoderStaticChannelInfo)
+H_ALLOC_MEM(AacDecoderChannelInfo, CAacDecoderChannelInfo)
+H_ALLOC_MEM(OverlapBuffer, FIXP_DBL)
+
+H_ALLOC_MEM(CpePersistentData, CpePersistentData)
+H_ALLOC_MEM(CplxPredictionData, CCplxPredictionData)
+H_ALLOC_MEM(SpectralCoeffs, FIXP_DBL)
+H_ALLOC_MEM(SpecScale, SHORT)
+
+H_ALLOC_MEM(TimeDataFlush, INT_PCM)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1)
+H_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore3, FIXP_DBL)
+H_ALLOC_MEM(WorkBufferCore4, FIXP_DBL)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore5, PCM_DEC)
+
+H_ALLOC_MEM_OVERLAY(WorkBufferCore6, SCHAR)
+
+#endif /* #ifndef AAC_RAM_H */
diff --git a/fdk-aac/libAACdec/src/aac_rom.cpp b/fdk-aac/libAACdec/src/aac_rom.cpp
new file mode 100644
index 0000000..cbdffc4
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_rom.cpp
@@ -0,0 +1,3428 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl, Tobias Chalupka
+
+ Description: Definition of constant tables
+
+*******************************************************************************/
+
+#include "aac_rom.h"
+
+/* Prescale InverseQuantTable by 4 to save
+ redundant shifts in invers quantization
+ */
+#define SCL_TAB(a) (a >> 4)
+const FIXP_DBL InverseQuantTable[INV_QUANT_TABLESIZE + 1] = {
+ SCL_TAB(0x32CBFD40), SCL_TAB(0x330FC340), SCL_TAB(0x33539FC0),
+ SCL_TAB(0x33979280), SCL_TAB(0x33DB9BC0), SCL_TAB(0x341FBB80),
+ SCL_TAB(0x3463F180), SCL_TAB(0x34A83DC0), SCL_TAB(0x34ECA000),
+ SCL_TAB(0x35311880), SCL_TAB(0x3575A700), SCL_TAB(0x35BA4B80),
+ SCL_TAB(0x35FF0600), SCL_TAB(0x3643D680), SCL_TAB(0x3688BCC0),
+ SCL_TAB(0x36CDB880), SCL_TAB(0x3712CA40), SCL_TAB(0x3757F1C0),
+ SCL_TAB(0x379D2F00), SCL_TAB(0x37E28180), SCL_TAB(0x3827E9C0),
+ SCL_TAB(0x386D6740), SCL_TAB(0x38B2FA40), SCL_TAB(0x38F8A2C0),
+ SCL_TAB(0x393E6080), SCL_TAB(0x39843380), SCL_TAB(0x39CA1BC0),
+ SCL_TAB(0x3A101940), SCL_TAB(0x3A562BC0), SCL_TAB(0x3A9C5340),
+ SCL_TAB(0x3AE28FC0), SCL_TAB(0x3B28E180), SCL_TAB(0x3B6F4800),
+ SCL_TAB(0x3BB5C340), SCL_TAB(0x3BFC5380), SCL_TAB(0x3C42F880),
+ SCL_TAB(0x3C89B200), SCL_TAB(0x3CD08080), SCL_TAB(0x3D176340),
+ SCL_TAB(0x3D5E5B00), SCL_TAB(0x3DA56700), SCL_TAB(0x3DEC87C0),
+ SCL_TAB(0x3E33BCC0), SCL_TAB(0x3E7B0640), SCL_TAB(0x3EC26400),
+ SCL_TAB(0x3F09D640), SCL_TAB(0x3F515C80), SCL_TAB(0x3F98F740),
+ SCL_TAB(0x3FE0A600), SCL_TAB(0x40286900), SCL_TAB(0x40704000),
+ SCL_TAB(0x40B82B00), SCL_TAB(0x41002A00), SCL_TAB(0x41483D00),
+ SCL_TAB(0x41906400), SCL_TAB(0x41D89F00), SCL_TAB(0x4220ED80),
+ SCL_TAB(0x42695000), SCL_TAB(0x42B1C600), SCL_TAB(0x42FA5000),
+ SCL_TAB(0x4342ED80), SCL_TAB(0x438B9E80), SCL_TAB(0x43D46380),
+ SCL_TAB(0x441D3B80), SCL_TAB(0x44662780), SCL_TAB(0x44AF2680),
+ SCL_TAB(0x44F83900), SCL_TAB(0x45415F00), SCL_TAB(0x458A9880),
+ SCL_TAB(0x45D3E500), SCL_TAB(0x461D4500), SCL_TAB(0x4666B800),
+ SCL_TAB(0x46B03E80), SCL_TAB(0x46F9D800), SCL_TAB(0x47438480),
+ SCL_TAB(0x478D4400), SCL_TAB(0x47D71680), SCL_TAB(0x4820FC00),
+ SCL_TAB(0x486AF500), SCL_TAB(0x48B50000), SCL_TAB(0x48FF1E80),
+ SCL_TAB(0x49494F80), SCL_TAB(0x49939380), SCL_TAB(0x49DDEA80),
+ SCL_TAB(0x4A285400), SCL_TAB(0x4A72D000), SCL_TAB(0x4ABD5E80),
+ SCL_TAB(0x4B080000), SCL_TAB(0x4B52B400), SCL_TAB(0x4B9D7A80),
+ SCL_TAB(0x4BE85380), SCL_TAB(0x4C333F00), SCL_TAB(0x4C7E3D00),
+ SCL_TAB(0x4CC94D00), SCL_TAB(0x4D146F80), SCL_TAB(0x4D5FA500),
+ SCL_TAB(0x4DAAEC00), SCL_TAB(0x4DF64580), SCL_TAB(0x4E41B180),
+ SCL_TAB(0x4E8D2F00), SCL_TAB(0x4ED8BF80), SCL_TAB(0x4F246180),
+ SCL_TAB(0x4F701600), SCL_TAB(0x4FBBDC00), SCL_TAB(0x5007B480),
+ SCL_TAB(0x50539F00), SCL_TAB(0x509F9B80), SCL_TAB(0x50EBA980),
+ SCL_TAB(0x5137C980), SCL_TAB(0x5183FB80), SCL_TAB(0x51D03F80),
+ SCL_TAB(0x521C9500), SCL_TAB(0x5268FC80), SCL_TAB(0x52B57580),
+ SCL_TAB(0x53020000), SCL_TAB(0x534E9C80), SCL_TAB(0x539B4A80),
+ SCL_TAB(0x53E80A80), SCL_TAB(0x5434DB80), SCL_TAB(0x5481BE80),
+ SCL_TAB(0x54CEB280), SCL_TAB(0x551BB880), SCL_TAB(0x5568CF80),
+ SCL_TAB(0x55B5F800), SCL_TAB(0x56033200), SCL_TAB(0x56507D80),
+ SCL_TAB(0x569DDA00), SCL_TAB(0x56EB4800), SCL_TAB(0x5738C700),
+ SCL_TAB(0x57865780), SCL_TAB(0x57D3F900), SCL_TAB(0x5821AC00),
+ SCL_TAB(0x586F7000), SCL_TAB(0x58BD4500), SCL_TAB(0x590B2B00),
+ SCL_TAB(0x59592200), SCL_TAB(0x59A72A80), SCL_TAB(0x59F54380),
+ SCL_TAB(0x5A436D80), SCL_TAB(0x5A91A900), SCL_TAB(0x5ADFF500),
+ SCL_TAB(0x5B2E5180), SCL_TAB(0x5B7CBF80), SCL_TAB(0x5BCB3E00),
+ SCL_TAB(0x5C19CD00), SCL_TAB(0x5C686D80), SCL_TAB(0x5CB71E00),
+ SCL_TAB(0x5D05DF80), SCL_TAB(0x5D54B200), SCL_TAB(0x5DA39500),
+ SCL_TAB(0x5DF28880), SCL_TAB(0x5E418C80), SCL_TAB(0x5E90A100),
+ SCL_TAB(0x5EDFC680), SCL_TAB(0x5F2EFC00), SCL_TAB(0x5F7E4280),
+ SCL_TAB(0x5FCD9900), SCL_TAB(0x601D0080), SCL_TAB(0x606C7800),
+ SCL_TAB(0x60BC0000), SCL_TAB(0x610B9800), SCL_TAB(0x615B4100),
+ SCL_TAB(0x61AAF980), SCL_TAB(0x61FAC300), SCL_TAB(0x624A9C80),
+ SCL_TAB(0x629A8600), SCL_TAB(0x62EA8000), SCL_TAB(0x633A8A00),
+ SCL_TAB(0x638AA480), SCL_TAB(0x63DACF00), SCL_TAB(0x642B0980),
+ SCL_TAB(0x647B5400), SCL_TAB(0x64CBAE80), SCL_TAB(0x651C1900),
+ SCL_TAB(0x656C9400), SCL_TAB(0x65BD1E80), SCL_TAB(0x660DB900),
+ SCL_TAB(0x665E6380), SCL_TAB(0x66AF1E00), SCL_TAB(0x66FFE880),
+ SCL_TAB(0x6750C280), SCL_TAB(0x67A1AC80), SCL_TAB(0x67F2A600),
+ SCL_TAB(0x6843B000), SCL_TAB(0x6894C900), SCL_TAB(0x68E5F200),
+ SCL_TAB(0x69372B00), SCL_TAB(0x69887380), SCL_TAB(0x69D9CB80),
+ SCL_TAB(0x6A2B3300), SCL_TAB(0x6A7CAA80), SCL_TAB(0x6ACE3180),
+ SCL_TAB(0x6B1FC800), SCL_TAB(0x6B716E00), SCL_TAB(0x6BC32400),
+ SCL_TAB(0x6C14E900), SCL_TAB(0x6C66BD80), SCL_TAB(0x6CB8A180),
+ SCL_TAB(0x6D0A9500), SCL_TAB(0x6D5C9800), SCL_TAB(0x6DAEAA00),
+ SCL_TAB(0x6E00CB80), SCL_TAB(0x6E52FC80), SCL_TAB(0x6EA53D00),
+ SCL_TAB(0x6EF78C80), SCL_TAB(0x6F49EB80), SCL_TAB(0x6F9C5980),
+ SCL_TAB(0x6FEED700), SCL_TAB(0x70416380), SCL_TAB(0x7093FF00),
+ SCL_TAB(0x70E6AA00), SCL_TAB(0x71396400), SCL_TAB(0x718C2D00),
+ SCL_TAB(0x71DF0580), SCL_TAB(0x7231ED00), SCL_TAB(0x7284E300),
+ SCL_TAB(0x72D7E880), SCL_TAB(0x732AFD00), SCL_TAB(0x737E2080),
+ SCL_TAB(0x73D15300), SCL_TAB(0x74249480), SCL_TAB(0x7477E480),
+ SCL_TAB(0x74CB4400), SCL_TAB(0x751EB200), SCL_TAB(0x75722F00),
+ SCL_TAB(0x75C5BB00), SCL_TAB(0x76195580), SCL_TAB(0x766CFF00),
+ SCL_TAB(0x76C0B700), SCL_TAB(0x77147E00), SCL_TAB(0x77685400),
+ SCL_TAB(0x77BC3880), SCL_TAB(0x78102B80), SCL_TAB(0x78642D80),
+ SCL_TAB(0x78B83E00), SCL_TAB(0x790C5D00), SCL_TAB(0x79608B00),
+ SCL_TAB(0x79B4C780), SCL_TAB(0x7A091280), SCL_TAB(0x7A5D6C00),
+ SCL_TAB(0x7AB1D400), SCL_TAB(0x7B064A80), SCL_TAB(0x7B5ACF80),
+ SCL_TAB(0x7BAF6380), SCL_TAB(0x7C040580), SCL_TAB(0x7C58B600),
+ SCL_TAB(0x7CAD7500), SCL_TAB(0x7D024200), SCL_TAB(0x7D571E00),
+ SCL_TAB(0x7DAC0800), SCL_TAB(0x7E010080), SCL_TAB(0x7E560780),
+ SCL_TAB(0x7EAB1C80), SCL_TAB(0x7F004000), SCL_TAB(0x7F557200),
+ SCL_TAB(0x7FAAB200), SCL_TAB(0x7FFFFFFF)};
+
+/**
+ * \brief Table representing scale factor gains. Given a scale factor sf, and a
+ * value pSpec[i] the gain is given by: MantissaTable[sf % 4][msb] = 2^(sf % 4)
+ * / (1<<ExponentTable[sf % 4][msb] The second dimension "msb" represents the
+ * upper scale factor bit count floor(log2(scalefactor >> 2)) The corresponding
+ * exponents for the values in this tables are stored in ExponentTable[sf %
+ * 4][msb] below.
+ */
+const FIXP_DBL MantissaTable[4][14] = {
+ {0x40000000, 0x50A28C00, 0x6597FA80, 0x40000000, 0x50A28C00, 0x6597FA80,
+ 0x40000000, 0x50A28C00, 0x6597FA80, 0x40000000, 0x50A28C00, 0x6597FA80,
+ 0x40000000, 0x50A28C00},
+ {0x4C1BF800, 0x5FE44380, 0x78D0DF80, 0x4C1BF800, 0x5FE44380, 0x78D0DF80,
+ 0x4C1BF800, 0x5FE44380, 0x78D0DF80, 0x4C1BF800, 0x5FE44380, 0x78D0DF80,
+ 0x4C1BF800, 0x5FE44380},
+ {0x5A827980, 0x7208F800, 0x47D66B00, 0x5A827980, 0x7208F800, 0x47D66B00,
+ 0x5A827980, 0x7208F800, 0x47D66B00, 0x5A827980, 0x7208F800, 0x47D66B00,
+ 0x5A827980, 0x7208F800},
+ {0x6BA27E80, 0x43CE3E80, 0x556E0400, 0x6BA27E80, 0x43CE3E80, 0x556E0400,
+ 0x6BA27E80, 0x43CE3E80, 0x556E0400, 0x6BA27E80, 0x43CE3E80, 0x556E0400,
+ 0x6BA27E80, 0x43CE3E80}};
+
+const SCHAR ExponentTable[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}};
+
+/* 41 scfbands */
+static const SHORT sfb_96_1024[42] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 156, 172, 188, 212,
+ 240, 276, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024};
+/* 12 scfbands */
+static const SHORT sfb_96_128[13] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 128};
+
+/* 47 scfbands*/
+static const SHORT sfb_64_1024[48] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 48, 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, 156,
+ 172, 192, 216, 240, 268, 304, 344, 384, 424, 464, 504, 544,
+ 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024};
+
+/* 12 scfbands */
+static const SHORT sfb_64_128[13] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 128};
+
+/* 49 scfbands */
+static const SHORT sfb_48_1024[50] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024};
+/* 14 scfbands */
+static const SHORT sfb_48_128[15] = {0, 4, 8, 12, 16, 20, 28, 36,
+ 44, 56, 68, 80, 96, 112, 128};
+
+/* 51 scfbands */
+static const SHORT sfb_32_1024[52] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024};
+
+/* 47 scfbands */
+static const SHORT sfb_24_1024[48] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_24_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 108, 128};
+
+/* 43 scfbands */
+static const SHORT sfb_16_1024[44] = {
+ 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 100, 112, 124,
+ 136, 148, 160, 172, 184, 196, 212, 228, 244, 260, 280, 300, 320, 344, 368,
+ 396, 424, 456, 492, 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_16_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 108, 128};
+
+/* 40 scfbands */
+static const SHORT sfb_8_1024[41] = {
+ 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156,
+ 172, 188, 204, 220, 236, 252, 268, 288, 308, 328, 348, 372, 396, 420,
+ 448, 476, 508, 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024};
+
+/* 15 scfbands */
+static const SHORT sfb_8_128[16] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 108, 128};
+
+static const SHORT
+ sfb_96_960[42] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 48, 52, 56, 64, 72, 80, 88, 96, 108, 120,
+ 132, 144, 156, 172, 188, 212, 240, 276, 320, 384, 448,
+ 512, 576, 640, 704, 768, 832, 896, 960}; /* 40 scfbands */
+
+static const SHORT sfb_96_120[13] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 120}; /* 12 scfbands */
+
+static const SHORT sfb_64_960[47] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 48, 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, 156,
+ 172, 192, 216, 240, 268, 304, 344, 384, 424, 464, 504, 544,
+ 584, 624, 664, 704, 744, 784, 824, 864, 904, 944, 960}; /* 46 scfbands */
+
+static const SHORT sfb_64_120[13] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 120}; /* 12 scfbands */
+
+static const SHORT sfb_48_960[50] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960}; /* 49 scfbands */
+static const SHORT sfb_48_120[15] = {
+ 0, 4, 8, 12, 16, 20, 28, 36,
+ 44, 56, 68, 80, 96, 112, 120}; /* 14 scfbands */
+
+static const SHORT sfb_32_960[50] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56,
+ 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176, 196, 216,
+ 240, 264, 292, 320, 352, 384, 416, 448, 480, 512, 544, 576, 608,
+ 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960}; /* 49 scfbands */
+
+static const SHORT sfb_24_960[47] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768, 832, 896, 960}; /* 46 scfbands */
+
+static const SHORT sfb_24_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 108, 120}; /* 15 scfbands */
+
+static const SHORT sfb_16_960[43] = {0, 8, 16, 24, 32, 40, 48, 56,
+ 64, 72, 80, 88, 100, 112, 124, 136,
+ 148, 160, 172, 184, 196, 212, 228, 244,
+ 260, 280, 300, 320, 344, 368, 396, 424,
+ 456, 492, 532, 572, 616, 664, 716, 772,
+ 832, 896, 960}; /* 42 scfbands */
+
+static const SHORT sfb_16_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 108, 120}; /* 15 scfbands */
+
+static const SHORT sfb_8_960[41] = {0, 12, 24, 36, 48, 60, 72, 84, 96,
+ 108, 120, 132, 144, 156, 172, 188, 204, 220,
+ 236, 252, 268, 288, 308, 328, 348, 372, 396,
+ 420, 448, 476, 508, 544, 580, 620, 664, 712,
+ 764, 820, 880, 944, 960}; /* 40 scfbands */
+
+static const SHORT sfb_8_120[16] = {
+ 0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 108, 120}; /* 15 scfbands */
+
+static const SHORT
+ sfb_96_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 156, 172, 188, 212, 240, 276,
+ 320, 384, 448, 512, 576, 640, 704, 768}; /* 37 scfbands */
+static const SHORT sfb_96_96[] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 96}; /* 12 scfbands */
+
+static const SHORT sfb_64_768[] =
+ {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 48, 52, 56, 64, 72, 80, 88, 100, 112, 124,
+ 140, 156, 172, 192, 216, 240, 268, 304, 344, 384, 424,
+ 464, 504, 544, 584, 624, 664, 704, 744, 768}; /* 41 scfbands */
+
+static const SHORT sfb_64_96[] = {0, 4, 8, 12, 16, 20, 24,
+ 32, 40, 48, 64, 92, 96}; /* 12 scfbands */
+
+static const SHORT
+ sfb_48_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48,
+ 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176,
+ 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512,
+ 544, 576, 608, 640, 672, 704, 736, 768}; /* 43 scfbands */
+
+static const SHORT sfb_48_96[] = {0, 4, 8, 12, 16, 20, 28,
+ 36, 44, 56, 68, 80, 96}; /* 12 scfbands */
+
+static const SHORT
+ sfb_32_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48,
+ 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, 176,
+ 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, 512,
+ 544, 576, 608, 640, 672, 704, 736, 768}; /* 43 scfbands */
+
+static const SHORT
+ sfb_24_768[] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44,
+ 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148,
+ 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396,
+ 432, 468, 508, 552, 600, 652, 704, 768}; /* 43 scfbands */
+
+static const SHORT sfb_24_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 64, 76, 92, 96}; /* 14 scfbands */
+
+static const SHORT sfb_16_768[] = {0, 8, 16, 24, 32, 40, 48, 56, 64,
+ 72, 80, 88, 100, 112, 124, 136, 148, 160,
+ 172, 184, 196, 212, 228, 244, 260, 280, 300,
+ 320, 344, 368, 396, 424, 456, 492, 532, 572,
+ 616, 664, 716, 768}; /* 39 scfbands */
+
+static const SHORT sfb_16_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 40, 48, 60, 72, 88, 96}; /* 14 scfbands */
+
+static const SHORT
+ sfb_8_768[] = {0, 12, 24, 36, 48, 60, 72, 84, 96, 108,
+ 120, 132, 144, 156, 172, 188, 204, 220, 236, 252,
+ 268, 288, 308, 328, 348, 372, 396, 420, 448, 476,
+ 508, 544, 580, 620, 664, 712, 764, 768}; /* 37 scfbands */
+
+static const SHORT sfb_8_96[] = {0, 4, 8, 12, 16, 20, 24, 28,
+ 36, 44, 52, 60, 72, 88, 96}; /* 14 scfbands */
+
+static const SHORT sfb_48_512[37] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
+ 52, 56, 60, 68, 76, 84, 92, 100, 112, 124, 136, 148, 164,
+ 184, 208, 236, 268, 300, 332, 364, 396, 428, 460, 512}; /* 36 scfbands */
+static const SHORT
+ sfb_32_512[38] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,
+ 108, 120, 132, 144, 160, 176, 192, 212, 236, 260,
+ 288, 320, 352, 384, 416, 448, 480, 512}; /* 37 scfbands */
+static const SHORT sfb_24_512[32] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 52, 60, 68, 80, 92, 104, 120, 140, 164, 192,
+ 224, 256, 288, 320, 352, 384, 416, 448, 480, 512}; /* 31 scfbands */
+
+static const SHORT sfb_48_480[36] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
+ 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 156, 172,
+ 188, 212, 240, 272, 304, 336, 368, 400, 432, 480}; /* 35 scfbands */
+static const SHORT
+ sfb_32_480[38] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 48, 52, 56, 60, 64, 72, 80, 88,
+ 96, 104, 112, 124, 136, 148, 164, 180, 200, 224,
+ 256, 288, 320, 352, 384, 416, 448, 480}; /* 37 scfbands */
+static const SHORT sfb_24_480[31] =
+ {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40,
+ 44, 52, 60, 68, 80, 92, 104, 120, 140, 164, 192,
+ 224, 256, 288, 320, 352, 384, 416, 448, 480}; /* 30 scfbands */
+
+const SFB_INFO sfbOffsetTables[5][16] = {{
+ {sfb_96_1024, sfb_96_128, 41, 12},
+ {sfb_96_1024, sfb_96_128, 41, 12},
+ {sfb_64_1024, sfb_64_128, 47, 12},
+ {sfb_48_1024, sfb_48_128, 49, 14},
+ {sfb_48_1024, sfb_48_128, 49, 14},
+ {sfb_32_1024, sfb_48_128, 51, 14},
+ {sfb_24_1024, sfb_24_128, 47, 15},
+ {sfb_24_1024, sfb_24_128, 47, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_16_1024, sfb_16_128, 43, 15},
+ {sfb_8_1024, sfb_8_128, 40, 15},
+ {sfb_8_1024, sfb_8_128, 40, 15},
+ },
+ {
+ {sfb_96_960, sfb_96_120, 40, 12},
+ {sfb_96_960, sfb_96_120, 40, 12},
+ {sfb_64_960, sfb_64_120, 46, 12},
+ {sfb_48_960, sfb_48_120, 49, 14},
+ {sfb_48_960, sfb_48_120, 49, 14},
+ {sfb_32_960, sfb_48_120, 49, 14},
+ {sfb_24_960, sfb_24_120, 46, 15},
+ {sfb_24_960, sfb_24_120, 46, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_16_960, sfb_16_120, 42, 15},
+ {sfb_8_960, sfb_8_120, 40, 15},
+ {sfb_8_960, sfb_8_120, 40, 15},
+ },
+ {
+ {sfb_96_768, sfb_96_96, 37, 12},
+ {sfb_96_768, sfb_96_96, 37, 12},
+ {sfb_64_768, sfb_64_96, 41, 12},
+ {sfb_48_768, sfb_48_96, 43, 12},
+ {sfb_48_768, sfb_48_96, 43, 12},
+ {sfb_32_768, sfb_48_96, 43, 12},
+ {sfb_24_768, sfb_24_96, 43, 14},
+ {sfb_24_768, sfb_24_96, 43, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_16_768, sfb_16_96, 39, 14},
+ {sfb_8_768, sfb_8_96, 37, 14},
+ {sfb_8_768, sfb_8_96, 37, 14},
+ },
+ {
+ {sfb_48_512, NULL, 36, 0},
+ {sfb_48_512, NULL, 36, 0},
+ {sfb_48_512, NULL, 36, 0},
+ {sfb_48_512, NULL, 36, 0},
+ {sfb_48_512, NULL, 36, 0},
+ {sfb_32_512, NULL, 37, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ {sfb_24_512, NULL, 31, 0},
+ },
+ {
+ {sfb_48_480, NULL, 35, 0},
+ {sfb_48_480, NULL, 35, 0},
+ {sfb_48_480, NULL, 35, 0},
+ {sfb_48_480, NULL, 35, 0},
+ {sfb_48_480, NULL, 35, 0},
+ {sfb_32_480, NULL, 37, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ {sfb_24_480, NULL, 30, 0},
+ }};
+
+/*# don't use 1 bit hufman tables */
+/*
+ MPEG-2 AAC 2 BITS parallel Hufman Tables
+
+ Bit 0: = 1=ENDNODE, 0=INDEX
+ Bit 1: = CODEWORD LEN MOD 2
+ Bit 2..9: = VALUE/REF Tables 1..10,SCL
+ Bit 2..11: = VALUE/REF Table 11
+*/
+const USHORT HuffmanCodeBook_1[51][4] = {
+ {0x0157, 0x0157, 0x0004, 0x0018}, {0x0008, 0x000c, 0x0010, 0x0014},
+ {0x015b, 0x015b, 0x0153, 0x0153}, {0x0057, 0x0057, 0x0167, 0x0167},
+ {0x0257, 0x0257, 0x0117, 0x0117}, {0x0197, 0x0197, 0x0147, 0x0147},
+ {0x001c, 0x0030, 0x0044, 0x0058}, {0x0020, 0x0024, 0x0028, 0x002c},
+ {0x014b, 0x014b, 0x0163, 0x0163}, {0x0217, 0x0217, 0x0127, 0x0127},
+ {0x0187, 0x0187, 0x0097, 0x0097}, {0x016b, 0x016b, 0x0017, 0x0017},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x0143, 0x0143, 0x0107, 0x0107},
+ {0x011b, 0x011b, 0x0067, 0x0067}, {0x0193, 0x0193, 0x0297, 0x0297},
+ {0x019b, 0x019b, 0x0247, 0x0247}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x01a7, 0x01a7, 0x0267, 0x0267}, {0x0113, 0x0113, 0x025b, 0x025b},
+ {0x0053, 0x0053, 0x005b, 0x005b}, {0x0253, 0x0253, 0x0047, 0x0047},
+ {0x005c, 0x0070, 0x0084, 0x0098}, {0x0060, 0x0064, 0x0068, 0x006c},
+ {0x012b, 0x012b, 0x0123, 0x0123}, {0x018b, 0x018b, 0x00a7, 0x00a7},
+ {0x0227, 0x0227, 0x0287, 0x0287}, {0x0087, 0x0087, 0x010b, 0x010b},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x021b, 0x021b, 0x0027, 0x0027},
+ {0x01a3, 0x01a3, 0x0093, 0x0093}, {0x0183, 0x0183, 0x0207, 0x0207},
+ {0x024b, 0x024b, 0x004b, 0x004b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0063, 0x0063, 0x0103, 0x0103}, {0x0007, 0x0007, 0x02a7, 0x02a7},
+ {0x009b, 0x009b, 0x026b, 0x026b}, {0x0263, 0x0263, 0x01ab, 0x01ab},
+ {0x009c, 0x00a0, 0x00a4, 0x00b8}, {0x0241, 0x0011, 0x0069, 0x0019},
+ {0x0211, 0x0041, 0x0291, 0x0299}, {0x00a8, 0x00ac, 0x00b0, 0x00b4},
+ {0x008b, 0x008b, 0x0223, 0x0223}, {0x00a3, 0x00a3, 0x020b, 0x020b},
+ {0x02ab, 0x02ab, 0x0283, 0x0283}, {0x002b, 0x002b, 0x0083, 0x0083},
+ {0x00bc, 0x00c0, 0x00c4, 0x00c8}, {0x0003, 0x0003, 0x022b, 0x022b},
+ {0x028b, 0x028b, 0x02a3, 0x02a3}, {0x0023, 0x0023, 0x0203, 0x0203},
+ {0x000b, 0x000b, 0x00ab, 0x00ab}};
+
+const USHORT HuffmanCodeBook_2[39][4] = {
+ {0x0004, 0x000c, 0x0020, 0x0034}, {0x0157, 0x0157, 0x0159, 0x0008},
+ {0x0153, 0x0153, 0x0257, 0x0257}, {0x0010, 0x0014, 0x0018, 0x001c},
+ {0x0117, 0x0117, 0x0057, 0x0057}, {0x0147, 0x0147, 0x0197, 0x0197},
+ {0x0167, 0x0167, 0x0185, 0x0161}, {0x0125, 0x0095, 0x0065, 0x0215},
+ {0x0024, 0x0028, 0x002c, 0x0030}, {0x0051, 0x0149, 0x0119, 0x0141},
+ {0x0015, 0x0199, 0x0259, 0x0245}, {0x0191, 0x0265, 0x0105, 0x0251},
+ {0x0045, 0x0111, 0x0169, 0x01a5}, {0x0038, 0x0044, 0x0058, 0x006c},
+ {0x0295, 0x0059, 0x003c, 0x0040}, {0x0227, 0x0227, 0x021b, 0x021b},
+ {0x0123, 0x0123, 0x0087, 0x0087}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x018b, 0x018b, 0x006b, 0x006b}, {0x029b, 0x029b, 0x01a3, 0x01a3},
+ {0x0207, 0x0207, 0x01ab, 0x01ab}, {0x0093, 0x0093, 0x0103, 0x0103},
+ {0x005c, 0x0060, 0x0064, 0x0068}, {0x0213, 0x0213, 0x010b, 0x010b},
+ {0x012b, 0x012b, 0x0249, 0x0061}, {0x0181, 0x0291, 0x0241, 0x0041},
+ {0x0005, 0x0099, 0x0019, 0x0025}, {0x0070, 0x0074, 0x0078, 0x0088},
+ {0x02a5, 0x0261, 0x0011, 0x00a5}, {0x0049, 0x0285, 0x0269, 0x0089},
+ {0x0221, 0x007c, 0x0080, 0x0084}, {0x020b, 0x020b, 0x0003, 0x0003},
+ {0x00a3, 0x00a3, 0x02a3, 0x02a3}, {0x02ab, 0x02ab, 0x0083, 0x0083},
+ {0x008c, 0x0090, 0x0094, 0x0098}, {0x028b, 0x028b, 0x0023, 0x0023},
+ {0x0283, 0x0283, 0x002b, 0x002b}, {0x000b, 0x000b, 0x0203, 0x0203},
+ {0x022b, 0x022b, 0x00ab, 0x00ab}};
+
+const USHORT HuffmanCodeBook_3[39][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0005, 0x0101, 0x0011, 0x0041},
+ {0x000c, 0x0010, 0x0014, 0x0020}, {0x0017, 0x0017, 0x0143, 0x0143},
+ {0x0051, 0x0111, 0x0045, 0x0151}, {0x0105, 0x0055, 0x0018, 0x001c},
+ {0x0157, 0x0157, 0x0147, 0x0147}, {0x0117, 0x0117, 0x0009, 0x0201},
+ {0x0024, 0x002c, 0x0040, 0x0054}, {0x0241, 0x0019, 0x0065, 0x0028},
+ {0x0183, 0x0183, 0x0193, 0x0193}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0027, 0x0027, 0x0253, 0x0253}, {0x005b, 0x005b, 0x0083, 0x0083},
+ {0x0063, 0x0063, 0x0093, 0x0093}, {0x0023, 0x0023, 0x0213, 0x0213},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x004b, 0x004b, 0x0167, 0x0167},
+ {0x0163, 0x0163, 0x0097, 0x0097}, {0x0197, 0x0197, 0x0125, 0x0085},
+ {0x0185, 0x0121, 0x0159, 0x0255}, {0x0058, 0x005c, 0x0060, 0x0070},
+ {0x0119, 0x0245, 0x0281, 0x0291}, {0x0069, 0x00a5, 0x0205, 0x0109},
+ {0x01a1, 0x0064, 0x0068, 0x006c}, {0x002b, 0x002b, 0x01a7, 0x01a7},
+ {0x0217, 0x0217, 0x014b, 0x014b}, {0x0297, 0x0297, 0x016b, 0x016b},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x00a3, 0x00a3, 0x0263, 0x0263},
+ {0x0285, 0x0129, 0x0099, 0x00a9}, {0x02a1, 0x01a9, 0x0199, 0x0265},
+ {0x02a5, 0x0084, 0x0088, 0x008c}, {0x0223, 0x0223, 0x008b, 0x008b},
+ {0x0227, 0x0227, 0x0189, 0x0259}, {0x0219, 0x0090, 0x0094, 0x0098},
+ {0x02ab, 0x02ab, 0x026b, 0x026b}, {0x029b, 0x029b, 0x024b, 0x024b},
+ {0x020b, 0x020b, 0x0229, 0x0289}};
+
+const USHORT HuffmanCodeBook_4[38][4] = {
+ {0x0004, 0x0008, 0x000c, 0x0018}, {0x0155, 0x0151, 0x0115, 0x0055},
+ {0x0145, 0x0005, 0x0015, 0x0001}, {0x0141, 0x0045, 0x0010, 0x0014},
+ {0x0107, 0x0107, 0x0053, 0x0053}, {0x0103, 0x0103, 0x0113, 0x0113},
+ {0x001c, 0x0020, 0x0034, 0x0048}, {0x0043, 0x0043, 0x0013, 0x0013},
+ {0x0024, 0x0028, 0x002c, 0x0030}, {0x015b, 0x015b, 0x0197, 0x0197},
+ {0x0167, 0x0167, 0x0257, 0x0257}, {0x005b, 0x005b, 0x011b, 0x011b},
+ {0x0067, 0x0067, 0x014b, 0x014b}, {0x0038, 0x003c, 0x0040, 0x0044},
+ {0x0193, 0x0193, 0x0251, 0x0095}, {0x0161, 0x0245, 0x0125, 0x0215},
+ {0x0185, 0x0019, 0x0049, 0x0025}, {0x0109, 0x0211, 0x0061, 0x0241},
+ {0x004c, 0x0050, 0x0058, 0x006c}, {0x0091, 0x0121, 0x0205, 0x0181},
+ {0x0085, 0x0009, 0x0201, 0x0054}, {0x0023, 0x0023, 0x0083, 0x0083},
+ {0x005c, 0x0060, 0x0064, 0x0068}, {0x01a7, 0x01a7, 0x016b, 0x016b},
+ {0x019b, 0x019b, 0x0297, 0x0297}, {0x0267, 0x0267, 0x025b, 0x025b},
+ {0x00a5, 0x0069, 0x0099, 0x01a1}, {0x0070, 0x0074, 0x0078, 0x0084},
+ {0x0291, 0x0129, 0x0261, 0x0189}, {0x0285, 0x01a9, 0x0225, 0x0249},
+ {0x0219, 0x02a5, 0x007c, 0x0080}, {0x029b, 0x029b, 0x026b, 0x026b},
+ {0x00a3, 0x00a3, 0x002b, 0x002b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0283, 0x0283, 0x008b, 0x008b}, {0x0223, 0x0223, 0x020b, 0x020b},
+ {0x02ab, 0x02ab, 0x02a3, 0x02a3}, {0x00ab, 0x00ab, 0x0229, 0x0289}};
+
+const USHORT HuffmanCodeBook_5[41][4] = {
+ {0x0113, 0x0113, 0x0004, 0x0008}, {0x010d, 0x0115, 0x0151, 0x00d1},
+ {0x000c, 0x0010, 0x0014, 0x0028}, {0x00d7, 0x00d7, 0x014f, 0x014f},
+ {0x00cf, 0x00cf, 0x0157, 0x0157}, {0x0018, 0x001c, 0x0020, 0x0024},
+ {0x010b, 0x010b, 0x0193, 0x0193}, {0x011b, 0x011b, 0x0093, 0x0093},
+ {0x00c9, 0x0159, 0x008d, 0x0195}, {0x0149, 0x00d9, 0x018d, 0x0095},
+ {0x002c, 0x0030, 0x0044, 0x0058}, {0x0105, 0x011d, 0x0051, 0x01d1},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x00c7, 0x00c7, 0x01d7, 0x01d7},
+ {0x015f, 0x015f, 0x004f, 0x004f}, {0x0147, 0x0147, 0x00df, 0x00df},
+ {0x0057, 0x0057, 0x01cf, 0x01cf}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x018b, 0x018b, 0x019b, 0x019b}, {0x008b, 0x008b, 0x009b, 0x009b},
+ {0x0085, 0x009d, 0x01c9, 0x0059}, {0x019d, 0x01d9, 0x0185, 0x0049},
+ {0x005c, 0x0060, 0x0074, 0x0088}, {0x0011, 0x0101, 0x0161, 0x0121},
+ {0x0064, 0x0068, 0x006c, 0x0070}, {0x00c3, 0x00c3, 0x0213, 0x0213},
+ {0x00e3, 0x00e3, 0x000f, 0x000f}, {0x0217, 0x0217, 0x020f, 0x020f},
+ {0x0143, 0x0143, 0x0017, 0x0017}, {0x0078, 0x007c, 0x0080, 0x0084},
+ {0x005f, 0x005f, 0x0047, 0x0047}, {0x01c7, 0x01c7, 0x020b, 0x020b},
+ {0x0083, 0x0083, 0x01a3, 0x01a3}, {0x001b, 0x001b, 0x021b, 0x021b},
+ {0x008c, 0x0090, 0x0094, 0x0098}, {0x01df, 0x01df, 0x0183, 0x0183},
+ {0x0009, 0x00a1, 0x001d, 0x0041}, {0x01c1, 0x021d, 0x0205, 0x01e1},
+ {0x0061, 0x0005, 0x009c, 0x00a0}, {0x0023, 0x0023, 0x0203, 0x0203},
+ {0x0223, 0x0223, 0x0003, 0x0003}};
+
+const USHORT HuffmanCodeBook_6[40][4] = {
+ {0x0004, 0x0008, 0x000c, 0x001c}, {0x0111, 0x0115, 0x00d1, 0x0151},
+ {0x010d, 0x0155, 0x014d, 0x00d5}, {0x00cd, 0x0010, 0x0014, 0x0018},
+ {0x00d9, 0x0159, 0x0149, 0x00c9}, {0x0109, 0x018d, 0x0119, 0x0095},
+ {0x0195, 0x0091, 0x008d, 0x0191}, {0x0020, 0x0024, 0x0038, 0x004c},
+ {0x0099, 0x0189, 0x0089, 0x0199}, {0x0028, 0x002c, 0x0030, 0x0034},
+ {0x0147, 0x0147, 0x015f, 0x015f}, {0x00df, 0x00df, 0x01cf, 0x01cf},
+ {0x00c7, 0x00c7, 0x01d7, 0x01d7}, {0x0057, 0x0057, 0x004f, 0x004f},
+ {0x003c, 0x0040, 0x0044, 0x0048}, {0x011f, 0x011f, 0x0107, 0x0107},
+ {0x0053, 0x0053, 0x01d3, 0x01d3}, {0x019f, 0x019f, 0x0085, 0x01c9},
+ {0x01d9, 0x009d, 0x0059, 0x0049}, {0x0050, 0x005c, 0x0070, 0x0084},
+ {0x0185, 0x01dd, 0x0054, 0x0058}, {0x005f, 0x005f, 0x0047, 0x0047},
+ {0x01c7, 0x01c7, 0x0017, 0x0017}, {0x0060, 0x0064, 0x0068, 0x006c},
+ {0x000f, 0x000f, 0x0163, 0x0163}, {0x0143, 0x0143, 0x00c3, 0x00c3},
+ {0x0217, 0x0217, 0x00e3, 0x00e3}, {0x020f, 0x020f, 0x0013, 0x0013},
+ {0x0074, 0x0078, 0x007c, 0x0080}, {0x0183, 0x0183, 0x0083, 0x0083},
+ {0x021b, 0x021b, 0x000b, 0x000b}, {0x0103, 0x0103, 0x01a3, 0x01a3},
+ {0x00a3, 0x00a3, 0x020b, 0x020b}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x0123, 0x0123, 0x001b, 0x001b}, {0x0213, 0x0213, 0x0005, 0x0205},
+ {0x001d, 0x0061, 0x021d, 0x01e1}, {0x01c1, 0x0041, 0x0098, 0x009c},
+ {0x0223, 0x0223, 0x0203, 0x0203}, {0x0003, 0x0003, 0x0023, 0x0023}};
+
+const USHORT HuffmanCodeBook_7[31][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0007, 0x0007, 0x0043, 0x0043},
+ {0x0045, 0x000c, 0x0010, 0x0024}, {0x0049, 0x0085, 0x0009, 0x0081},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x004f, 0x004f, 0x00c7, 0x00c7},
+ {0x008b, 0x008b, 0x000f, 0x000f}, {0x00c3, 0x00c3, 0x00c9, 0x008d},
+ {0x0105, 0x0051, 0x0145, 0x0055}, {0x0028, 0x002c, 0x0040, 0x0054},
+ {0x00cd, 0x0109, 0x0101, 0x0011}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0093, 0x0093, 0x014b, 0x014b}, {0x0097, 0x0097, 0x0143, 0x0143},
+ {0x005b, 0x005b, 0x0017, 0x0017}, {0x0187, 0x0187, 0x00d3, 0x00d3},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x014f, 0x014f, 0x010f, 0x010f},
+ {0x00d7, 0x00d7, 0x018b, 0x018b}, {0x009b, 0x009b, 0x01c7, 0x01c7},
+ {0x018d, 0x0181, 0x0019, 0x0111}, {0x0058, 0x005c, 0x0060, 0x0068},
+ {0x005d, 0x0151, 0x009d, 0x0115}, {0x00d9, 0x01c9, 0x00dd, 0x0119},
+ {0x0155, 0x0191, 0x01cd, 0x0064}, {0x001f, 0x001f, 0x01c3, 0x01c3},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x015b, 0x015b, 0x0197, 0x0197},
+ {0x011f, 0x011f, 0x01d3, 0x01d3}, {0x01d7, 0x01d7, 0x015f, 0x015f},
+ {0x019d, 0x0199, 0x01d9, 0x01dd}};
+
+const USHORT HuffmanCodeBook_8[31][4] = {
+ {0x0004, 0x0008, 0x0010, 0x0024}, {0x0047, 0x0047, 0x0049, 0x0005},
+ {0x0085, 0x0041, 0x0089, 0x000c}, {0x0003, 0x0003, 0x000b, 0x000b},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x0083, 0x0083, 0x004f, 0x004f},
+ {0x00c7, 0x00c7, 0x008f, 0x008f}, {0x00cb, 0x00cb, 0x00cd, 0x0051},
+ {0x0105, 0x0091, 0x0109, 0x000d}, {0x0028, 0x002c, 0x0040, 0x0054},
+ {0x00c1, 0x00d1, 0x010d, 0x0095}, {0x0030, 0x0034, 0x0038, 0x003c},
+ {0x0057, 0x0057, 0x014b, 0x014b}, {0x0147, 0x0147, 0x00d7, 0x00d7},
+ {0x014f, 0x014f, 0x0113, 0x0113}, {0x0117, 0x0117, 0x0103, 0x0103},
+ {0x0044, 0x0048, 0x004c, 0x0050}, {0x0153, 0x0153, 0x0013, 0x0013},
+ {0x018b, 0x018b, 0x009b, 0x009b}, {0x005b, 0x005b, 0x0187, 0x0187},
+ {0x018d, 0x00d9, 0x0155, 0x0015}, {0x0058, 0x005c, 0x0060, 0x0068},
+ {0x0119, 0x0141, 0x0191, 0x005d}, {0x009d, 0x01c9, 0x0159, 0x00dd},
+ {0x01c5, 0x0195, 0x01cd, 0x0064}, {0x019b, 0x019b, 0x011f, 0x011f},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x001b, 0x001b, 0x01d3, 0x01d3},
+ {0x0183, 0x0183, 0x015f, 0x015f}, {0x019f, 0x019f, 0x01db, 0x01db},
+ {0x01d5, 0x001d, 0x01c1, 0x01dd}};
+
+const USHORT HuffmanCodeBook_9[84][4] = {
+ {0x0003, 0x0003, 0x0004, 0x0008}, {0x0007, 0x0007, 0x0043, 0x0043},
+ {0x0045, 0x000c, 0x0010, 0x002c}, {0x0049, 0x0085, 0x0009, 0x0081},
+ {0x0014, 0x0018, 0x001c, 0x0020}, {0x004f, 0x004f, 0x008b, 0x008b},
+ {0x00c7, 0x00c7, 0x000d, 0x00c1}, {0x00c9, 0x008d, 0x0105, 0x0051},
+ {0x0109, 0x0145, 0x0024, 0x0028}, {0x0093, 0x0093, 0x00cf, 0x00cf},
+ {0x0103, 0x0103, 0x0013, 0x0013}, {0x0030, 0x0044, 0x0058, 0x00a4},
+ {0x0034, 0x0038, 0x003c, 0x0040}, {0x0057, 0x0057, 0x014b, 0x014b},
+ {0x0187, 0x0187, 0x010f, 0x010f}, {0x0097, 0x0097, 0x005b, 0x005b},
+ {0x00d3, 0x00d3, 0x0141, 0x0189}, {0x0048, 0x004c, 0x0050, 0x0054},
+ {0x0015, 0x01c5, 0x014d, 0x0205}, {0x0061, 0x0111, 0x00d5, 0x0099},
+ {0x005d, 0x0181, 0x00a1, 0x0209}, {0x018d, 0x01c9, 0x0151, 0x0065},
+ {0x005c, 0x0068, 0x007c, 0x0090}, {0x0245, 0x009d, 0x0060, 0x0064},
+ {0x001b, 0x001b, 0x0117, 0x0117}, {0x00db, 0x00db, 0x00e3, 0x00e3},
+ {0x006c, 0x0070, 0x0074, 0x0078}, {0x01c3, 0x01c3, 0x00a7, 0x00a7},
+ {0x020f, 0x020f, 0x0193, 0x0193}, {0x01cf, 0x01cf, 0x0203, 0x0203},
+ {0x006b, 0x006b, 0x011b, 0x011b}, {0x0080, 0x0084, 0x0088, 0x008c},
+ {0x024b, 0x024b, 0x0157, 0x0157}, {0x0023, 0x0023, 0x001f, 0x001f},
+ {0x00df, 0x00df, 0x00ab, 0x00ab}, {0x00e7, 0x00e7, 0x0123, 0x0123},
+ {0x0094, 0x0098, 0x009c, 0x00a0}, {0x0287, 0x0287, 0x011f, 0x011f},
+ {0x015b, 0x015b, 0x0197, 0x0197}, {0x0213, 0x0213, 0x01d3, 0x01d3},
+ {0x024f, 0x024f, 0x006f, 0x006f}, {0x00a8, 0x00bc, 0x00d0, 0x00f4},
+ {0x00ac, 0x00b0, 0x00b4, 0x00b8}, {0x0217, 0x0217, 0x0027, 0x0027},
+ {0x0163, 0x0163, 0x00e9, 0x0289}, {0x0241, 0x00ad, 0x0125, 0x0199},
+ {0x0071, 0x0251, 0x01a1, 0x02c5}, {0x00c0, 0x00c4, 0x00c8, 0x00cc},
+ {0x0165, 0x0129, 0x01d5, 0x015d}, {0x02c9, 0x0305, 0x00b1, 0x00ed},
+ {0x028d, 0x0255, 0x01d9, 0x01e1}, {0x012d, 0x0281, 0x019d, 0x00f1},
+ {0x00d4, 0x00d8, 0x00dc, 0x00e0}, {0x0029, 0x0169, 0x0291, 0x0219},
+ {0x0309, 0x01a5, 0x01e5, 0x02d1}, {0x002d, 0x0259, 0x02cd, 0x0295},
+ {0x00e4, 0x00e8, 0x00ec, 0x00f0}, {0x0223, 0x0223, 0x021f, 0x021f},
+ {0x0173, 0x0173, 0x030f, 0x030f}, {0x016f, 0x016f, 0x01df, 0x01df},
+ {0x0133, 0x0133, 0x01af, 0x01af}, {0x00f8, 0x010c, 0x0120, 0x0134},
+ {0x00fc, 0x0100, 0x0104, 0x0108}, {0x01ab, 0x01ab, 0x0313, 0x0313},
+ {0x025f, 0x025f, 0x02d7, 0x02d7}, {0x02c3, 0x02c3, 0x01b3, 0x01b3},
+ {0x029b, 0x029b, 0x0033, 0x0033}, {0x0110, 0x0114, 0x0118, 0x011c},
+ {0x01eb, 0x01eb, 0x0317, 0x0317}, {0x029f, 0x029f, 0x0227, 0x0227},
+ {0x0303, 0x0303, 0x01ef, 0x01ef}, {0x0263, 0x0263, 0x0267, 0x0267},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x022b, 0x022b, 0x02df, 0x02df},
+ {0x01f3, 0x01f3, 0x02db, 0x02db}, {0x02e3, 0x02e3, 0x022f, 0x022f},
+ {0x031f, 0x031f, 0x031b, 0x031b}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x02a1, 0x0269, 0x0321, 0x02a5}, {0x02e5, 0x0325, 0x02e9, 0x0271},
+ {0x02a9, 0x026d, 0x0231, 0x02ad}, {0x02b1, 0x02f1, 0x0148, 0x014c},
+ {0x032b, 0x032b, 0x02ef, 0x02ef}, {0x032f, 0x032f, 0x0333, 0x0333}};
+
+const USHORT HuffmanCodeBook_10[82][4] = {
+ {0x0004, 0x000c, 0x0020, 0x004c}, {0x0045, 0x0085, 0x0049, 0x0008},
+ {0x008b, 0x008b, 0x0007, 0x0007}, {0x0010, 0x0014, 0x0018, 0x001c},
+ {0x0043, 0x0043, 0x00c7, 0x00c7}, {0x008f, 0x008f, 0x004f, 0x004f},
+ {0x00cb, 0x00cb, 0x00cf, 0x00cf}, {0x0009, 0x0081, 0x0109, 0x0091},
+ {0x0024, 0x0028, 0x002c, 0x0038}, {0x0105, 0x0051, 0x0001, 0x00d1},
+ {0x010d, 0x000d, 0x00c1, 0x0111}, {0x0149, 0x0095, 0x0030, 0x0034},
+ {0x0147, 0x0147, 0x0057, 0x0057}, {0x00d7, 0x00d7, 0x014f, 0x014f},
+ {0x003c, 0x0040, 0x0044, 0x0048}, {0x0117, 0x0117, 0x0153, 0x0153},
+ {0x009b, 0x009b, 0x018b, 0x018b}, {0x00db, 0x00db, 0x0013, 0x0013},
+ {0x005b, 0x005b, 0x0103, 0x0103}, {0x0050, 0x0064, 0x0078, 0x00c0},
+ {0x0054, 0x0058, 0x005c, 0x0060}, {0x0187, 0x0187, 0x018f, 0x018f},
+ {0x0157, 0x0157, 0x011b, 0x011b}, {0x0193, 0x0193, 0x0159, 0x009d},
+ {0x01cd, 0x01c9, 0x0195, 0x00a1}, {0x0068, 0x006c, 0x0070, 0x0074},
+ {0x00dd, 0x0015, 0x005d, 0x0141}, {0x0061, 0x01c5, 0x00e1, 0x011d},
+ {0x01d1, 0x0209, 0x0199, 0x015d}, {0x0205, 0x020d, 0x0121, 0x0211},
+ {0x007c, 0x0084, 0x0098, 0x00ac}, {0x01d5, 0x0161, 0x0215, 0x0080},
+ {0x019f, 0x019f, 0x01db, 0x01db}, {0x0088, 0x008c, 0x0090, 0x0094},
+ {0x00a7, 0x00a7, 0x001b, 0x001b}, {0x021b, 0x021b, 0x00e7, 0x00e7},
+ {0x024f, 0x024f, 0x0067, 0x0067}, {0x024b, 0x024b, 0x0183, 0x0183},
+ {0x009c, 0x00a0, 0x00a4, 0x00a8}, {0x01a3, 0x01a3, 0x0127, 0x0127},
+ {0x0253, 0x0253, 0x00ab, 0x00ab}, {0x0247, 0x0247, 0x01df, 0x01df},
+ {0x01e3, 0x01e3, 0x0167, 0x0167}, {0x00b0, 0x00b4, 0x00b8, 0x00bc},
+ {0x021f, 0x021f, 0x00eb, 0x00eb}, {0x0257, 0x0257, 0x012b, 0x012b},
+ {0x028b, 0x028b, 0x006b, 0x006b}, {0x028f, 0x028f, 0x01a7, 0x01a7},
+ {0x00c4, 0x00d8, 0x00ec, 0x0100}, {0x00c8, 0x00cc, 0x00d0, 0x00d4},
+ {0x025b, 0x025b, 0x0023, 0x0023}, {0x0293, 0x0293, 0x001f, 0x001f},
+ {0x00af, 0x00af, 0x025d, 0x00ed}, {0x01a9, 0x0285, 0x006d, 0x01e5},
+ {0x00dc, 0x00e0, 0x00e4, 0x00e8}, {0x01c1, 0x0221, 0x0169, 0x02cd},
+ {0x0295, 0x0261, 0x016d, 0x0201}, {0x012d, 0x02c9, 0x029d, 0x0299},
+ {0x01e9, 0x02d1, 0x02c5, 0x00b1}, {0x00f0, 0x00f4, 0x00f8, 0x00fc},
+ {0x0225, 0x00f1, 0x01ad, 0x02d5}, {0x0131, 0x01ed, 0x0171, 0x030d},
+ {0x02d9, 0x0025, 0x0229, 0x0029}, {0x0071, 0x0241, 0x0311, 0x0265},
+ {0x0104, 0x010c, 0x0120, 0x0134}, {0x01b1, 0x0309, 0x02a1, 0x0108},
+ {0x02a7, 0x02a7, 0x0307, 0x0307}, {0x0110, 0x0114, 0x0118, 0x011c},
+ {0x022f, 0x022f, 0x01f3, 0x01f3}, {0x02df, 0x02df, 0x0317, 0x0317},
+ {0x031b, 0x031b, 0x026b, 0x026b}, {0x02e3, 0x02e3, 0x0233, 0x0233},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x0283, 0x0283, 0x031f, 0x031f},
+ {0x002f, 0x002f, 0x02ab, 0x02ab}, {0x026f, 0x026f, 0x02af, 0x02af},
+ {0x02c3, 0x02c3, 0x02ef, 0x02ef}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x02e7, 0x02e7, 0x02eb, 0x02eb}, {0x0033, 0x0033, 0x0323, 0x0323},
+ {0x0271, 0x0329, 0x0325, 0x032d}, {0x02f1, 0x0301, 0x02b1, 0x0331}};
+
+const USHORT HuffmanCodeBook_11[152][4] = {
+ {0x0004, 0x0010, 0x0038, 0x008c}, {0x0001, 0x0085, 0x0008, 0x000c},
+ {0x0843, 0x0843, 0x0007, 0x0007}, {0x0083, 0x0083, 0x008b, 0x008b},
+ {0x0014, 0x0018, 0x001c, 0x0024}, {0x0107, 0x0107, 0x010b, 0x010b},
+ {0x0185, 0x008d, 0x010d, 0x0009}, {0x0189, 0x0101, 0x018d, 0x0020},
+ {0x0093, 0x0093, 0x0207, 0x0207}, {0x0028, 0x002c, 0x0030, 0x0034},
+ {0x0113, 0x0113, 0x020b, 0x020b}, {0x0193, 0x0193, 0x020f, 0x020f},
+ {0x000f, 0x000f, 0x0183, 0x0183}, {0x0097, 0x0097, 0x0117, 0x0117},
+ {0x003c, 0x0050, 0x0064, 0x0078}, {0x0040, 0x0044, 0x0048, 0x004c},
+ {0x028b, 0x028b, 0x0213, 0x0213}, {0x0287, 0x0287, 0x0197, 0x0197},
+ {0x028f, 0x028f, 0x0217, 0x0217}, {0x0291, 0x0119, 0x0309, 0x0099},
+ {0x0054, 0x0058, 0x005c, 0x0060}, {0x0199, 0x030d, 0x0305, 0x0811},
+ {0x080d, 0x02c1, 0x01c1, 0x0241}, {0x0219, 0x0341, 0x0011, 0x0311},
+ {0x0201, 0x0809, 0x0295, 0x0815}, {0x0068, 0x006c, 0x0070, 0x0074},
+ {0x03c1, 0x0141, 0x0441, 0x0389}, {0x011d, 0x038d, 0x0299, 0x0315},
+ {0x0819, 0x0541, 0x019d, 0x009d}, {0x04c1, 0x081d, 0x0805, 0x0385},
+ {0x007c, 0x0080, 0x0084, 0x0088}, {0x0391, 0x05c1, 0x021d, 0x0641},
+ {0x0821, 0x00c1, 0x0319, 0x0825}, {0x0409, 0x0395, 0x0829, 0x06c1},
+ {0x01a1, 0x0121, 0x040d, 0x0015}, {0x0090, 0x00c8, 0x011c, 0x0170},
+ {0x0094, 0x0098, 0x00a0, 0x00b4}, {0x0741, 0x082d, 0x029d, 0x0411},
+ {0x0399, 0x031d, 0x0281, 0x009c}, {0x0223, 0x0223, 0x07c3, 0x07c3},
+ {0x00a4, 0x00a8, 0x00ac, 0x00b0}, {0x0833, 0x0833, 0x0407, 0x0407},
+ {0x00a3, 0x00a3, 0x083b, 0x083b}, {0x0417, 0x0417, 0x0837, 0x0837},
+ {0x048f, 0x048f, 0x02a3, 0x02a3}, {0x00b8, 0x00bc, 0x00c0, 0x00c4},
+ {0x039f, 0x039f, 0x048b, 0x048b}, {0x0323, 0x0323, 0x0127, 0x0127},
+ {0x01a7, 0x01a7, 0x083f, 0x083f}, {0x0493, 0x0493, 0x041b, 0x041b},
+ {0x00cc, 0x00e0, 0x00f4, 0x0108}, {0x00d0, 0x00d4, 0x00d8, 0x00dc},
+ {0x001b, 0x001b, 0x0227, 0x0227}, {0x0497, 0x0497, 0x03a3, 0x03a3},
+ {0x041f, 0x041f, 0x0487, 0x0487}, {0x01ab, 0x01ab, 0x0303, 0x0303},
+ {0x00e4, 0x00e8, 0x00ec, 0x00f0}, {0x012b, 0x012b, 0x00a7, 0x00a7},
+ {0x02a7, 0x02a7, 0x0513, 0x0513}, {0x050b, 0x050b, 0x0327, 0x0327},
+ {0x050f, 0x050f, 0x049b, 0x049b}, {0x00f8, 0x00fc, 0x0100, 0x0104},
+ {0x022b, 0x022b, 0x0423, 0x0423}, {0x02ab, 0x02ab, 0x03a7, 0x03a7},
+ {0x01af, 0x01af, 0x0507, 0x0507}, {0x001f, 0x001f, 0x032b, 0x032b},
+ {0x010c, 0x0110, 0x0114, 0x0118}, {0x049f, 0x049f, 0x058f, 0x058f},
+ {0x0517, 0x0517, 0x00ab, 0x00ab}, {0x0593, 0x0593, 0x012f, 0x012f},
+ {0x0137, 0x0137, 0x051b, 0x051b}, {0x0120, 0x0134, 0x0148, 0x015c},
+ {0x0124, 0x0128, 0x012c, 0x0130}, {0x01b7, 0x01b7, 0x058b, 0x058b},
+ {0x0043, 0x0043, 0x0597, 0x0597}, {0x02af, 0x02af, 0x022d, 0x0425},
+ {0x051d, 0x04a1, 0x0801, 0x0691}, {0x0138, 0x013c, 0x0140, 0x0144},
+ {0x0381, 0x068d, 0x032d, 0x00b5}, {0x0235, 0x01b1, 0x0689, 0x02b5},
+ {0x0521, 0x0599, 0x0429, 0x03a9}, {0x0139, 0x0231, 0x0585, 0x0611},
+ {0x014c, 0x0150, 0x0154, 0x0158}, {0x00ad, 0x060d, 0x0685, 0x0131},
+ {0x059d, 0x070d, 0x0615, 0x0695}, {0x0239, 0x0711, 0x03ad, 0x01b9},
+ {0x02b1, 0x0335, 0x0331, 0x0021}, {0x0160, 0x0164, 0x0168, 0x016c},
+ {0x042d, 0x0609, 0x04a5, 0x02b9}, {0x0699, 0x0529, 0x013d, 0x05a1},
+ {0x0525, 0x0339, 0x04a9, 0x0715}, {0x04ad, 0x00b9, 0x0709, 0x0619},
+ {0x0174, 0x0188, 0x019c, 0x01cc}, {0x0178, 0x017c, 0x0180, 0x0184},
+ {0x0605, 0x0435, 0x0401, 0x03b5}, {0x061d, 0x03b1, 0x069d, 0x01bd},
+ {0x00b1, 0x0719, 0x0789, 0x02bd}, {0x023d, 0x0705, 0x05a5, 0x0791},
+ {0x018c, 0x0190, 0x0194, 0x0198}, {0x03b9, 0x06a1, 0x04b5, 0x0621},
+ {0x0795, 0x078d, 0x05a9, 0x052d}, {0x0431, 0x033d, 0x03bd, 0x0721},
+ {0x00bd, 0x071d, 0x0025, 0x0481}, {0x01a0, 0x01a4, 0x01a8, 0x01b8},
+ {0x06a5, 0x0625, 0x04b1, 0x0439}, {0x06a9, 0x04b9, 0x0531, 0x0799},
+ {0x079d, 0x01ac, 0x01b0, 0x01b4}, {0x0727, 0x0727, 0x043f, 0x043f},
+ {0x05af, 0x05af, 0x072f, 0x072f}, {0x0787, 0x0787, 0x062b, 0x062b},
+ {0x01bc, 0x01c0, 0x01c4, 0x01c8}, {0x072b, 0x072b, 0x05b7, 0x05b7},
+ {0x0537, 0x0537, 0x06af, 0x06af}, {0x062f, 0x062f, 0x07a3, 0x07a3},
+ {0x05bb, 0x05bb, 0x0637, 0x0637}, {0x01d0, 0x01e4, 0x01f8, 0x020c},
+ {0x01d4, 0x01d8, 0x01dc, 0x01e0}, {0x06b3, 0x06b3, 0x04bf, 0x04bf},
+ {0x053b, 0x053b, 0x002b, 0x002b}, {0x05b3, 0x05b3, 0x07a7, 0x07a7},
+ {0x0503, 0x0503, 0x0633, 0x0633}, {0x01e8, 0x01ec, 0x01f0, 0x01f4},
+ {0x002f, 0x002f, 0x0733, 0x0733}, {0x07ab, 0x07ab, 0x06b7, 0x06b7},
+ {0x0683, 0x0683, 0x063b, 0x063b}, {0x053f, 0x053f, 0x05bf, 0x05bf},
+ {0x01fc, 0x0200, 0x0204, 0x0208}, {0x07af, 0x07af, 0x06bb, 0x06bb},
+ {0x0037, 0x0037, 0x0583, 0x0583}, {0x0737, 0x0737, 0x063f, 0x063f},
+ {0x06bf, 0x06bf, 0x07b3, 0x07b3}, {0x0210, 0x0214, 0x0218, 0x021c},
+ {0x003b, 0x003b, 0x073b, 0x073b}, {0x07b7, 0x07b7, 0x0033, 0x0033},
+ {0x07bb, 0x07bb, 0x0701, 0x0601}, {0x073d, 0x003d, 0x0781, 0x07bd},
+ {0x0118, 0x0117, 0x0100, 0x0109}, {0x05a5, 0x05a1, 0x05b7, 0x0513},
+ {0x08f9, 0x08ff, 0x0821, 0x08ff}, {0x084f, 0x08ff, 0x08bc, 0x08ff},
+ {0x0815, 0x08ff, 0x0837, 0x08ff}, {0x080d, 0x08ff, 0x085f, 0x08ff},
+ {0x084a, 0x08ff, 0x087d, 0x08ff}, {0x08ff, 0x08ff, 0x08a8, 0x08ff},
+ {0x0815, 0x08ff, 0x083f, 0x08ff}, {0x0830, 0x08ff, 0x0894, 0x08ff},
+ {0x08d4, 0x08ff, 0x0825, 0x08ff}, {0x08ef, 0x08ff, 0x083f, 0x08ff},
+ {0x0809, 0x08ff, 0x08fc, 0x08ff}, {0x0842, 0x08ff, 0x08b3, 0x08ff},
+ {0x070d, 0x07a9, 0x060e, 0x06e2}, {0x06c7, 0x06d0, 0x04b2, 0x0407}};
+
+const USHORT HuffmanCodeBook_SCL[65][4] = {
+ {0x00f3, 0x00f3, 0x0004, 0x0008}, {0x00ef, 0x00ef, 0x00f5, 0x00e9},
+ {0x00f9, 0x000c, 0x0010, 0x0014}, {0x00e7, 0x00e7, 0x00ff, 0x00ff},
+ {0x00e1, 0x0101, 0x00dd, 0x0105}, {0x0018, 0x001c, 0x0020, 0x0028},
+ {0x010b, 0x010b, 0x00db, 0x00db}, {0x010f, 0x010f, 0x00d5, 0x0111},
+ {0x00d1, 0x0115, 0x00cd, 0x0024}, {0x011b, 0x011b, 0x00cb, 0x00cb},
+ {0x002c, 0x0030, 0x0034, 0x0040}, {0x00c7, 0x00c7, 0x011f, 0x011f},
+ {0x0121, 0x00c1, 0x0125, 0x00bd}, {0x0129, 0x00b9, 0x0038, 0x003c},
+ {0x0133, 0x0133, 0x012f, 0x012f}, {0x0137, 0x0137, 0x013b, 0x013b},
+ {0x0044, 0x0048, 0x004c, 0x0058}, {0x00b7, 0x00b7, 0x00af, 0x00af},
+ {0x00b1, 0x013d, 0x00a9, 0x00a5}, {0x0141, 0x00a1, 0x0050, 0x0054},
+ {0x0147, 0x0147, 0x009f, 0x009f}, {0x014b, 0x014b, 0x009b, 0x009b},
+ {0x005c, 0x0060, 0x0064, 0x0070}, {0x014f, 0x014f, 0x0095, 0x008d},
+ {0x0155, 0x0085, 0x0091, 0x0089}, {0x0151, 0x0081, 0x0068, 0x006c},
+ {0x015f, 0x015f, 0x0167, 0x0167}, {0x007b, 0x007b, 0x007f, 0x007f},
+ {0x0074, 0x0078, 0x0080, 0x00b0}, {0x0159, 0x0075, 0x0069, 0x006d},
+ {0x0071, 0x0061, 0x0161, 0x007c}, {0x0067, 0x0067, 0x005b, 0x005b},
+ {0x0084, 0x0088, 0x008c, 0x009c}, {0x005f, 0x005f, 0x0169, 0x0055},
+ {0x004d, 0x000d, 0x0005, 0x0009}, {0x0001, 0x0090, 0x0094, 0x0098},
+ {0x018b, 0x018b, 0x018f, 0x018f}, {0x0193, 0x0193, 0x0197, 0x0197},
+ {0x019b, 0x019b, 0x01d7, 0x01d7}, {0x00a0, 0x00a4, 0x00a8, 0x00ac},
+ {0x0187, 0x0187, 0x016f, 0x016f}, {0x0173, 0x0173, 0x0177, 0x0177},
+ {0x017b, 0x017b, 0x017f, 0x017f}, {0x0183, 0x0183, 0x01a3, 0x01a3},
+ {0x00b4, 0x00c8, 0x00dc, 0x00f0}, {0x00b8, 0x00bc, 0x00c0, 0x00c4},
+ {0x01bf, 0x01bf, 0x01c3, 0x01c3}, {0x01c7, 0x01c7, 0x01cb, 0x01cb},
+ {0x01cf, 0x01cf, 0x01d3, 0x01d3}, {0x01bb, 0x01bb, 0x01a7, 0x01a7},
+ {0x00cc, 0x00d0, 0x00d4, 0x00d8}, {0x01ab, 0x01ab, 0x01af, 0x01af},
+ {0x01b3, 0x01b3, 0x01b7, 0x01b7}, {0x01db, 0x01db, 0x001b, 0x001b},
+ {0x0023, 0x0023, 0x0027, 0x0027}, {0x00e0, 0x00e4, 0x00e8, 0x00ec},
+ {0x002b, 0x002b, 0x0017, 0x0017}, {0x019f, 0x019f, 0x01e3, 0x01e3},
+ {0x01df, 0x01df, 0x0013, 0x0013}, {0x001f, 0x001f, 0x003f, 0x003f},
+ {0x00f4, 0x00f8, 0x00fc, 0x0100}, {0x0043, 0x0043, 0x004b, 0x004b},
+ {0x0053, 0x0053, 0x0047, 0x0047}, {0x002f, 0x002f, 0x0033, 0x0033},
+ {0x003b, 0x003b, 0x0037, 0x0037}};
+
+/* .CodeBook = HuffmanCodeBook_x, .Dimension = 4, .numBits = 2, .Offset = 0 */
+const CodeBookDescription AACcodeBookDescriptionTable[13] = {
+ {NULL, 0, 0, 0},
+ {HuffmanCodeBook_1, 4, 2, 1},
+ {HuffmanCodeBook_2, 4, 2, 1},
+ {HuffmanCodeBook_3, 4, 2, 0},
+ {HuffmanCodeBook_4, 4, 2, 0},
+ {HuffmanCodeBook_5, 2, 4, 4},
+ {HuffmanCodeBook_6, 2, 4, 4},
+ {HuffmanCodeBook_7, 2, 4, 0},
+ {HuffmanCodeBook_8, 2, 4, 0},
+ {HuffmanCodeBook_9, 2, 4, 0},
+ {HuffmanCodeBook_10, 2, 4, 0},
+ {HuffmanCodeBook_11, 2, 5, 0},
+ {HuffmanCodeBook_SCL, 1, 8, 60}};
+
+const CodeBookDescription AACcodeBookDescriptionSCL = {HuffmanCodeBook_SCL, 1,
+ 8, 60};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree41 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 1). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* HuffTree */
+const UINT aHuffTree41[80] = {
+ 0x4a0001, 0x026002, 0x013003, 0x021004, 0x01c005, 0x00b006, 0x010007,
+ 0x019008, 0x00900e, 0x00a03a, 0x400528, 0x00c037, 0x00d03b, 0x454404,
+ 0x00f04c, 0x448408, 0x017011, 0x01202e, 0x42c40c, 0x034014, 0x01502c,
+ 0x016049, 0x410470, 0x01804e, 0x414424, 0x03201a, 0x02001b, 0x520418,
+ 0x02f01d, 0x02a01e, 0x01f04d, 0x41c474, 0x540420, 0x022024, 0x04a023,
+ 0x428510, 0x025029, 0x430508, 0x02703c, 0x028047, 0x50c434, 0x438478,
+ 0x04802b, 0x46443c, 0x02d03e, 0x4404b0, 0x44451c, 0x03003f, 0x03104b,
+ 0x52444c, 0x033039, 0x4f0450, 0x035041, 0x036046, 0x4e8458, 0x04f038,
+ 0x45c53c, 0x4604e0, 0x4f8468, 0x46c4d4, 0x04503d, 0x4ac47c, 0x518480,
+ 0x043040, 0x4844dc, 0x042044, 0x4884a8, 0x4bc48c, 0x530490, 0x4a4494,
+ 0x4984b8, 0x49c4c4, 0x5044b4, 0x5004c0, 0x4d04c8, 0x4f44cc, 0x4d8538,
+ 0x4ec4e4, 0x52c4fc, 0x514534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree42 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 2). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree42[80] = {
+ 0x026001, 0x014002, 0x009003, 0x010004, 0x01d005, 0x00600d, 0x007018,
+ 0x450008, 0x4e0400, 0x02e00a, 0x03900b, 0x03d00c, 0x43c404, 0x01b00e,
+ 0x00f04f, 0x4d8408, 0x023011, 0x01203b, 0x01a013, 0x41440c, 0x015020,
+ 0x016040, 0x025017, 0x500410, 0x038019, 0x540418, 0x41c444, 0x02d01c,
+ 0x420520, 0x01e042, 0x03701f, 0x4244cc, 0x02a021, 0x02204c, 0x478428,
+ 0x024031, 0x42c4dc, 0x4304e8, 0x027033, 0x4a0028, 0x50c029, 0x4344a4,
+ 0x02c02b, 0x470438, 0x4404c8, 0x4f8448, 0x04902f, 0x04b030, 0x44c484,
+ 0x524032, 0x4ec454, 0x03e034, 0x035046, 0x4c4036, 0x488458, 0x4d445c,
+ 0x460468, 0x04e03a, 0x51c464, 0x03c04a, 0x46c514, 0x47453c, 0x04503f,
+ 0x47c4ac, 0x044041, 0x510480, 0x04304d, 0x4e448c, 0x490518, 0x49449c,
+ 0x048047, 0x4c0498, 0x4b84a8, 0x4b0508, 0x4fc4b4, 0x4bc504, 0x5304d0,
+ 0x5344f0, 0x4f452c, 0x528538};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree43 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 3). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree43[80] = {
+ 0x400001, 0x002004, 0x00300a, 0x46c404, 0x00b005, 0x00600d, 0x034007,
+ 0x037008, 0x494009, 0x4d8408, 0x42440c, 0x00c01b, 0x490410, 0x00e016,
+ 0x00f011, 0x010014, 0x4144fc, 0x01201d, 0x020013, 0x508418, 0x4c0015,
+ 0x41c440, 0x022017, 0x018026, 0x019035, 0x03801a, 0x420444, 0x01c01f,
+ 0x430428, 0x02101e, 0x44842c, 0x478434, 0x4b4438, 0x45443c, 0x02c023,
+ 0x039024, 0x02503f, 0x48844c, 0x030027, 0x02e028, 0x032029, 0x02a041,
+ 0x4d402b, 0x4504f0, 0x04302d, 0x4584a8, 0x02f03b, 0x46045c, 0x03103d,
+ 0x464046, 0x033044, 0x46853c, 0x47049c, 0x045036, 0x4744dc, 0x4a047c,
+ 0x500480, 0x4ac03a, 0x4b8484, 0x03c04e, 0x48c524, 0x03e040, 0x4984e8,
+ 0x50c4a4, 0x4b0530, 0x042047, 0x4bc04b, 0x4e44c4, 0x5184c8, 0x52c4cc,
+ 0x5204d0, 0x04d048, 0x04a049, 0x4e004c, 0x51c4ec, 0x4f4510, 0x5284f8,
+ 0x50404f, 0x514538, 0x540534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree44 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 4). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 4) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 4 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree44[80] = {
+ 0x001004, 0x020002, 0x036003, 0x490400, 0x005008, 0x010006, 0x01f007,
+ 0x404428, 0x00e009, 0x01100a, 0x00b018, 0x01600c, 0x03700d, 0x408015,
+ 0x00f03e, 0x40c424, 0x410478, 0x022012, 0x038013, 0x01e014, 0x454414,
+ 0x448418, 0x025017, 0x47441c, 0x030019, 0x02601a, 0x02d01b, 0x01c034,
+ 0x01d029, 0x4204f0, 0x4dc42c, 0x470430, 0x02103c, 0x4a0434, 0x02302a,
+ 0x440024, 0x4384a8, 0x43c44c, 0x02703a, 0x02802c, 0x444524, 0x4504e0,
+ 0x02b03d, 0x458480, 0x45c4f4, 0x04b02e, 0x04f02f, 0x460520, 0x042031,
+ 0x048032, 0x049033, 0x514464, 0x03504c, 0x540468, 0x47c46c, 0x4844d8,
+ 0x039044, 0x4884fc, 0x03b045, 0x48c53c, 0x49449c, 0x4b8498, 0x03f046,
+ 0x041040, 0x4c44a4, 0x50c4ac, 0x04a043, 0x5184b0, 0x4e44b4, 0x4bc4ec,
+ 0x04e047, 0x4c04e8, 0x4c8510, 0x4cc52c, 0x4d0530, 0x5044d4, 0x53804d,
+ 0x5284f8, 0x508500, 0x51c534};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree21 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 5). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree21[80] = {
+ 0x450001, 0x044002, 0x042003, 0x035004, 0x026005, 0x022006, 0x013007,
+ 0x010008, 0x00d009, 0x01c00a, 0x01f00b, 0x01e00c, 0x4a0400, 0x01b00e,
+ 0x03200f, 0x47e402, 0x020011, 0x01204d, 0x40449c, 0x017014, 0x015019,
+ 0x01603f, 0x406458, 0x01804f, 0x448408, 0x04901a, 0x40a45a, 0x48c40c,
+ 0x01d031, 0x40e48e, 0x490410, 0x492412, 0x021030, 0x480414, 0x033023,
+ 0x02402e, 0x02503e, 0x416482, 0x02a027, 0x02802c, 0x029040, 0x418468,
+ 0x02b04a, 0x41a486, 0x02d048, 0x41c484, 0x04e02f, 0x41e426, 0x420434,
+ 0x42249e, 0x424494, 0x03d034, 0x428470, 0x039036, 0x03703b, 0x038041,
+ 0x42a476, 0x03a04b, 0x42c454, 0x03c047, 0x42e472, 0x430478, 0x43246e,
+ 0x496436, 0x488438, 0x43a466, 0x046043, 0x43c464, 0x04504c, 0x43e462,
+ 0x460440, 0x44245e, 0x45c444, 0x46a446, 0x44a456, 0x47444c, 0x45244e,
+ 0x46c47c, 0x48a47a, 0x49a498};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree22 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 6). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree22[80] = {
+ 0x03c001, 0x02f002, 0x020003, 0x01c004, 0x00f005, 0x00c006, 0x016007,
+ 0x04d008, 0x00b009, 0x01500a, 0x400490, 0x40e402, 0x00d013, 0x00e02a,
+ 0x40c404, 0x019010, 0x011041, 0x038012, 0x40a406, 0x014037, 0x40849c,
+ 0x4a0410, 0x04a017, 0x458018, 0x412422, 0x02801a, 0x01b029, 0x480414,
+ 0x02401d, 0x01e02b, 0x48a01f, 0x416432, 0x02d021, 0x026022, 0x023039,
+ 0x418468, 0x025043, 0x48641a, 0x027040, 0x41c488, 0x41e48c, 0x42045a,
+ 0x47c424, 0x04c02c, 0x46e426, 0x03602e, 0x428478, 0x030033, 0x43c031,
+ 0x04b032, 0x42e42a, 0x03403a, 0x035048, 0x42c442, 0x470430, 0x494434,
+ 0x43649a, 0x45c438, 0x04403b, 0x43a454, 0x04503d, 0x03e03f, 0x43e464,
+ 0x440460, 0x484444, 0x049042, 0x446448, 0x44a456, 0x46644c, 0x047046,
+ 0x44e452, 0x450462, 0x47445e, 0x46a496, 0x49846c, 0x472476, 0x47a482,
+ 0x04e04f, 0x47e492, 0x48e49e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree23 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 7). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree23[63] = {
+ 0x400001, 0x002003, 0x410402, 0x004007, 0x412005, 0x01c006, 0x420404,
+ 0x00800b, 0x01d009, 0x00a01f, 0x406026, 0x00c012, 0x00d00f, 0x02700e,
+ 0x408440, 0x010022, 0x028011, 0x45440a, 0x013017, 0x029014, 0x024015,
+ 0x01602f, 0x43c40c, 0x02b018, 0x019033, 0x03201a, 0x43e01b, 0x47040e,
+ 0x422414, 0x01e025, 0x432416, 0x020021, 0x418442, 0x41a452, 0x036023,
+ 0x41c446, 0x46441e, 0x424430, 0x426434, 0x436428, 0x44442a, 0x02e02a,
+ 0x45642c, 0x03002c, 0x02d03b, 0x46642e, 0x43a438, 0x460448, 0x031037,
+ 0x47244a, 0x45a44c, 0x034039, 0x038035, 0x47844e, 0x462450, 0x474458,
+ 0x46a45c, 0x03a03c, 0x45e47a, 0x476468, 0x03d03e, 0x47c46c, 0x46e47e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree24 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 8). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree24[63] = {
+ 0x001006, 0x01d002, 0x005003, 0x424004, 0x400420, 0x414402, 0x00700a,
+ 0x008020, 0x00901f, 0x404432, 0x00b011, 0x00c00e, 0x00d032, 0x406446,
+ 0x02300f, 0x033010, 0x458408, 0x025012, 0x013016, 0x01402f, 0x015038,
+ 0x46840a, 0x028017, 0x01801a, 0x039019, 0x40c47a, 0x03e01b, 0x03b01c,
+ 0x40e47e, 0x41201e, 0x422410, 0x416434, 0x02a021, 0x02202b, 0x418444,
+ 0x02c024, 0x41a456, 0x02d026, 0x027034, 0x46241c, 0x029036, 0x41e45c,
+ 0x426031, 0x428430, 0x45242a, 0x03702e, 0x42c464, 0x03003c, 0x47442e,
+ 0x436442, 0x438454, 0x43a448, 0x03503a, 0x43c466, 0x43e03d, 0x44a440,
+ 0x44c472, 0x46044e, 0x45a450, 0x45e470, 0x46a476, 0x46c478, 0x47c46e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree25 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 9). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree25[168] = {
+ 0x400001, 0x002003, 0x41a402, 0x004007, 0x41c005, 0x035006, 0x434404,
+ 0x008010, 0x00900c, 0x04a00a, 0x42000b, 0x44e406, 0x03600d, 0x03800e,
+ 0x05a00f, 0x408468, 0x01101a, 0x012016, 0x039013, 0x070014, 0x46e015,
+ 0x40a440, 0x03b017, 0x01804d, 0x01904f, 0x4b840c, 0x01b022, 0x01c041,
+ 0x03f01d, 0x01e020, 0x01f05b, 0x40e4ee, 0x02107c, 0x45c410, 0x02302c,
+ 0x024028, 0x053025, 0x026045, 0x02707d, 0x412522, 0x047029, 0x05e02a,
+ 0x02b08a, 0x526414, 0x05602d, 0x02e081, 0x02f032, 0x06e030, 0x031080,
+ 0x416544, 0x079033, 0x034091, 0x41852c, 0x43641e, 0x04b037, 0x42246a,
+ 0x43c424, 0x04c03a, 0x426456, 0x03c066, 0x03d03e, 0x482428, 0x45842a,
+ 0x040072, 0x42c4ba, 0x050042, 0x04305c, 0x044074, 0x42e4be, 0x06a046,
+ 0x4dc430, 0x075048, 0x0490a3, 0x44a432, 0x450438, 0x43a452, 0x48443e,
+ 0x04e068, 0x45a442, 0x4d4444, 0x051088, 0x052087, 0x44648c, 0x077054,
+ 0x4da055, 0x50a448, 0x057060, 0x06b058, 0x05906d, 0x44c4f6, 0x46c454,
+ 0x45e474, 0x06905d, 0x460520, 0x05f07e, 0x462494, 0x061063, 0x07f062,
+ 0x464496, 0x06408b, 0x08d065, 0x542466, 0x067071, 0x4d2470, 0x4724ec,
+ 0x478476, 0x53a47a, 0x09b06c, 0x47c4ac, 0x4f847e, 0x06f078, 0x510480,
+ 0x48649e, 0x4884a0, 0x07307b, 0x49c48a, 0x4a648e, 0x098076, 0x4904c0,
+ 0x4924ea, 0x4c8498, 0x07a08e, 0x51249a, 0x4a24d6, 0x5064a4, 0x4f24a8,
+ 0x4aa4de, 0x51e4ae, 0x4b0538, 0x082092, 0x083085, 0x08f084, 0x5464b2,
+ 0x096086, 0x4ce4b4, 0x4d04b6, 0x089090, 0x4bc508, 0x4c253e, 0x08c0a4,
+ 0x5284c4, 0x4e04c6, 0x4ca4fa, 0x5144cc, 0x4f04d8, 0x4e24fc, 0x09309c,
+ 0x094099, 0x095097, 0x4e4516, 0x4e652e, 0x4e84fe, 0x4f450c, 0x09a09f,
+ 0x500502, 0x50450e, 0x09d0a0, 0x09e0a5, 0x518530, 0x51a54a, 0x0a70a1,
+ 0x0a20a6, 0x51c534, 0x53c524, 0x54052a, 0x548532, 0x536550, 0x54c54e};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree26 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 10). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree26[168] = {
+ 0x006001, 0x002013, 0x00300f, 0x00400d, 0x03b005, 0x40046e, 0x037007,
+ 0x00800a, 0x009067, 0x402420, 0x05600b, 0x00c057, 0x434404, 0x06600e,
+ 0x406470, 0x03c010, 0x059011, 0x06f012, 0x49e408, 0x014019, 0x03f015,
+ 0x016044, 0x017042, 0x079018, 0x4b840a, 0x01a01f, 0x01b047, 0x07c01c,
+ 0x08701d, 0x06901e, 0x44640c, 0x020027, 0x04b021, 0x02204f, 0x023025,
+ 0x02406b, 0x40e4e0, 0x081026, 0x528410, 0x02802c, 0x06c029, 0x08f02a,
+ 0x02b078, 0x53a412, 0x05202d, 0x02e033, 0x02f031, 0x0300a2, 0x4144ce,
+ 0x0a6032, 0x416534, 0x09a034, 0x09f035, 0x0360a7, 0x54e418, 0x03a038,
+ 0x436039, 0x43841a, 0x41c41e, 0x42246a, 0x05803d, 0x03e068, 0x424484,
+ 0x04005b, 0x04107a, 0x42645a, 0x043093, 0x4d2428, 0x05e045, 0x046072,
+ 0x42a45e, 0x048060, 0x073049, 0x04a098, 0x42c4c4, 0x07504c, 0x09504d,
+ 0x04e09c, 0x51042e, 0x063050, 0x077051, 0x43053c, 0x053084, 0x065054,
+ 0x4e4055, 0x4fe432, 0x43a454, 0x43c46c, 0x43e486, 0x07005a, 0x4a0440,
+ 0x07105c, 0x05d07b, 0x45c442, 0x05f08a, 0x476444, 0x07f061, 0x06206a,
+ 0x448506, 0x06408e, 0x52644a, 0x54444c, 0x45644e, 0x452450, 0x488458,
+ 0x4604ec, 0x4624f6, 0x50e464, 0x08206d, 0x0a406e, 0x542466, 0x4a2468,
+ 0x48a472, 0x474089, 0x4d8478, 0x097074, 0x47a508, 0x08d076, 0x47c4b6,
+ 0x51247e, 0x4804fc, 0x4bc482, 0x48c4a4, 0x48e4d4, 0x07d07e, 0x4904da,
+ 0x49208b, 0x094080, 0x49450c, 0x4964e2, 0x09d083, 0x52a498, 0x085091,
+ 0x0a5086, 0x4cc49a, 0x08808c, 0x4ee49c, 0x4a64ba, 0x4a84c0, 0x4c24aa,
+ 0x4ac4f0, 0x4ae4d0, 0x4ca4b0, 0x0900a1, 0x4b24ea, 0x092099, 0x4b4516,
+ 0x4d64be, 0x4c650a, 0x522096, 0x4c8524, 0x4dc4f2, 0x4de4f4, 0x4e6548,
+ 0x09e09b, 0x5384e8, 0x5204f8, 0x4fa53e, 0x50051a, 0x0a30a0, 0x502536,
+ 0x514504, 0x51e518, 0x54a51c, 0x54052c, 0x52e546, 0x530532, 0x54c550};
+
+/* *********************************************************************************************
+ */
+/* Table: HuffTree27 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the decode tree for spectral data
+ * (Codebook 11). */
+/* bit 23 and 11 not used */
+/* bit 22 and 10 determine end value */
+/* bit 21-12 and 9-0 (offset to next node) or (index value *
+ * 2) */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* input: codeword */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* output: index * 2 */
+/* ---------------------------------------------------------------------------------------------
+ */
+const UINT aHuffTree27[288] = {
+ 0x00100d, 0x002006, 0x003004, 0x400424, 0x047005, 0x402446, 0x048007,
+ 0x00800a, 0x00904c, 0x44a404, 0x07400b, 0x00c0bb, 0x466406, 0x00e014,
+ 0x00f054, 0x04e010, 0x051011, 0x0a9012, 0x0130bc, 0x408464, 0x01501f,
+ 0x01601a, 0x017059, 0x0af018, 0x0ca019, 0x40a0e4, 0x01b05e, 0x01c084,
+ 0x0bf01d, 0x05d01e, 0x55a40c, 0x020026, 0x021066, 0x043022, 0x023062,
+ 0x02408d, 0x025108, 0x40e480, 0x027030, 0x02802c, 0x02906b, 0x02a0da,
+ 0x06502b, 0x4105c8, 0x0a402d, 0x0ec02e, 0x0dd02f, 0x532412, 0x06e031,
+ 0x032036, 0x03303e, 0x0fd034, 0x0fc035, 0x4145b0, 0x03703a, 0x038117,
+ 0x10d039, 0x5ba416, 0x10f03b, 0x03c041, 0x5fa03d, 0x41c418, 0x10403f,
+ 0x04011d, 0x41a5f4, 0x11c042, 0x41e61c, 0x087044, 0x0f5045, 0x0d9046,
+ 0x4204a2, 0x640422, 0x04904a, 0x426448, 0x04b073, 0x428468, 0x46c04d,
+ 0x48a42a, 0x04f077, 0x076050, 0x42c4b0, 0x0520a7, 0x096053, 0x42e4a8,
+ 0x05507d, 0x07a056, 0x0d4057, 0x0df058, 0x442430, 0x05a081, 0x05b09b,
+ 0x05c0e2, 0x5b8432, 0x4fe434, 0x05f09e, 0x0e6060, 0x0610d6, 0x57c436,
+ 0x0cc063, 0x112064, 0x4384a0, 0x43a5ca, 0x067089, 0x0680b7, 0x0690a2,
+ 0x0a106a, 0x43c59c, 0x09206c, 0x06d0ba, 0x60643e, 0x0d106f, 0x0700ee,
+ 0x0de071, 0x10b072, 0x44056c, 0x46a444, 0x075094, 0x48c44c, 0x44e490,
+ 0x095078, 0x0ab079, 0x4504ce, 0x07b097, 0x11e07c, 0x630452, 0x0ac07e,
+ 0x07f099, 0x080106, 0x4544b8, 0x0820b1, 0x0830e5, 0x4fc456, 0x0b3085,
+ 0x08609d, 0x45853e, 0x0880c2, 0x5c045a, 0x08a08f, 0x08b0ce, 0x08c0f7,
+ 0x58645c, 0x11108e, 0x45e5c4, 0x0c4090, 0x10a091, 0x4604e4, 0x0d0093,
+ 0x462608, 0x48e46e, 0x4704b2, 0x4d2472, 0x0980bd, 0x4f2474, 0x0e309a,
+ 0x4764aa, 0x0be09c, 0x47851a, 0x47a4de, 0x09f0b5, 0x0a00c1, 0x50047c,
+ 0x57847e, 0x0a30c3, 0x504482, 0x0e90a5, 0x0a6100, 0x4c8484, 0x0a811f,
+ 0x48662a, 0x0c70aa, 0x488494, 0x4924d0, 0x0ad0c8, 0x0ae0d8, 0x496636,
+ 0x10e0b0, 0x4f8498, 0x0f30b2, 0x49a4dc, 0x0f20b4, 0x53c49c, 0x0b60cb,
+ 0x49e57a, 0x0b80e0, 0x0b9109, 0x5e44a4, 0x5484a6, 0x4ac4ae, 0x4b44ca,
+ 0x4d64b6, 0x4ba5da, 0x0c60c0, 0x4bc51e, 0x4be556, 0x6204c0, 0x4c24c4,
+ 0x0f80c5, 0x5664c6, 0x4cc53a, 0x4d462c, 0x0f10c9, 0x4d8552, 0x4da4fa,
+ 0x5be4e0, 0x0cd0ff, 0x5244e2, 0x0cf0e8, 0x4e6568, 0x59a4e8, 0x0f90d2,
+ 0x1010d3, 0x5ac4ea, 0x0d50d7, 0x4ec634, 0x4ee560, 0x4f44f0, 0x4f6638,
+ 0x502522, 0x0db0dc, 0x5065a6, 0x508604, 0x60050a, 0x50c0fb, 0x63250e,
+ 0x1130e1, 0x5a4510, 0x5125fc, 0x516514, 0x51863e, 0x51c536, 0x0e70f4,
+ 0x55c520, 0x602526, 0x0eb0ea, 0x5cc528, 0x5ea52a, 0x1140ed, 0x60c52c,
+ 0x1020ef, 0x0f0119, 0x58e52e, 0x530622, 0x558534, 0x53861e, 0x55e540,
+ 0x5800f6, 0x57e542, 0x5445e6, 0x5465e8, 0x0fa115, 0x54c54a, 0x54e60e,
+ 0x5ae550, 0x1160fe, 0x5f0554, 0x564562, 0x56a58a, 0x56e5ee, 0x10310c,
+ 0x5705d0, 0x107105, 0x5725d4, 0x57463a, 0x5765b4, 0x5825bc, 0x5845e2,
+ 0x5885de, 0x58c592, 0x5ce590, 0x5945f6, 0x63c596, 0x11b110, 0x5d8598,
+ 0x5c259e, 0x5e05a0, 0x5a25c6, 0x5a860a, 0x5aa5ec, 0x5b2610, 0x11a118,
+ 0x6185b6, 0x5f25d2, 0x5d6616, 0x5dc5f8, 0x61a5fe, 0x612614, 0x62e624,
+ 0x626628};
+
+/* get starting addresses of huffman tables into an array [convert codebook into
+ * starting address] */
+/* cb tree */
+const UINT *aHuffTable[MAX_CB] = {
+ aHuffTree41,
+ /* 0 - */ /* use tree 1 as dummy here */
+ aHuffTree41, /* 1 1 */
+ aHuffTree42, /* 2 2 */
+ aHuffTree43, /* 3 3 */
+ aHuffTree44, /* 4 4 */
+ aHuffTree21, /* 5 5 */
+ aHuffTree22, /* 6 6 */
+ aHuffTree23, /* 7 7 */
+ aHuffTree24, /* 8 8 */
+ aHuffTree25, /* 9 9 */
+ aHuffTree26, /* 10 10 */
+ aHuffTree27, /* 11 11 */
+ aHuffTree41,
+ /* 12 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 13 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 14 - */ /* use tree 1 as dummy here */
+ aHuffTree41,
+ /* 15 - */ /* use tree 1 as dummy here */
+ aHuffTree27, /* 16 11 */
+ aHuffTree27, /* 17 11 */
+ aHuffTree27, /* 18 11 */
+ aHuffTree27, /* 19 11 */
+ aHuffTree27, /* 20 11 */
+ aHuffTree27, /* 21 11 */
+ aHuffTree27, /* 22 11 */
+ aHuffTree27, /* 23 11 */
+ aHuffTree27, /* 24 11 */
+ aHuffTree27, /* 25 11 */
+ aHuffTree27, /* 26 11 */
+ aHuffTree27, /* 27 11 */
+ aHuffTree27, /* 28 11 */
+ aHuffTree27, /* 29 11 */
+ aHuffTree27, /* 30 11 */
+ aHuffTree27}; /* 31 11 */
+
+/*---------------------------------------------------------------------------------------------
+ data-description:
+ The following tables contain the quantized values. Two or four of the
+ quantized values are indexed by the result of the decoding in the decoding tree
+ (see tables above).
+ --------------------------------------------------------------------------------------------
+ */
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab41 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 1-2. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab41[324] = {
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, 0, -1, -1, -1,
+ 0, 0, -1, -1, 0, 1, -1, -1, 1, -1, -1, -1, 1, 0, -1, -1, 1, 1,
+ -1, 0, -1, -1, -1, 0, -1, 0, -1, 0, -1, 1, -1, 0, 0, -1, -1, 0,
+ 0, 0, -1, 0, 0, 1, -1, 0, 1, -1, -1, 0, 1, 0, -1, 0, 1, 1,
+ -1, 1, -1, -1, -1, 1, -1, 0, -1, 1, -1, 1, -1, 1, 0, -1, -1, 1,
+ 0, 0, -1, 1, 0, 1, -1, 1, 1, -1, -1, 1, 1, 0, -1, 1, 1, 1,
+ 0, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 1, 0, -1, 0, -1, 0, -1,
+ 0, 0, 0, -1, 0, 1, 0, -1, 1, -1, 0, -1, 1, 0, 0, -1, 1, 1,
+ 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, 1, 0, 0, 0, -1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 1, -1, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 1, -1, -1, 0, 1, -1, 0, 0, 1, -1, 1, 0, 1, 0, -1, 0, 1,
+ 0, 0, 0, 1, 0, 1, 0, 1, 1, -1, 0, 1, 1, 0, 0, 1, 1, 1,
+ 1, -1, -1, -1, 1, -1, -1, 0, 1, -1, -1, 1, 1, -1, 0, -1, 1, -1,
+ 0, 0, 1, -1, 0, 1, 1, -1, 1, -1, 1, -1, 1, 0, 1, -1, 1, 1,
+ 1, 0, -1, -1, 1, 0, -1, 0, 1, 0, -1, 1, 1, 0, 0, -1, 1, 0,
+ 0, 0, 1, 0, 0, 1, 1, 0, 1, -1, 1, 0, 1, 0, 1, 0, 1, 1,
+ 1, 1, -1, -1, 1, 1, -1, 0, 1, 1, -1, 1, 1, 1, 0, -1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, -1, 1, 1, 1, 0, 1, 1, 1, 1};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab42 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 3-4. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab42[324] = {
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0,
+ 0, 2, 0, 0, 0, 2, 1, 0, 0, 2, 2, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 2, 0, 1,
+ 1, 0, 0, 1, 1, 1, 0, 1, 1, 2, 0, 1, 2, 0, 0, 1, 2, 1, 0, 1, 2, 2, 0, 2, 0,
+ 0, 0, 2, 0, 1, 0, 2, 0, 2, 0, 2, 1, 0, 0, 2, 1, 1, 0, 2, 1, 2, 0, 2, 2, 0,
+ 0, 2, 2, 1, 0, 2, 2, 2, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 0, 1,
+ 0, 1, 1, 1, 0, 1, 2, 1, 0, 2, 0, 1, 0, 2, 1, 1, 0, 2, 2, 1, 1, 0, 0, 1, 1,
+ 0, 1, 1, 1, 0, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 0, 1, 1, 2,
+ 1, 1, 1, 2, 2, 1, 2, 0, 0, 1, 2, 0, 1, 1, 2, 0, 2, 1, 2, 1, 0, 1, 2, 1, 1,
+ 1, 2, 1, 2, 1, 2, 2, 0, 1, 2, 2, 1, 1, 2, 2, 2, 2, 0, 0, 0, 2, 0, 0, 1, 2,
+ 0, 0, 2, 2, 0, 1, 0, 2, 0, 1, 1, 2, 0, 1, 2, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0,
+ 2, 2, 2, 1, 0, 0, 2, 1, 0, 1, 2, 1, 0, 2, 2, 1, 1, 0, 2, 1, 1, 1, 2, 1, 1,
+ 2, 2, 1, 2, 0, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 0, 0, 2, 2, 0, 1, 2, 2, 0, 2,
+ 2, 2, 1, 0, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 2};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab21 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 5-6. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab21[162] = {
+ -4, -4, -4, -3, -4, -2, -4, -1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 4,
+ -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 3, -3, 4,
+ -2, -4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2, 4,
+ -1, -4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4,
+ 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4,
+ 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4,
+ 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2, 3, 2, 4,
+ 3, -4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4,
+ 4, -4, 4, -3, 4, -2, 4, -1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab22 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 7-8. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab22[128] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 1, 0, 1, 1, 1, 2,
+ 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5,
+ 2, 6, 2, 7, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 4, 0,
+ 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7, 5, 0, 5, 1, 5, 2, 5, 3,
+ 5, 4, 5, 5, 5, 6, 5, 7, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6,
+ 6, 7, 7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab23 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks
+ * 9-10. */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab23[338] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
+ 9, 0, 10, 0, 11, 0, 12, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5,
+ 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11, 1, 12, 2, 0, 2, 1, 2,
+ 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11,
+ 2, 12, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3,
+ 8, 3, 9, 3, 10, 3, 11, 3, 12, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4,
+ 4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 4, 11, 4, 12, 5, 0, 5,
+ 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9, 5, 10,
+ 5, 11, 5, 12, 6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6,
+ 7, 6, 8, 6, 9, 6, 10, 6, 11, 6, 12, 7, 0, 7, 1, 7, 2, 7, 3,
+ 7, 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9, 7, 10, 7, 11, 7, 12, 8,
+ 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8, 9,
+ 8, 10, 8, 11, 8, 12, 9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9,
+ 6, 9, 7, 9, 8, 9, 9, 9, 10, 9, 11, 9, 12, 10, 0, 10, 1, 10, 2,
+ 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10, 10, 10, 11, 10,
+ 12, 11, 0, 11, 1, 11, 2, 11, 3, 11, 4, 11, 5, 11, 6, 11, 7, 11, 8,
+ 11, 9, 11, 10, 11, 11, 11, 12, 12, 0, 12, 1, 12, 2, 12, 3, 12, 4, 12,
+ 5, 12, 6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 12};
+
+/* *********************************************************************************************
+ */
+/* Table: ValTab24 */
+/* ---------------------------------------------------------------------------------------------
+ */
+/* description: This table contains the quantized values for codebooks 11.
+ */
+/* ---------------------------------------------------------------------------------------------
+ */
+const SCHAR aValTab24[578] = {
+ 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0,
+ 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 15, 0, 16, 1, 0, 1, 1,
+ 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1,
+ 11, 1, 12, 1, 13, 1, 14, 1, 15, 1, 16, 2, 0, 2, 1, 2, 2, 2, 3,
+ 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11, 2, 12, 2,
+ 13, 2, 14, 2, 15, 2, 16, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5,
+ 3, 6, 3, 7, 3, 8, 3, 9, 3, 10, 3, 11, 3, 12, 3, 13, 3, 14, 3,
+ 15, 3, 16, 4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7,
+ 4, 8, 4, 9, 4, 10, 4, 11, 4, 12, 4, 13, 4, 14, 4, 15, 4, 16, 5,
+ 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9,
+ 5, 10, 5, 11, 5, 12, 5, 13, 5, 14, 5, 15, 5, 16, 6, 0, 6, 1, 6,
+ 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8, 6, 9, 6, 10, 6, 11,
+ 6, 12, 6, 13, 6, 14, 6, 15, 6, 16, 7, 0, 7, 1, 7, 2, 7, 3, 7,
+ 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9, 7, 10, 7, 11, 7, 12, 7, 13,
+ 7, 14, 7, 15, 7, 16, 8, 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8,
+ 6, 8, 7, 8, 8, 8, 9, 8, 10, 8, 11, 8, 12, 8, 13, 8, 14, 8, 15,
+ 8, 16, 9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9, 6, 9, 7, 9,
+ 8, 9, 9, 9, 10, 9, 11, 9, 12, 9, 13, 9, 14, 9, 15, 9, 16, 10, 0,
+ 10, 1, 10, 2, 10, 3, 10, 4, 10, 5, 10, 6, 10, 7, 10, 8, 10, 9, 10,
+ 10, 10, 11, 10, 12, 10, 13, 10, 14, 10, 15, 10, 16, 11, 0, 11, 1, 11, 2,
+ 11, 3, 11, 4, 11, 5, 11, 6, 11, 7, 11, 8, 11, 9, 11, 10, 11, 11, 11,
+ 12, 11, 13, 11, 14, 11, 15, 11, 16, 12, 0, 12, 1, 12, 2, 12, 3, 12, 4,
+ 12, 5, 12, 6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 12, 12, 13, 12,
+ 14, 12, 15, 12, 16, 13, 0, 13, 1, 13, 2, 13, 3, 13, 4, 13, 5, 13, 6,
+ 13, 7, 13, 8, 13, 9, 13, 10, 13, 11, 13, 12, 13, 13, 13, 14, 13, 15, 13,
+ 16, 14, 0, 14, 1, 14, 2, 14, 3, 14, 4, 14, 5, 14, 6, 14, 7, 14, 8,
+ 14, 9, 14, 10, 14, 11, 14, 12, 14, 13, 14, 14, 14, 15, 14, 16, 15, 0, 15,
+ 1, 15, 2, 15, 3, 15, 4, 15, 5, 15, 6, 15, 7, 15, 8, 15, 9, 15, 10,
+ 15, 11, 15, 12, 15, 13, 15, 14, 15, 15, 15, 16, 16, 0, 16, 1, 16, 2, 16,
+ 3, 16, 4, 16, 5, 16, 6, 16, 7, 16, 8, 16, 9, 16, 10, 16, 11, 16, 12,
+ 16, 13, 16, 14, 16, 15, 16, 16};
+
+/* cb quant. val table */
+const SCHAR *aQuantTable[] = {
+ aValTab41,
+ /* 0 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41, /* 1 1 */
+ aValTab41, /* 2 1 */
+ aValTab42, /* 3 2 */
+ aValTab42, /* 4 2 */
+ aValTab21, /* 5 3 */
+ aValTab21, /* 6 3 */
+ aValTab22, /* 7 4 */
+ aValTab22, /* 8 4 */
+ aValTab23, /* 9 5 */
+ aValTab23, /* 10 5 */
+ aValTab24, /* 11 6 */
+ aValTab41,
+ /* 12 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 13 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 14 - */ /* use quant. val talble 1 as dummy here */
+ aValTab41,
+ /* 15 - */ /* use quant. val talble 1 as dummy here */
+ aValTab24, /* 16 6 */
+ aValTab24, /* 17 6 */
+ aValTab24, /* 18 6 */
+ aValTab24, /* 19 6 */
+ aValTab24, /* 20 6 */
+ aValTab24, /* 21 6 */
+ aValTab24, /* 22 6 */
+ aValTab24, /* 23 6 */
+ aValTab24, /* 24 6 */
+ aValTab24, /* 25 6 */
+ aValTab24, /* 26 6 */
+ aValTab24, /* 27 6 */
+ aValTab24, /* 28 6 */
+ aValTab24, /* 29 6 */
+ aValTab24, /* 30 6 */
+ aValTab24}; /* 31 6 */
+
+/* arrays for HCR_TABLE_INFO structures */
+/* maximum length of codeword in each codebook */
+/* codebook: 0,1, 2,3, 4, 5, 6, 7, 8, 9,
+ * 10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 */
+const UCHAR aMaxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14,
+ 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25,
+ 29, 29, 29, 29, 33, 33, 33, 37, 37, 41};
+
+/* 11 13 15 17 19
+ * 21 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
+ * 22 24 26 28 30 */
+const UCHAR aDimCb[MAX_CB] = {
+ 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; /* codebook dimension -
+ zero cb got a
+ dimension of 2 */
+
+/* 11 13 15 17 19
+ * 21 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20
+ * 22 24 26 28 30 */
+const UCHAR aDimCbShift[MAX_CB] = {
+ 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; /* codebook dimension */
+
+/* 1 -> decode sign bits */
+/* 0 -> decode no sign bits 11 13 15 17 19 21
+ * 23 25 27 39 31 */
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12 14 16 18 20 22
+ * 24 26 28 30 */
+const UCHAR aSignCb[MAX_CB] = {0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+
+/* arrays for HCR_CB_PAIRS structures */
+const UCHAR aMinOfCbPair[MAX_CB_PAIRS] = {0, 1, 3, 5, 7, 9, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 11};
+const UCHAR aMaxOfCbPair[MAX_CB_PAIRS] = {0, 2, 4, 6, 8, 10, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 11};
+
+/* priorities of codebooks */
+const UCHAR aCbPriority[MAX_CB] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
+ 22, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
+
+const SCHAR aCodebook2StartInt[] = {STOP_THIS_STATE, /* cb 0 */
+ BODY_ONLY, /* cb 1 */
+ BODY_ONLY, /* cb 2 */
+ BODY_SIGN__BODY, /* cb 3 */
+ BODY_SIGN__BODY, /* cb 4 */
+ BODY_ONLY, /* cb 5 */
+ BODY_ONLY, /* cb 6 */
+ BODY_SIGN__BODY, /* cb 7 */
+ BODY_SIGN__BODY, /* cb 8 */
+ BODY_SIGN__BODY, /* cb 9 */
+ BODY_SIGN__BODY, /* cb 10 */
+ BODY_SIGN_ESC__BODY, /* cb 11 */
+ STOP_THIS_STATE, /* cb 12 */
+ STOP_THIS_STATE, /* cb 13 */
+ STOP_THIS_STATE, /* cb 14 */
+ STOP_THIS_STATE, /* cb 15 */
+ BODY_SIGN_ESC__BODY, /* cb 16 */
+ BODY_SIGN_ESC__BODY, /* cb 17 */
+ BODY_SIGN_ESC__BODY, /* cb 18 */
+ BODY_SIGN_ESC__BODY, /* cb 19 */
+ BODY_SIGN_ESC__BODY, /* cb 20 */
+ BODY_SIGN_ESC__BODY, /* cb 21 */
+ BODY_SIGN_ESC__BODY, /* cb 22 */
+ BODY_SIGN_ESC__BODY, /* cb 23 */
+ BODY_SIGN_ESC__BODY, /* cb 24 */
+ BODY_SIGN_ESC__BODY, /* cb 25 */
+ BODY_SIGN_ESC__BODY, /* cb 26 */
+ BODY_SIGN_ESC__BODY, /* cb 27 */
+ BODY_SIGN_ESC__BODY, /* cb 28 */
+ BODY_SIGN_ESC__BODY, /* cb 29 */
+ BODY_SIGN_ESC__BODY, /* cb 30 */
+ BODY_SIGN_ESC__BODY}; /* cb 31 */
+
+const STATEFUNC aStateConstant2State[] = {
+ NULL, /* 0 = STOP_THIS_STATE */
+ Hcr_State_BODY_ONLY, /* 1 = BODY_ONLY */
+ Hcr_State_BODY_SIGN__BODY, /* 2 = BODY_SIGN__BODY */
+ Hcr_State_BODY_SIGN__SIGN, /* 3 = BODY_SIGN__SIGN */
+ Hcr_State_BODY_SIGN_ESC__BODY, /* 4 = BODY_SIGN_ESC__BODY */
+ Hcr_State_BODY_SIGN_ESC__SIGN, /* 5 = BODY_SIGN_ESC__SIGN */
+ Hcr_State_BODY_SIGN_ESC__ESC_PREFIX, /* 6 = BODY_SIGN_ESC__ESC_PREFIX */
+ Hcr_State_BODY_SIGN_ESC__ESC_WORD}; /* 7 = BODY_SIGN_ESC__ESC_WORD */
+
+/* CB: 0 1 2 3 4 5 6 7 8 9 10 12
+ * 14 16 18 20 22 24 26 28 30 */
+const USHORT aLargestAbsoluteValue[MAX_CB] = {
+ 0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12,
+ 8191, 0, 0, 0, 0, 15, 31, 47, 63, 95, 127,
+ 159, 191, 223, 255, 319, 383, 511, 767, 1023, 2047}; /* lav */
+/* CB: 11 13
+ * 15 17 19 21 23 25 27 39 31 */
+
+/* ------------------------------------------------------------------------------------------
+ description: The table 'HuffTreeRvlcEscape' contains the decode tree for
+the rvlc escape sequences. bit 23 and 11 not used bit 22 and 10 determine end
+value --> if set codeword is decoded bit 21-12 and 9-0 (offset to next node)
+or (index value) The escape sequence is the index value.
+
+ input: codeword
+ output: index
+------------------------------------------------------------------------------------------
+*/
+const UINT aHuffTreeRvlcEscape[53] = {
+ 0x002001, 0x400003, 0x401004, 0x402005, 0x403007, 0x404006, 0x00a405,
+ 0x009008, 0x00b406, 0x00c407, 0x00d408, 0x00e409, 0x40b40a, 0x40c00f,
+ 0x40d010, 0x40e011, 0x40f012, 0x410013, 0x411014, 0x412015, 0x016413,
+ 0x414415, 0x017416, 0x417018, 0x419019, 0x01a418, 0x01b41a, 0x01c023,
+ 0x03201d, 0x01e020, 0x43501f, 0x41b41c, 0x021022, 0x41d41e, 0x41f420,
+ 0x02402b, 0x025028, 0x026027, 0x421422, 0x423424, 0x02902a, 0x425426,
+ 0x427428, 0x02c02f, 0x02d02e, 0x42942a, 0x42b42c, 0x030031, 0x42d42e,
+ 0x42f430, 0x033034, 0x431432, 0x433434};
+
+/* ------------------------------------------------------------------------------------------
+ description: The table 'HuffTreeRvlc' contains the huffman decoding tree
+for the RVLC scale factors. The table contains 15 allowed, symmetric codewords
+and 8 forbidden codewords, which are used for error detection.
+
+ usage of bits: bit 23 and 11 not used
+ bit 22 and 10 determine end value --> if set codeword is
+decoded bit 21-12 and 9-0 (offset to next node within the table) or (index+7).
+ The decoded (index+7) is in the range from 0,1,..,22. If the
+(index+7) is in the range 15,16,..,22, then a forbidden codeword is decoded.
+
+ input: A single bit from a RVLC scalefactor codeword
+ output: [if codeword is not completely decoded:] offset to next node
+within table or [if codeword is decoded:] A dpcm value i.e. (index+7) in range
+from 0,1,..,22. The differential scalefactor (DPCM value) named 'index' is
+calculated by subtracting 7 from the decoded value (index+7).
+------------------------------------------------------------------------------------------
+*/
+const UINT aHuffTreeRvlCodewds[22] = {
+ 0x407001, 0x002009, 0x003406, 0x004405, 0x005404, 0x006403,
+ 0x007400, 0x008402, 0x411401, 0x00a408, 0x00c00b, 0x00e409,
+ 0x01000d, 0x40f40a, 0x41400f, 0x01340b, 0x011015, 0x410012,
+ 0x41240c, 0x416014, 0x41540d, 0x41340e};
+
+const FIXP_WTB LowDelaySynthesis256[768] = {
+ WTC(0xdaecb88a), WTC(0xdb7a5230), WTC(0xdc093961), WTC(0xdc9977b5),
+ WTC(0xdd2b11b4), WTC(0xddbe06c1), WTC(0xde525277), WTC(0xdee7f167),
+ WTC(0xdf7ee2f9), WTC(0xe0173207), WTC(0xe0b0e70e), WTC(0xe14beb4d),
+ WTC(0xe1e82002), WTC(0xe285693d), WTC(0xe323ba3c), WTC(0xe3c33cdb),
+ WTC(0xe4640c93), WTC(0xe5060b3f), WTC(0xe5a915ce), WTC(0xe64cffc2),
+ WTC(0xe6f19868), WTC(0xe796b4d7), WTC(0xe83c2ebf), WTC(0xe8e1eea1),
+ WTC(0xe987f784), WTC(0xea2e8014), WTC(0xead5a2b6), WTC(0xeb7d3476),
+ WTC(0xec24ebfb), WTC(0xeccc4e9a), WTC(0xed72f723), WTC(0xee18b585),
+ WTC(0xeebd6902), WTC(0xef610661), WTC(0xf0037f41), WTC(0xf0a4c139),
+ WTC(0xf144c5bc), WTC(0xf1e395c4), WTC(0xf2812c5d), WTC(0xf31d6db4),
+ WTC(0xf3b83ed0), WTC(0xf4517963), WTC(0xf4e8d672), WTC(0xf57de495),
+ WTC(0xf610395e), WTC(0xf69f7e84), WTC(0xf72b9152), WTC(0xf7b495b5),
+ WTC(0xf83af453), WTC(0xf8bf7118), WTC(0xf9429a33), WTC(0xf9c4c183),
+ WTC(0xfa466592), WTC(0xfac80867), WTC(0xfb49d2bd), WTC(0xfbcb7294),
+ WTC(0xfc4d0e35), WTC(0xfccf7e7b), WTC(0xfd53af97), WTC(0xfddab5ca),
+ WTC(0xfe629a56), WTC(0xfee5c7c9), WTC(0xff5b6311), WTC(0xffb6bd45),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff6c845), WTC(0xbfe461ee), WTC(0xbfd1f586), WTC(0xbfbf85b2),
+ WTC(0xbfad1518), WTC(0xbf9aa640), WTC(0xbf883911), WTC(0xbf75caf0),
+ WTC(0xbf635c4b), WTC(0xbf50f09b), WTC(0xbf3e886d), WTC(0xbf2c2167),
+ WTC(0xbf19bc2c), WTC(0xbf075c64), WTC(0xbef502db), WTC(0xbee2ad83),
+ WTC(0xbed05d67), WTC(0xbebe16a7), WTC(0xbeabda46), WTC(0xbe99a62e),
+ WTC(0xbe877b90), WTC(0xbe755ee8), WTC(0xbe63517d), WTC(0xbe51515b),
+ WTC(0xbe3f5fc9), WTC(0xbe2d8141), WTC(0xbe1bb721), WTC(0xbe09ffa3),
+ WTC(0xbdf85c17), WTC(0xbde6d0e3), WTC(0xbdd55f47), WTC(0xbdc4055d),
+ WTC(0xbdb2c438), WTC(0xbda19fe0), WTC(0xbd909942), WTC(0xbd7fae2f),
+ WTC(0xbd6edf8d), WTC(0xbd5e3153), WTC(0xbd4da45b), WTC(0xbd3d365a),
+ WTC(0xbd2ce7eb), WTC(0xbd1cbc87), WTC(0xbd0cb466), WTC(0xbcfccc80),
+ WTC(0xbced04c5), WTC(0xbcdd6022), WTC(0xbccdde49), WTC(0xbcbe7bb4),
+ WTC(0xbcaf37ec), WTC(0xbca01594), WTC(0xbc91149b), WTC(0xbc823234),
+ WTC(0xbc736d81), WTC(0xbc64c7a4), WTC(0xbc564085), WTC(0xbc47d6a9),
+ WTC(0xbc398617), WTC(0xbc2b4915), WTC(0xbc1d2a92), WTC(0xbc0f4370),
+ WTC(0xbc016785), WTC(0xbbf32f6c), WTC(0xbbe53648), WTC(0xbbd91eb5),
+ WTC(0xbbd02f7c), WTC(0xbbcb58db), WTC(0xbbca5ac2), WTC(0xbbcbdea2),
+ WTC(0xbbcee192), WTC(0xbbd2c7c2), WTC(0xbbd7a648), WTC(0xbbde3c5a),
+ WTC(0xbbe7079f), WTC(0xbbf238bf), WTC(0xbbff8eec), WTC(0xbc0e5d22),
+ WTC(0xbc1e2c8b), WTC(0xbc2ec3a4), WTC(0xbc402f19), WTC(0xbc52c1ac),
+ WTC(0xbc6709aa), WTC(0xbc7dcbce), WTC(0xbc979383), WTC(0xbcb4ae30),
+ WTC(0xbcd52aeb), WTC(0xbcf8db63), WTC(0xbd1f6993), WTC(0xbd485b46),
+ WTC(0xbd735007), WTC(0xbda003fc), WTC(0xbdce556c), WTC(0xbdfe453b),
+ WTC(0xbe2ffd4e), WTC(0xbe63ceb7), WTC(0xbe9a006f), WTC(0xbed2ce2b),
+ WTC(0xbf0e7d8e), WTC(0xbf4d5cfc), WTC(0xbf8f92bd), WTC(0xbfd5160c),
+ WTC(0xc01d3b27), WTC(0xc066b8f5), WTC(0xc0b0a3b8), WTC(0xc0fa7cdd),
+ WTC(0xc144b0e8), WTC(0xc1908d71), WTC(0xc1ded403), WTC(0xc22fae49),
+ WTC(0xc2830092), WTC(0xc2d86ca8), WTC(0xc32f4341), WTC(0xc38687e5),
+ WTC(0xc3dd5c55), WTC(0xc43310e4), WTC(0xc4883eca), WTC(0xc4deba3d),
+ WTC(0xc5372c82), WTC(0xc59102fb), WTC(0xc5eb416a), WTC(0xc644986f),
+ WTC(0xc69cabb2), WTC(0xc6f41290), WTC(0xc74b22bf), WTC(0xc7a1e4b9),
+ WTC(0xc7f83500), WTC(0xc84dc737), WTC(0xc8a24e07), WTC(0xc8f5776f),
+ WTC(0xb4db4a8b), WTC(0xb3c58a32), WTC(0xb2b2acb4), WTC(0xb1a2afc0),
+ WTC(0xb0959107), WTC(0xaf8b4e0a), WTC(0xae83dfef), WTC(0xad7f3ba6),
+ WTC(0xac7d5a57), WTC(0xab7e397d), WTC(0xaa81d5a7), WTC(0xa9882a64),
+ WTC(0xa89135bc), WTC(0xa79cf84e), WTC(0xa6ab74fc), WTC(0xa5bcb0d0),
+ WTC(0xa4d0b1b8), WTC(0xa3e77e6d), WTC(0xa3011e16), WTC(0xa21d986c),
+ WTC(0xa13cf921), WTC(0xa05f4fb9), WTC(0x9f84a850), WTC(0x9ead0baf),
+ WTC(0x9dd8888c), WTC(0x9d073385), WTC(0x9c391db5), WTC(0x9b6e5484),
+ WTC(0x9aa6e656), WTC(0x99e2e2c5), WTC(0x99225ac4), WTC(0x9865608a),
+ WTC(0x97ac0564), WTC(0x96f65984), WTC(0x96446a25), WTC(0x95964196),
+ WTC(0x94ebe9ec), WTC(0x94456d19), WTC(0x93a2d46a), WTC(0x93042864),
+ WTC(0x92696dea), WTC(0x91d2a637), WTC(0x913fd120), WTC(0x90b0ecfe),
+ WTC(0x9025f239), WTC(0x8f9ed33e), WTC(0x8f1b804b), WTC(0x8e9be72b),
+ WTC(0x8e1fe984), WTC(0x8da75ce4), WTC(0x8d321511), WTC(0x8cbfe381),
+ WTC(0x8c508090), WTC(0x8be38b7b), WTC(0x8b78a10a), WTC(0x8b0f5bb4),
+ WTC(0x8aa740f3), WTC(0x8a3fc439), WTC(0x89d8a093), WTC(0x8971e7bf),
+ WTC(0x890d0fa8), WTC(0x88acfc32), WTC(0x8855e07a), WTC(0x880d5010),
+ WTC(0x87cc444c), WTC(0x87b6e84e), WTC(0x879e3713), WTC(0x87850a87),
+ WTC(0x876c76ee), WTC(0x8753c55a), WTC(0x873aa70d), WTC(0x872147e7),
+ WTC(0x8707bb23), WTC(0x86edf64f), WTC(0x86d3f20d), WTC(0x86b9ab68),
+ WTC(0x869f21e7), WTC(0x86845744), WTC(0x8669499e), WTC(0x864df395),
+ WTC(0x863254b2), WTC(0x8616715e), WTC(0x85fa4870), WTC(0x85ddd324),
+ WTC(0x85c1108b), WTC(0x85a40597), WTC(0x8586b1d1), WTC(0x85690f48),
+ WTC(0x854b1dfb), WTC(0x852ce3e7), WTC(0x850e61c8), WTC(0x84ef9303),
+ WTC(0x84d078c2), WTC(0x84b119fa), WTC(0x849177fa), WTC(0x84718e56),
+ WTC(0x84515e65), WTC(0x8430ef53), WTC(0x841042cb), WTC(0x83ef54e8),
+ WTC(0x83ce27ab), WTC(0x83acc30a), WTC(0x838b2934), WTC(0x83695686),
+ WTC(0x83474d47), WTC(0x832515b6), WTC(0x8302b202), WTC(0x82e01e3b),
+ WTC(0x82bd5c8e), WTC(0x829a755a), WTC(0x82776abf), WTC(0x8254388a),
+ WTC(0x8230e07e), WTC(0x820d6a69), WTC(0x81e9d82d), WTC(0x81c625ae),
+ WTC(0x81a25455), WTC(0x817e6b1f), WTC(0x815a6b39), WTC(0x81364fec),
+ WTC(0x81121a34), WTC(0x80edd0c9), WTC(0x80c97479), WTC(0x80a5000a),
+ WTC(0x80807332), WTC(0x805bd2e6), WTC(0x80372460), WTC(0x80126cc4),
+ WTC(0x0a8a8431), WTC(0x0ae3c329), WTC(0x0b3fdab2), WTC(0x0b9e6e44),
+ WTC(0x0bff2161), WTC(0x0c619a72), WTC(0x0cc5c66d), WTC(0x0d2bd6df),
+ WTC(0x0d93cf64), WTC(0x0dfd8545), WTC(0x0e69093a), WTC(0x0ed6a636),
+ WTC(0x0f465aea), WTC(0x0fb7d810), WTC(0x102ade99), WTC(0x109f4245),
+ WTC(0x1114c9e8), WTC(0x118b31bc), WTC(0x120282b8), WTC(0x127b0be1),
+ WTC(0x12f46b9a), WTC(0x136d8dde), WTC(0x13e57912), WTC(0x145b55cb),
+ WTC(0x14ce5b18), WTC(0x153dccd0), WTC(0x15a8e724), WTC(0x160edefe),
+ WTC(0x166f004f), WTC(0x16c8aff4), WTC(0x171b7afc), WTC(0x17673db3),
+ WTC(0x17afb798), WTC(0x17fc62a2), WTC(0x185114c1), WTC(0x18add722),
+ WTC(0x1912798d), WTC(0x197eb9a2), WTC(0x19f25657), WTC(0x1a6d113e),
+ WTC(0x1aeeb824), WTC(0x1b7723ab), WTC(0x1c060b77), WTC(0x1c9b09a1),
+ WTC(0x1d361822), WTC(0x1dd7933f), WTC(0x1e7ff592), WTC(0x1f2fd0b5),
+ WTC(0x1fe762a9), WTC(0x20a68700), WTC(0x216bbf5e), WTC(0x22344798),
+ WTC(0x22feebdb), WTC(0x23cc22a6), WTC(0x249da10b), WTC(0x25762e41),
+ WTC(0x2655ebc8), WTC(0x273a4e66), WTC(0x28212eaa), WTC(0x2908ff30),
+ WTC(0x29f2ca00), WTC(0x2ae221c4), WTC(0x2bd9c6fc), WTC(0x2cdb967e),
+ WTC(0x2de64c86), WTC(0x2ef61340), WTC(0x3006852b), WTC(0x31131a1b),
+ WTC(0x321aec79), WTC(0x3320d4ed), WTC(0x342a2cb3), WTC(0x353e77f7),
+ WTC(0x3660aaba), WTC(0x378ef057), WTC(0x38c42495), WTC(0x39f81cec),
+ WTC(0x3b250148), WTC(0x3c47960e), WTC(0x3d60c625), WTC(0x3e75864a),
+ WTC(0x3f8a9ef7), WTC(0x40a46d36), WTC(0x41c537d7), WTC(0x42ed2889),
+ WTC(0x441b52d1), WTC(0x454dc37f), WTC(0x4681e9fa), WTC(0x47b4a9fe),
+ WTC(0x48e39960), WTC(0x4a0d10fd), WTC(0x4b30824b), WTC(0x4c4e759e),
+ WTC(0x4d680b1c), WTC(0x4e7eecaa), WTC(0x4f947d1e), WTC(0x50a9d1f4),
+ WTC(0x51bfee19), WTC(0x52d7be4d), WTC(0x53f187eb), WTC(0x550cd3c8),
+ WTC(0x56270706), WTC(0x573b7c75), WTC(0x58474819), WTC(0x59496ae2),
+ WTC(0x5a43dfa0), WTC(0x5b3b721f), WTC(0x5c32e266), WTC(0x5d2abea1),
+ WTC(0x5e22b479), WTC(0x5f199f8b), WTC(0x600d9194), WTC(0x60fbe188),
+ WTC(0x61e289de), WTC(0x62c0520c), WTC(0x63974d1e), WTC(0x646cb022),
+ WTC(0x6542745a), WTC(0x66172e2f), WTC(0x66e897d0), WTC(0x67b3cc52),
+ WTC(0x68783ebd), WTC(0x6937b9ed), WTC(0x69f365dd), WTC(0x6aabab1a),
+ WTC(0x6b60849c), WTC(0x6c11876e), WTC(0x6cbe46f0), WTC(0x6d6645bc),
+ WTC(0xae238366), WTC(0xb047d99a), WTC(0xb26207ba), WTC(0xb4733ab5),
+ WTC(0xb67c9f5f), WTC(0xb87f5bce), WTC(0xba7bf18d), WTC(0xbc723dd6),
+ WTC(0xbe621be8), WTC(0xc04b6b3d), WTC(0xc22e00ff), WTC(0xc409a8ad),
+ WTC(0xc5de425b), WTC(0xc7abc2a7), WTC(0xc9721421), WTC(0xcb31173c),
+ WTC(0xcce8c08d), WTC(0xce991894), WTC(0xd04218cd), WTC(0xd1e3aba9),
+ WTC(0xd37dcf0c), WTC(0xd510942f), WTC(0xd69bfa86), WTC(0xd81fefcc),
+ WTC(0xd99c766d), WTC(0xdb11a570), WTC(0xdc7f806e), WTC(0xdde5f79d),
+ WTC(0xdf451092), WTC(0xe09ce645), WTC(0xe1ed7fff), WTC(0xe336d16a),
+ WTC(0xe478e4f4), WTC(0xe5b3dbbb), WTC(0xe6e7c1ac), WTC(0xe8148d53),
+ WTC(0xe93a4835), WTC(0xea590eb0), WTC(0xeb70e4f8), WTC(0xec81b75d),
+ WTC(0xed8b8b6c), WTC(0xee8e8068), WTC(0xef8aa970), WTC(0xf0800dfd),
+ WTC(0xf16edc4d), WTC(0xf2576853), WTC(0xf339e058), WTC(0xf4164a51),
+ WTC(0xf4ec8fb8), WTC(0xf5bc7cef), WTC(0xf685a697), WTC(0xf74771c9),
+ WTC(0xf801f31b), WTC(0xf8b5eeb1), WTC(0xf963fadb), WTC(0xfa0c7427),
+ WTC(0xfaaf3e0f), WTC(0xfb4bcb6d), WTC(0xfbe2276f), WTC(0xfc72f578),
+ WTC(0xfcfe65d9), WTC(0xfd842e5b), WTC(0xfe03e14e), WTC(0xfe7ce07d),
+ WTC(0xfeef932b), WTC(0xff5d0236), WTC(0xffc68fee), WTC(0x002dbccc),
+ WTC(0x00927c78), WTC(0x00f32cbd), WTC(0x014d7209), WTC(0x019e5f51),
+ WTC(0x01e550aa), WTC(0x0223fc07), WTC(0x025d2618), WTC(0x02947b12),
+ WTC(0x02cc33db), WTC(0x0304fa92), WTC(0x033db713), WTC(0x0373a431),
+ WTC(0x03a47d96), WTC(0x03ce9b0f), WTC(0x03f14dc9), WTC(0x040ce0bc),
+ WTC(0x042245a9), WTC(0x043309a5), WTC(0x0440981a), WTC(0x044c30f1),
+ WTC(0x0456bb74), WTC(0x0460c1b4), WTC(0x046a2fdd), WTC(0x0472573f),
+ WTC(0x047877b6), WTC(0x047bc673), WTC(0x047b8615), WTC(0x04770be2),
+ WTC(0x046e23fc), WTC(0x04611460), WTC(0x04507fbd), WTC(0x043d6170),
+ WTC(0x0428ca31), WTC(0x0413d39a), WTC(0x03feb9c3), WTC(0x03e8d946),
+ WTC(0x03d16667), WTC(0x03b77aba), WTC(0x039aa384), WTC(0x037ae75c),
+ WTC(0x0358be80), WTC(0x03350af6), WTC(0x031064fa), WTC(0x02eb13f6),
+ WTC(0x02c51a7b), WTC(0x029e38b0), WTC(0x027619ef), WTC(0x024c5c09),
+ WTC(0x02210ea3), WTC(0x01f4b19e), WTC(0x01c78f79), WTC(0x0199b8ad),
+ WTC(0x016b3aef), WTC(0x013c2366), WTC(0x010c7be8), WTC(0x00dc4bb5),
+ WTC(0x00abab29), WTC(0x007ac3e1), WTC(0x0049c02f), WTC(0x0018ca71),
+ WTC(0xd6208221), WTC(0xd54e9f5b), WTC(0xd47fa35f), WTC(0xd3b35bdb),
+ WTC(0xd2e99693), WTC(0xd2222685), WTC(0xd15d5e4c), WTC(0xd09c06ff),
+ WTC(0xcfde0c24), WTC(0xcf2281d2), WTC(0xce698b2a), WTC(0xcdb455e0),
+ WTC(0xcd02c9b7), WTC(0xcc5381e5), WTC(0xcba580c3), WTC(0xcaf839ea),
+ WTC(0xca4ad0b7), WTC(0xc99c2153), WTC(0xc8ec5a61), WTC(0xc83ce258),
+ WTC(0xc78c42cd), WTC(0xc6d6213b), WTC(0xc616a6e0), WTC(0xc54a9f27),
+ WTC(0xc46ee44d), WTC(0xc38058a2), WTC(0xc27bd88d), WTC(0xc15e3d07),
+ WTC(0xc024a4d9), WTC(0xbecc7ca2), WTC(0xbd53f2b9), WTC(0xbbba98b4),
+ WTC(0xba0ffbc3), WTC(0xb872fb24), WTC(0xb6f36547), WTC(0xb5915345),
+ WTC(0xb44c3975), WTC(0xb3238942), WTC(0xb216b3fb), WTC(0xb1252b0b),
+ WTC(0xb04e5fc8), WTC(0xaf91c370), WTC(0xaeeec760), WTC(0xae64dd0b),
+ WTC(0xadf375ce), WTC(0xad9a02f0), WTC(0xad57f5bc), WTC(0xad2cbf87),
+ WTC(0xad17d19d), WTC(0xad189d42), WTC(0xad2e93d6), WTC(0xad5926d3),
+ WTC(0xad97c78a), WTC(0xade9e726), WTC(0xae4ef6fc), WTC(0xaec6688c),
+ WTC(0xaf4fad2c), WTC(0xafea3605), WTC(0xb0957469), WTC(0xb150d9d2),
+ WTC(0xb21bd793), WTC(0xb2f5de5d), WTC(0xb3de573d), WTC(0xb4d4de47),
+ WTC(0xb5d89c80), WTC(0xb6e937c2), WTC(0xb8061354), WTC(0xb92ea07c),
+ WTC(0xba62508e), WTC(0xbba094e4), WTC(0xbce8dee0), WTC(0xbe3a9fe3),
+ WTC(0xbf954939), WTC(0xc0f84c11), WTC(0xc26319c2), WTC(0xc3d523c5),
+ WTC(0xc54ddb77), WTC(0xc6ccb217), WTC(0xc85118f8), WTC(0xc9da8182),
+ WTC(0xcb685d07), WTC(0xccfa1cc7), WTC(0xce8f3211), WTC(0xd0270e48),
+ WTC(0xd1c122c7), WTC(0xd35ce0de), WTC(0xd4f9b9e1), WTC(0xd6971f23),
+ WTC(0xd83481f8), WTC(0xd9d153bb), WTC(0xdb6d05c0), WTC(0xdd070956),
+ WTC(0xde9ecfd2), WTC(0xe033ca91), WTC(0xe1c56ae7), WTC(0xe3532223),
+ WTC(0xe4dc6199), WTC(0xe6609aa5), WTC(0xe7df3e9a), WTC(0xe957bec9),
+ WTC(0xeac98c84), WTC(0xec341927), WTC(0xed96d607), WTC(0xeef13474),
+ WTC(0xf042a5c5), WTC(0xf18a9b4e), WTC(0xf2c88667), WTC(0xf3fbd863),
+ WTC(0xf5240296), WTC(0xf6407658), WTC(0xf750a4fe), WTC(0xf853ffda),
+ WTC(0xf949f840), WTC(0xfa31ff83), WTC(0xfb0b86fb), WTC(0xfbd5fffe),
+ WTC(0xfc90dbe1), WTC(0xfd3b8bf8), WTC(0xfdd58197), WTC(0xfe5e2e14),
+ WTC(0xfed502c4), WTC(0xff3970fc), WTC(0xff8aea0f), WTC(0xffc8df55),
+ WTC(0xfff2c233), WTC(0x000804e6), WTC(0x0008256a), WTC(0xfff25358),
+};
+
+const FIXP_WTB LowDelaySynthesis240[720] = {
+ WTC(0xdaf16ba1), WTC(0xdb888d4d), WTC(0xdc212bc1), WTC(0xdcbb51d0),
+ WTC(0xdd5703be), WTC(0xddf43f3b), WTC(0xde92fee5), WTC(0xdf333f92),
+ WTC(0xdfd505d1), WTC(0xe078624a), WTC(0xe11d48ff), WTC(0xe1c39358),
+ WTC(0xe26b2066), WTC(0xe313d8a9), WTC(0xe3bde63c), WTC(0xe4696e45),
+ WTC(0xe5164d95), WTC(0xe5c4597d), WTC(0xe673596f), WTC(0xe723153c),
+ WTC(0xe7d35813), WTC(0xe883fa49), WTC(0xe934e7a3), WTC(0xe9e64205),
+ WTC(0xea984aa8), WTC(0xeb4ae6ef), WTC(0xebfdcbf6), WTC(0xecb0744b),
+ WTC(0xed625671), WTC(0xee133361), WTC(0xeec2e1b4), WTC(0xef715334),
+ WTC(0xf01e7588), WTC(0xf0ca33ec), WTC(0xf1748a4e), WTC(0xf21d83ed),
+ WTC(0xf2c50dbe), WTC(0xf36b0639), WTC(0xf40f4892), WTC(0xf4b1944d),
+ WTC(0xf5517289), WTC(0xf5ee573d), WTC(0xf687d70d), WTC(0xf71db368),
+ WTC(0xf7b01057), WTC(0xf83f6570), WTC(0xf8cc9d0a), WTC(0xf9585a73),
+ WTC(0xf9e307f8), WTC(0xfa6d44d2), WTC(0xfaf79d75), WTC(0xfb8208e8),
+ WTC(0xfc0c33c8), WTC(0xfc96d00c), WTC(0xfd22f257), WTC(0xfdb1e623),
+ WTC(0xfe4318a3), WTC(0xfed08c1d), WTC(0xff5091f1), WTC(0xffb4390a),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff62b62), WTC(0xbfe28a84), WTC(0xbfcee30d), WTC(0xbfbb3832),
+ WTC(0xbfa78d29), WTC(0xbf93e490), WTC(0xbf803cc6), WTC(0xbf6c9376),
+ WTC(0xbf58eb89), WTC(0xbf4547f8), WTC(0xbf31a6aa), WTC(0xbf1e06a3),
+ WTC(0xbf0a6bdf), WTC(0xbef6d863), WTC(0xbee349e5), WTC(0xbecfc145),
+ WTC(0xbebc4362), WTC(0xbea8d111), WTC(0xbe956806), WTC(0xbe820aeb),
+ WTC(0xbe6ebeb9), WTC(0xbe5b8313), WTC(0xbe485678), WTC(0xbe353cfb),
+ WTC(0xbe223ab8), WTC(0xbe0f4e5f), WTC(0xbdfc77b4), WTC(0xbde9bb99),
+ WTC(0xbdd71cbe), WTC(0xbdc4990d), WTC(0xbdb23175), WTC(0xbd9feab6),
+ WTC(0xbd8dc58d), WTC(0xbd7bbf8c), WTC(0xbd69daec), WTC(0xbd581c07),
+ WTC(0xbd46820c), WTC(0xbd350af8), WTC(0xbd23b9cc), WTC(0xbd129158),
+ WTC(0xbd018ece), WTC(0xbcf0b057), WTC(0xbcdff912), WTC(0xbccf69cf),
+ WTC(0xbcbefe81), WTC(0xbcaeb63a), WTC(0xbc9e9406), WTC(0xbc8e977c),
+ WTC(0xbc7ebd58), WTC(0xbc6f0544), WTC(0xbc5f7077), WTC(0xbc4ffe1d),
+ WTC(0xbc40ab99), WTC(0xbc317239), WTC(0xbc2252ad), WTC(0xbc136963),
+ WTC(0xbc04a822), WTC(0xbbf5941e), WTC(0xbbe68dab), WTC(0xbbd97a36),
+ WTC(0xbbcff44f), WTC(0xbbcb1891), WTC(0xbbca7818), WTC(0xbbcc765f),
+ WTC(0xbbcffaa5), WTC(0xbbd46a0f), WTC(0xbbda4060), WTC(0xbbe257f1),
+ WTC(0xbbed131c), WTC(0xbbfa7628), WTC(0xbc09cdd6), WTC(0xbc1a685b),
+ WTC(0xbc2bf2fd), WTC(0xbc3e6557), WTC(0xbc521d37), WTC(0xbc67c093),
+ WTC(0xbc803b98), WTC(0xbc9c3060), WTC(0xbcbbf6da), WTC(0xbcdf8c51),
+ WTC(0xbd06afb5), WTC(0xbd30e36d), WTC(0xbd5d99a0), WTC(0xbd8c71a6),
+ WTC(0xbdbd29c3), WTC(0xbdefb72a), WTC(0xbe243660), WTC(0xbe5b0335),
+ WTC(0xbe9477fd), WTC(0xbed0de00), WTC(0xbf108881), WTC(0xbf53d585),
+ WTC(0xbf9aeeba), WTC(0xbfe5bb38), WTC(0xc033318c), WTC(0xc081cdf2),
+ WTC(0xc0d0a9ee), WTC(0xc11f76d5), WTC(0xc16f66c3), WTC(0xc1c1d5c1),
+ WTC(0xc21726d4), WTC(0xc26f5bba), WTC(0xc2ca1036), WTC(0xc3268b0f),
+ WTC(0xc3839ff3), WTC(0xc3e03d22), WTC(0xc43b93ef), WTC(0xc4968594),
+ WTC(0xc4f3353c), WTC(0xc55202ab), WTC(0xc5b21fcf), WTC(0xc61224e6),
+ WTC(0xc670c168), WTC(0xc6ce3f1e), WTC(0xc72b3fbb), WTC(0xc787e688),
+ WTC(0xc7e41f56), WTC(0xc83f94a9), WTC(0xc899e833), WTC(0xc8f2b832),
+ WTC(0xb4d1fc78), WTC(0xb3a9ec70), WTC(0xb28524ca), WTC(0xb163a2ba),
+ WTC(0xb0456373), WTC(0xaf2a6327), WTC(0xae129708), WTC(0xacfdf2ca),
+ WTC(0xabec7168), WTC(0xaade0f8c), WTC(0xa9d2c80a), WTC(0xa8ca9711),
+ WTC(0xa7c57cdc), WTC(0xa6c37c29), WTC(0xa5c49ae6), WTC(0xa4c8e02c),
+ WTC(0xa3d05422), WTC(0xa2daff83), WTC(0xa1e8ec04), WTC(0xa0fa293f),
+ WTC(0xa00ec98a), WTC(0x9f26d990), WTC(0x9e4265a5), WTC(0x9d618437),
+ WTC(0x9c844ce0), WTC(0x9baad0fa), WTC(0x9ad52154), WTC(0x9a03509b),
+ WTC(0x993572ed), WTC(0x986b9e4d), WTC(0x97a5e7d8), WTC(0x96e46329),
+ WTC(0x96271ff8), WTC(0x956e2ab8), WTC(0x94b98f9c), WTC(0x94095a97),
+ WTC(0x935d969b), WTC(0x92b64cdf), WTC(0x9213809b), WTC(0x9175328a),
+ WTC(0x90db6153), WTC(0x90460712), WTC(0x8fb5146f), WTC(0x8f2876f4),
+ WTC(0x8ea018e5), WTC(0x8e1bd6df), WTC(0x8d9b7d9b), WTC(0x8d1ed745),
+ WTC(0x8ca5a942), WTC(0x8c2f93ce), WTC(0x8bbc204c), WTC(0x8b4ad58d),
+ WTC(0x8adb31e4), WTC(0x8a6c909b), WTC(0x89fe673d), WTC(0x8990a478),
+ WTC(0x89244670), WTC(0x88bc84cb), WTC(0x885e0963), WTC(0x880f73f5),
+ WTC(0x87cba2c0), WTC(0x87b48a6f), WTC(0x8799fb25), WTC(0x877f46f2),
+ WTC(0x876519cd), WTC(0x874a9a11), WTC(0x872fae01), WTC(0x871487d2),
+ WTC(0x86f9287b), WTC(0x86dd83b5), WTC(0x86c1947c), WTC(0x86a558f1),
+ WTC(0x8688d2e3), WTC(0x866c015b), WTC(0x864ede0c), WTC(0x863167cc),
+ WTC(0x8613a3b8), WTC(0x85f58fb2), WTC(0x85d723f0), WTC(0x85b86176),
+ WTC(0x85994d82), WTC(0x8579e443), WTC(0x855a201b), WTC(0x853a05b7),
+ WTC(0x85199a26), WTC(0x84f8d93f), WTC(0x84d7c100), WTC(0x84b65901),
+ WTC(0x8494a4ee), WTC(0x84729fd4), WTC(0x84504a9b), WTC(0x842dadb3),
+ WTC(0x840aca71), WTC(0x83e79c87), WTC(0x83c42892), WTC(0x83a07767),
+ WTC(0x837c883a), WTC(0x83585835), WTC(0x8333eeca), WTC(0x830f5368),
+ WTC(0x82ea82ec), WTC(0x82c57c57), WTC(0x82a048ea), WTC(0x827aed86),
+ WTC(0x82556588), WTC(0x822fb255), WTC(0x8209dd1e), WTC(0x81e3e76f),
+ WTC(0x81bdccac), WTC(0x81979098), WTC(0x81713ad7), WTC(0x814ac95d),
+ WTC(0x812437f2), WTC(0x80fd8c4b), WTC(0x80d6cc0a), WTC(0x80aff283),
+ WTC(0x8088fc64), WTC(0x8061eebe), WTC(0x803acfe9), WTC(0x8013a62d),
+ WTC(0x0a8d710a), WTC(0x0aecd974), WTC(0x0b4f7449), WTC(0x0bb4d13b),
+ WTC(0x0c1c7fee), WTC(0x0c86202a), WTC(0x0cf1c2e7), WTC(0x0d5f98d1),
+ WTC(0x0dcf816a), WTC(0x0e4162ae), WTC(0x0eb588ad), WTC(0x0f2c1e88),
+ WTC(0x0fa4d14f), WTC(0x101f4d80), WTC(0x109b5bfd), WTC(0x1118b908),
+ WTC(0x11971466), WTC(0x12168249), WTC(0x129754ab), WTC(0x1318d5c0),
+ WTC(0x1399b5d7), WTC(0x1418d8ec), WTC(0x14953f24), WTC(0x150dfe8a),
+ WTC(0x15822faa), WTC(0x15f0dd70), WTC(0x16592014), WTC(0x16ba35b2),
+ WTC(0x171384e7), WTC(0x1764cf1f), WTC(0x17b22a28), WTC(0x18047d40),
+ WTC(0x185ffc05), WTC(0x18c4a075), WTC(0x19322980), WTC(0x19a84643),
+ WTC(0x1a26a8f4), WTC(0x1aad099d), WTC(0x1b3b3493), WTC(0x1bd0eb32),
+ WTC(0x1c6db754), WTC(0x1d115a8c), WTC(0x1dbc329b), WTC(0x1e6ecb33),
+ WTC(0x1f29d42a), WTC(0x1feda2e4), WTC(0x20ba056e), WTC(0x218d02a2),
+ WTC(0x22635c75), WTC(0x233c2e7f), WTC(0x24184da1), WTC(0x24fa799d),
+ WTC(0x25e54e95), WTC(0x26d6edd8), WTC(0x27cc57a5), WTC(0x28c36349),
+ WTC(0x29bbdfdf), WTC(0x2ab9b7c2), WTC(0x2bc09790), WTC(0x2cd2d465),
+ WTC(0x2def4cb9), WTC(0x2f115dcc), WTC(0x3033a99c), WTC(0x3150fd8d),
+ WTC(0x32698a94), WTC(0x338152e6), WTC(0x34a02dcd), WTC(0x35cdedd1),
+ WTC(0x370aa9fa), WTC(0x38527a79), WTC(0x399c4a4f), WTC(0x3adf9c27),
+ WTC(0x3c17edc7), WTC(0x3d44f05d), WTC(0x3e6c519e), WTC(0x3f93ea5b),
+ WTC(0x40c0fc6d), WTC(0x41f60bdd), WTC(0x43332d15), WTC(0x4476e6ea),
+ WTC(0x45beb7e1), WTC(0x47072f2b), WTC(0x484cb71a), WTC(0x498ceafd),
+ WTC(0x4ac650c3), WTC(0x4bf93458), WTC(0x4d26a4c7), WTC(0x4e5090eb),
+ WTC(0x4f78c2ac), WTC(0x50a0918a), WTC(0x51c93995), WTC(0x52f3d6c7),
+ WTC(0x5420a9a2), WTC(0x554ef122), WTC(0x567ac4a9), WTC(0x579ebeb9),
+ WTC(0x58b8569c), WTC(0x59c74ea4), WTC(0x5ad03f31), WTC(0x5bd821c8),
+ WTC(0x5ce05502), WTC(0x5de8e582), WTC(0x5ef09b49), WTC(0x5ff56247),
+ WTC(0x60f40d81), WTC(0x61ea1450), WTC(0x62d60a2d), WTC(0x63bad7f1),
+ WTC(0x649e942e), WTC(0x65827556), WTC(0x66648178), WTC(0x67418c31),
+ WTC(0x6816c1ee), WTC(0x68e5411d), WTC(0x69aeffdb), WTC(0x6a74bb0e),
+ WTC(0x6b36a5ae), WTC(0x6bf44fd1), WTC(0x6cad341f), WTC(0x6d60c0ca),
+ WTC(0xae35f79b), WTC(0xb07e1b0d), WTC(0xb2bad26d), WTC(0xb4ed8af7),
+ WTC(0xb717b207), WTC(0xb93a8f5b), WTC(0xbb56631e), WTC(0xbd6afcab),
+ WTC(0xbf7832db), WTC(0xc17dd996), WTC(0xc37bb355), WTC(0xc5718d72),
+ WTC(0xc75f56cc), WTC(0xc944f93d), WTC(0xcb224f17), WTC(0xccf74805),
+ WTC(0xcec3ed8c), WTC(0xd08835d9), WTC(0xd2440837), WTC(0xd3f7692d),
+ WTC(0xd5a26b17), WTC(0xd74502b6), WTC(0xd8df1f82), WTC(0xda70d495),
+ WTC(0xdbfa35a1), WTC(0xdd7b3498), WTC(0xdef3cba3), WTC(0xe064184e),
+ WTC(0xe1cc2ab9), WTC(0xe32bf548), WTC(0xe48381cd), WTC(0xe5d2f779),
+ WTC(0xe71a6218), WTC(0xe859b789), WTC(0xe9910a60), WTC(0xeac07956),
+ WTC(0xebe7fb55), WTC(0xed077f41), WTC(0xee1f1f9d), WTC(0xef2efd99),
+ WTC(0xf0372472), WTC(0xf137b605), WTC(0xf23112b3), WTC(0xf323808a),
+ WTC(0xf40f0a86), WTC(0xf4f39883), WTC(0xf5d0eb3c), WTC(0xf6a679c6),
+ WTC(0xf7739640), WTC(0xf8389849), WTC(0xf8f66b2a), WTC(0xf9ada7d6),
+ WTC(0xfa5e97ed), WTC(0xfb08becd), WTC(0xfbabb380), WTC(0xfc48125f),
+ WTC(0xfcde5b40), WTC(0xfd6e4aac), WTC(0xfdf76560), WTC(0xfe78f3ab),
+ WTC(0xfef34cf0), WTC(0xff67b689), WTC(0xffd7e342), WTC(0x004584ef),
+ WTC(0x00b00074), WTC(0x01152d47), WTC(0x0171ccea), WTC(0x01c2fdbe),
+ WTC(0x0209b563), WTC(0x02489832), WTC(0x0283e2cd), WTC(0x02bf2050),
+ WTC(0x02fb72fb), WTC(0x03381f29), WTC(0x0371ea7c), WTC(0x03a602f3),
+ WTC(0x03d267e0), WTC(0x03f6621b), WTC(0x04125dc8), WTC(0x0427b7a5),
+ WTC(0x04385062), WTC(0x0445caca), WTC(0x04518ee3), WTC(0x045c745e),
+ WTC(0x0466d714), WTC(0x0470125c), WTC(0x047742d7), WTC(0x047b73cf),
+ WTC(0x047bba82), WTC(0x047744aa), WTC(0x046dc536), WTC(0x045f9068),
+ WTC(0x044d7632), WTC(0x0438aa92), WTC(0x04227f39), WTC(0x040c2331),
+ WTC(0x03f561d8), WTC(0x03dd60b4), WTC(0x03c31064), WTC(0x03a58d7d),
+ WTC(0x0384b74f), WTC(0x0360e29a), WTC(0x033b1151), WTC(0x031417f0),
+ WTC(0x02ec54ca), WTC(0x02c3d2ce), WTC(0x029a458d), WTC(0x026f4411),
+ WTC(0x02426093), WTC(0x0213d67f), WTC(0x01e43b01), WTC(0x01b3c7c1),
+ WTC(0x01828dd8), WTC(0x01509d92), WTC(0x011e0556), WTC(0x00eace1d),
+ WTC(0x00b70bb3), WTC(0x0082ed8b), WTC(0x004ea707), WTC(0x001a6b8f),
+ WTC(0xd619769b), WTC(0xd539cbf6), WTC(0xd45d68b9), WTC(0xd3840fce),
+ WTC(0xd2ad840b), WTC(0xd1d9a580), WTC(0xd1092160), WTC(0xd03cacdc),
+ WTC(0xcf7383ba), WTC(0xceacfd46), WTC(0xcdea429a), WTC(0xcd2bf5ec),
+ WTC(0xcc709dc1), WTC(0xcbb6dc91), WTC(0xcafdff71), WTC(0xca4504cd),
+ WTC(0xc98a93f4), WTC(0xc8cf0eb0), WTC(0xc813ee7f), WTC(0xc75665f3),
+ WTC(0xc6912d63), WTC(0xc5bff74a), WTC(0xc4dee9fa), WTC(0xc3ea39ef),
+ WTC(0xc2de1c94), WTC(0xc1b6bd08), WTC(0xc07074da), WTC(0xbf081038),
+ WTC(0xbd7b166b), WTC(0xbbc8afd7), WTC(0xba01d47c), WTC(0xb84b481f),
+ WTC(0xb6b65953), WTC(0xb542e5d2), WTC(0xb3f04291), WTC(0xb2bdc25a),
+ WTC(0xb1aab810), WTC(0xb0b676a0), WTC(0xafe050d5), WTC(0xaf27997d),
+ WTC(0xae8ba390), WTC(0xae0bc202), WTC(0xada7479d), WTC(0xad5d872f),
+ WTC(0xad2dd392), WTC(0xad177f97), WTC(0xad19de04), WTC(0xad3441c5),
+ WTC(0xad65fddc), WTC(0xadae6514), WTC(0xae0cca18), WTC(0xae807fde),
+ WTC(0xaf08d967), WTC(0xafa5296f), WTC(0xb054c2ac), WTC(0xb116f81b),
+ WTC(0xb1eb1cb1), WTC(0xb2d082fe), WTC(0xb3c677e5), WTC(0xb4cc6e9c),
+ WTC(0xb5e17eb4), WTC(0xb7052956), WTC(0xb836b427), WTC(0xb97571f3),
+ WTC(0xbac0b594), WTC(0xbc17d1ee), WTC(0xbd7a19eb), WTC(0xbee6e071),
+ WTC(0xc05d7837), WTC(0xc1dd33fe), WTC(0xc36566c2), WTC(0xc4f56377),
+ WTC(0xc68c7ce5), WTC(0xc82a05db), WTC(0xc9cd5148), WTC(0xcb75b207),
+ WTC(0xcd227ad9), WTC(0xced2fe95), WTC(0xd0869026), WTC(0xd23c8268),
+ WTC(0xd3f42834), WTC(0xd5acd460), WTC(0xd765d9c5), WTC(0xd91e8b42),
+ WTC(0xdad63bb5), WTC(0xdc8c3df2), WTC(0xde3fe4d1), WTC(0xdff08333),
+ WTC(0xe19d6bf6), WTC(0xe345f1ee), WTC(0xe4e967f3), WTC(0xe68720e7),
+ WTC(0xe81e6fa3), WTC(0xe9aea6fb), WTC(0xeb3719cb), WTC(0xecb71af3),
+ WTC(0xee2dfd4b), WTC(0xef9b13ab), WTC(0xf0fdb0ee), WTC(0xf25527f1),
+ WTC(0xf3a0cb8e), WTC(0xf4dfee9f), WTC(0xf611e3ff), WTC(0xf735fe8b),
+ WTC(0xf84b911a), WTC(0xf951ee85), WTC(0xfa4869a5), WTC(0xfb2e5557),
+ WTC(0xfc030477), WTC(0xfcc5c9e0), WTC(0xfd75f86b), WTC(0xfe12e2f2),
+ WTC(0xfe9bdc51), WTC(0xff103761), WTC(0xff6f46fc), WTC(0xffb85dfe),
+ WTC(0xffeacf42), WTC(0x0005ee03), WTC(0x0009162b), WTC(0xfff368d1),
+};
+
+const FIXP_WTB LowDelaySynthesis160[480] = {
+ WTC(0xdb171130), WTC(0xdbfadfbd), WTC(0xdce2192a), WTC(0xddcccbc8),
+ WTC(0xdebaeb0c), WTC(0xdfac6ebd), WTC(0xe0a17875), WTC(0xe199e10c),
+ WTC(0xe29531fd), WTC(0xe3933ef6), WTC(0xe49487be), WTC(0xe598bcf5),
+ WTC(0xe69f38b0), WTC(0xe7a73d45), WTC(0xe8b02e94), WTC(0xe9b9dc97),
+ WTC(0xeac4e62c), WTC(0xebd111fc), WTC(0xecdd0242), WTC(0xede7178d),
+ WTC(0xeeee9c24), WTC(0xeff34dba), WTC(0xf0f4eaf5), WTC(0xf1f36695),
+ WTC(0xf2eeb2b2), WTC(0xf3e663cb), WTC(0xf4d9cbfe), WTC(0xf5c76b3c),
+ WTC(0xf6ada4cb), WTC(0xf78bc92d), WTC(0xf862dc57), WTC(0xf93589ca),
+ WTC(0xfa059b44), WTC(0xfad501fc), WTC(0xfba49819), WTC(0xfc740f58),
+ WTC(0xfd465b6d), WTC(0xfe1ee06f), WTC(0xfef2581b), WTC(0xff9ec7d9),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff143f6), WTC(0xbfd3cd5c), WTC(0xbfb64d54), WTC(0xbf98ce80),
+ WTC(0xbf7b5291), WTC(0xbf5dd523), WTC(0xbf405f8e), WTC(0xbf22ee55),
+ WTC(0xbf058664), WTC(0xbee82d22), WTC(0xbecae0a1), WTC(0xbeadacb5),
+ WTC(0xbe908f68), WTC(0xbe73901d), WTC(0xbe56b673), WTC(0xbe3a013e),
+ WTC(0xbe1d7dad), WTC(0xbe012b19), WTC(0xbde51134), WTC(0xbdc93781),
+ WTC(0xbdad9c88), WTC(0xbd924bd8), WTC(0xbd774311), WTC(0xbd5c882b),
+ WTC(0xbd4220fa), WTC(0xbd280a49), WTC(0xbd0e4d50), WTC(0xbcf4e46e),
+ WTC(0xbcdbd1a4), WTC(0xbcc31624), WTC(0xbcaaaa02), WTC(0xbc929348),
+ WTC(0xbc7acc12), WTC(0xbc63525e), WTC(0xbc4c26b1), WTC(0xbc353ea9),
+ WTC(0xbc1e91e2), WTC(0xbc085aea), WTC(0xbbf1c04a), WTC(0xbbdc7521),
+ WTC(0xbbce4740), WTC(0xbbca5187), WTC(0xbbcd3a7c), WTC(0xbbd33634),
+ WTC(0xbbdc0a34), WTC(0xbbea218a), WTC(0xbbfe25b7), WTC(0xbc162887),
+ WTC(0xbc3076c5), WTC(0xbc4d09f6), WTC(0xbc6d925c), WTC(0xbc94da6e),
+ WTC(0xbcc48300), WTC(0xbcfc9763), WTC(0xbd3bd94f), WTC(0xbd808d05),
+ WTC(0xbdc9a11b), WTC(0xbe16e339), WTC(0xbe691db9), WTC(0xbec179c1),
+ WTC(0xbf210140), WTC(0xbf88cd62), WTC(0xbff8e8d3), WTC(0xc06e1aaa),
+ WTC(0xc0e45951), WTC(0xc15b3820), WTC(0xc1d6e2ff), WTC(0xc2590e0a),
+ WTC(0xc2e10f83), WTC(0xc36c5c9a), WTC(0xc3f735f3), WTC(0xc47fb2d1),
+ WTC(0xc50abce5), WTC(0xc59a0a25), WTC(0xc629f21c), WTC(0xc6b6ef89),
+ WTC(0xc7427180), WTC(0xc7cd1fc4), WTC(0xc856485f), WTC(0xc8dcae93),
+ WTC(0xb487a986), WTC(0xb2ce0812), WTC(0xb11bc4c2), WTC(0xaf70d5cb),
+ WTC(0xadcd228e), WTC(0xac3086a2), WTC(0xaa9af36b), WTC(0xa90c5935),
+ WTC(0xa784b214), WTC(0xa60407e9), WTC(0xa48a7076), WTC(0xa31806f9),
+ WTC(0xa1aceb03), WTC(0xa0494f63), WTC(0x9eed6840), WTC(0x9d996570),
+ WTC(0x9c4d93b4), WTC(0x9b0a3114), WTC(0x99cf798d), WTC(0x989db16a),
+ WTC(0x97752146), WTC(0x965609f1), WTC(0x95409b05), WTC(0x9434fda9),
+ WTC(0x9333587b), WTC(0x923bc7d6), WTC(0x914e5299), WTC(0x906af345),
+ WTC(0x8f9185e6), WTC(0x8ec1cbe9), WTC(0x8dfb64c9), WTC(0x8d3dab18),
+ WTC(0x8c87de34), WTC(0x8bd8c494), WTC(0x8b2ecacc), WTC(0x8a882a5f),
+ WTC(0x89e2ecd1), WTC(0x893f12b2), WTC(0x88a3c878), WTC(0x882141c7),
+ WTC(0x87c65dcd), WTC(0x87a0c07b), WTC(0x8778b859), WTC(0x87514698),
+ WTC(0x8728e900), WTC(0x87000679), WTC(0x86d68f05), WTC(0x86ac6ee7),
+ WTC(0x8681a5ce), WTC(0x86562ed0), WTC(0x8629fdeb), WTC(0x85fd1ca8),
+ WTC(0x85cf7b32), WTC(0x85a11a2f), WTC(0x8571fbbe), WTC(0x854213f5),
+ WTC(0x8511722b), WTC(0x84e00ee3), WTC(0x84adf346), WTC(0x847b28e5),
+ WTC(0x8447a9d0), WTC(0x84138a20), WTC(0x83dec5b6), WTC(0x83a9694f),
+ WTC(0x83738231), WTC(0x833d0def), WTC(0x8306247b), WTC(0x82cec29b),
+ WTC(0x8296f5f3), WTC(0x825ecbe4), WTC(0x82263fe8), WTC(0x81ed682f),
+ WTC(0x81b4406d), WTC(0x817ad2a1), WTC(0x814127f4), WTC(0x8107392d),
+ WTC(0x80cd184d), WTC(0x8092bc5f), WTC(0x80582866), WTC(0x801d714f),
+ WTC(0x0aa4f846), WTC(0x0b3686fe), WTC(0x0bce899e), WTC(0x0c6b8a7e),
+ WTC(0x0d0d036f), WTC(0x0db358b8), WTC(0x0e5e31dd), WTC(0x0f0e4270),
+ WTC(0x0fc347c1), WTC(0x107c35cc), WTC(0x11383a63), WTC(0x11f68759),
+ WTC(0x12b7b1e3), WTC(0x13799d61), WTC(0x14383db4), WTC(0x14f032c0),
+ WTC(0x159e6920), WTC(0x163fb449), WTC(0x16d14820), WTC(0x17512c3f),
+ WTC(0x17c5f622), WTC(0x18483f2a), WTC(0x18df3074), WTC(0x1989f589),
+ WTC(0x1a4783af), WTC(0x1b16f152), WTC(0x1bf7795a), WTC(0x1ce7c950),
+ WTC(0x1de817ec), WTC(0x1efa3f4a), WTC(0x201ff37a), WTC(0x2157d4e1),
+ WTC(0x22995036), WTC(0x23e0d882), WTC(0x25345db2), WTC(0x269a10c3),
+ WTC(0x280a0798), WTC(0x297d6cf9), WTC(0x2afa7e1b), WTC(0x2c8d210a),
+ WTC(0x2e377db2), WTC(0x2feb60cc), WTC(0x31977111), WTC(0x333b1637),
+ WTC(0x34ea14df), WTC(0x36ba32d4), WTC(0x38a524c8), WTC(0x3a8fa891),
+ WTC(0x3c640cb3), WTC(0x3e22ab11), WTC(0x3fde7cc9), WTC(0x41a80486),
+ WTC(0x438394e4), WTC(0x456c8d8f), WTC(0x4758f4da), WTC(0x493d7a7b),
+ WTC(0x4b139f32), WTC(0x4cdbb199), WTC(0x4e9ab8d1), WTC(0x50569530),
+ WTC(0x5213a89e), WTC(0x53d5462c), WTC(0x559a5aa7), WTC(0x5756acf5),
+ WTC(0x58fcfb38), WTC(0x5a8e3e07), WTC(0x5c1a20e8), WTC(0x5da6c7da),
+ WTC(0x5f3231f3), WTC(0x60b51fb6), WTC(0x62260848), WTC(0x6381f5a9),
+ WTC(0x64d79ac7), WTC(0x662c51c0), WTC(0x67779c07), WTC(0x68b22184),
+ WTC(0x69e0ca28), WTC(0x6b068bcf), WTC(0x6c23008e), WTC(0x6d346856),
+ WTC(0xaec92693), WTC(0xb22ca2bd), WTC(0xb578d421), WTC(0xb8b27edb),
+ WTC(0xbbdc38b5), WTC(0xbef598bb), WTC(0xc1fe0dcd), WTC(0xc4f4d7ff),
+ WTC(0xc7d98479), WTC(0xcaabc289), WTC(0xcd6b38f6), WTC(0xd017edff),
+ WTC(0xd2b1aa37), WTC(0xd538739f), WTC(0xd7ac554d), WTC(0xda0d2f5e),
+ WTC(0xdc5b3f69), WTC(0xde966e30), WTC(0xe0bee2c8), WTC(0xe2d4c9cd),
+ WTC(0xe4d82000), WTC(0xe6c94926), WTC(0xe8a84b14), WTC(0xea755ac3),
+ WTC(0xec309bdc), WTC(0xedd9f2a8), WTC(0xef71c040), WTC(0xf0f842ad),
+ WTC(0xf26e53cb), WTC(0xf3d4cd9f), WTC(0xf52b9ddf), WTC(0xf671db4d),
+ WTC(0xf7a58faa), WTC(0xf8c79907), WTC(0xf9da7c73), WTC(0xfadee240),
+ WTC(0xfbd360e6), WTC(0xfcb95db4), WTC(0xfd913bb1), WTC(0xfe594e2e),
+ WTC(0xff10e67c), WTC(0xffbc2326), WTC(0x00608350), WTC(0x00fc8a2d),
+ WTC(0x01873313), WTC(0x01f8e4fe), WTC(0x02579318), WTC(0x02b03ec3),
+ WTC(0x030ab2da), WTC(0x0363ea2a), WTC(0x03b1e60d), WTC(0x03ee2920),
+ WTC(0x0418405c), WTC(0x04348449), WTC(0x0448d9f7), WTC(0x0459c65f),
+ WTC(0x04694a29), WTC(0x0475b506), WTC(0x047bebeb), WTC(0x0478dcd2),
+ WTC(0x046aa475), WTC(0x045249a9), WTC(0x043332f0), WTC(0x0411bb77),
+ WTC(0x03ef893b), WTC(0x03c9ebb8), WTC(0x039da778), WTC(0x036a1273),
+ WTC(0x03316a60), WTC(0x02f6553a), WTC(0x02b98be9), WTC(0x027a2e2c),
+ WTC(0x0236df64), WTC(0x01f036bf), WTC(0x01a78b41), WTC(0x015d29da),
+ WTC(0x01114624), WTC(0x00c406e9), WTC(0x0075ddb1), WTC(0x00277692),
+ WTC(0xd5e139e9), WTC(0xd494362e), WTC(0xd34e2bff), WTC(0xd20e56f8),
+ WTC(0xd0d5a3dc), WTC(0xcfa5904f), WTC(0xce7be3cb), WTC(0xcd5b3086),
+ WTC(0xcc420f0f), WTC(0xcb2c2bf6), WTC(0xca1695c3), WTC(0xc8fdf020),
+ WTC(0xc7e4fc07), WTC(0xc6c374c6), WTC(0xc5895653), WTC(0xc4297218),
+ WTC(0xc296f958), WTC(0xc0c51a3c), WTC(0xbea84ee5), WTC(0xbc38842f),
+ WTC(0xb9915966), WTC(0xb7186ae5), WTC(0xb4eb3040), WTC(0xb3076897),
+ WTC(0xb16acba3), WTC(0xb013112a), WTC(0xaefdf0a2), WTC(0xae2921f5),
+ WTC(0xad925cd6), WTC(0xad3758be), WTC(0xad15cd3d), WTC(0xad2b71ca),
+ WTC(0xad75fe65), WTC(0xadf32a84), WTC(0xaea0ada9), WTC(0xaf7c3fcd),
+ WTC(0xb0839825), WTC(0xb1b46e9c), WTC(0xb30c7a20), WTC(0xb48970be),
+ WTC(0xb62912e0), WTC(0xb7e90de7), WTC(0xb9c71d12), WTC(0xbbc0f7fd),
+ WTC(0xbdd45674), WTC(0xbffef022), WTC(0xc23e7c49), WTC(0xc490b2d4),
+ WTC(0xc6f34b70), WTC(0xc963fda9), WTC(0xcbe0813e), WTC(0xce668d98),
+ WTC(0xd0f3da69), WTC(0xd3861f64), WTC(0xd61b141f), WTC(0xd8b07038),
+ WTC(0xdb43eb5d), WTC(0xddd33d22), WTC(0xe05c1d2e), WTC(0xe2dc432c),
+ WTC(0xe55166ad), WTC(0xe7b93f62), WTC(0xea1184df), WTC(0xec57eec9),
+ WTC(0xee8a34c6), WTC(0xf0a60e70), WTC(0xf2a9336e), WTC(0xf4915b60),
+ WTC(0xf65c3dea), WTC(0xf80792ae), WTC(0xf9911147), WTC(0xfaf67154),
+ WTC(0xfc356a7e), WTC(0xfd4bb465), WTC(0xfe3706a9), WTC(0xfef518ec),
+ WTC(0xff83a2cf), WTC(0xffe05bed), WTC(0x0008fd26), WTC(0xfffb4037),
+};
+
+const FIXP_WTB LowDelaySynthesis128[384] = {
+ WTC(0xdb335c78), WTC(0xdc512d40), WTC(0xdd746116), WTC(0xde9cf7ae),
+ WTC(0xdfcadda8), WTC(0xe0fe4196), WTC(0xe236a409), WTC(0xe373518f),
+ WTC(0xe4b4e870), WTC(0xe5faf25e), WTC(0xe744190a), WTC(0xe88f06f4),
+ WTC(0xe9db2796), WTC(0xeb29613f), WTC(0xec78b08e), WTC(0xedc5f65d),
+ WTC(0xef0f5af4), WTC(0xf05447dd), WTC(0xf1945392), WTC(0xf2cf795a),
+ WTC(0xf405123d), WTC(0xf533af3d), WTC(0xf65842dd), WTC(0xf77071ae),
+ WTC(0xf87d623f), WTC(0xf983c711), WTC(0xfa8730ce), WTC(0xfb8aad4b),
+ WTC(0xfc8e1dc6), WTC(0xfd96d19a), WTC(0xfea5325a), WTC(0xff8d21da),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbfed9606), WTC(0xbfc8bddf), WTC(0xbfa3dd57), WTC(0xbf7f023c),
+ WTC(0xbf5a25e8), WTC(0xbf3554df), WTC(0xbf108b6b), WTC(0xbeebd7bd),
+ WTC(0xbec738a6), WTC(0xbea2bf45), WTC(0xbe7e6b42), WTC(0xbe5a4fd5),
+ WTC(0xbe366de8), WTC(0xbe12d91e), WTC(0xbdef9338), WTC(0xbdccaf6e),
+ WTC(0xbdaa2e3f), WTC(0xbd88205e), WTC(0xbd668430), WTC(0xbd456994),
+ WTC(0xbd24cdad), WTC(0xbd04bc91), WTC(0xbce52def), WTC(0xbcc62942),
+ WTC(0xbca7a273), WTC(0xbc899fba), WTC(0xbc6c16ab), WTC(0xbc4f0812),
+ WTC(0xbc326537), WTC(0xbc162fb3), WTC(0xbbfa5915), WTC(0xbbded462),
+ WTC(0xbbcd3956), WTC(0xbbcae0f5), WTC(0xbbd0beb7), WTC(0xbbdaaf42),
+ WTC(0xbbec5289), WTC(0xbc06d115), WTC(0xbc266162), WTC(0xbc494d27),
+ WTC(0xbc721013), WTC(0xbca5b2d9), WTC(0xbce6a063), WTC(0xbd339d3d),
+ WTC(0xbd8975b2), WTC(0xbde618b1), WTC(0xbe499de1), WTC(0xbeb60feb),
+ WTC(0xbf2d830e), WTC(0xbfb1ee2e), WTC(0xc041e22f), WTC(0xc0d59618),
+ WTC(0xc16a574d), WTC(0xc206ed94), WTC(0xc2ad7ad1), WTC(0xc35ae733),
+ WTC(0xc4085fbf), WTC(0xc4b33a35), WTC(0xc563f6ce), WTC(0xc6181ab7),
+ WTC(0xc6c86beb), WTC(0xc7768de4), WTC(0xc8231ab3), WTC(0xc8cc145a),
+ WTC(0xb4500dde), WTC(0xb22a524e), WTC(0xb010144c), WTC(0xae013530),
+ WTC(0xabfd7206), WTC(0xaa04a92f), WTC(0xa816c008), WTC(0xa633baab),
+ WTC(0xa45bbe2b), WTC(0xa28eff5e), WTC(0xa0cdc4c6), WTC(0x9f187801),
+ WTC(0x9d6f7708), WTC(0x9bd34eb0), WTC(0x9a44763a), WTC(0x98c36ace),
+ WTC(0x9750b896), WTC(0x95ecdc61), WTC(0x94982f8c), WTC(0x9353005a),
+ WTC(0x921d8bac), WTC(0x90f7e126), WTC(0x8fe1e828), WTC(0x8edb3ddc),
+ WTC(0x8de337c8), WTC(0x8cf89cdb), WTC(0x8c19be6d), WTC(0x8b43d072),
+ WTC(0x8a737663), WTC(0x89a52f4d), WTC(0x88dc38e8), WTC(0x882f6f3f),
+ WTC(0x87c22c55), WTC(0x87918a21), WTC(0x87602c61), WTC(0x872dfd0a),
+ WTC(0x86fae063), WTC(0x86c6d729), WTC(0x8691c4ad), WTC(0x865ba7e8),
+ WTC(0x86246b66), WTC(0x85ec17ab), WTC(0x85b293e2), WTC(0x8577eaac),
+ WTC(0x853c09be), WTC(0x84ff042d), WTC(0x84c0d195), WTC(0x84818c4c),
+ WTC(0x84412e63), WTC(0x83ffd42c), WTC(0x83bd7bdf), WTC(0x837a471b),
+ WTC(0x833636dc), WTC(0x82f16e48), WTC(0x82abed37), WTC(0x8265d6c4),
+ WTC(0x821f28cf), WTC(0x81d80322), WTC(0x8190625c), WTC(0x81486134),
+ WTC(0x80fff7a0), WTC(0x80b73d86), WTC(0x806e2527), WTC(0x8024c969),
+ WTC(0x0ab6c2d2), WTC(0x0b6edac2), WTC(0x0c302988), WTC(0x0cf88fab),
+ WTC(0x0dc87461), WTC(0x0e9f9122), WTC(0x0f7ee53f), WTC(0x1064e7bf),
+ WTC(0x114fe4b7), WTC(0x123e9e4c), WTC(0x13311589), WTC(0x1420b664),
+ WTC(0x15069245), WTC(0x15dc93ad), WTC(0x169caf41), WTC(0x17422e16),
+ WTC(0x17d51de4), WTC(0x187e7622), WTC(0x1947aa0b), WTC(0x1a2ed3b4),
+ WTC(0x1b321858), WTC(0x1c4fcc7f), WTC(0x1d8601a3), WTC(0x1ed6ec5e),
+ WTC(0x20460b07), WTC(0x21cfbf59), WTC(0x23652732), WTC(0x2508e4b1),
+ WTC(0x26c7b0a6), WTC(0x289505da), WTC(0x2a698dd8), WTC(0x2c5954d2),
+ WTC(0x2e6dd135), WTC(0x308d838f), WTC(0x329de377), WTC(0x34b28f13),
+ WTC(0x36f67988), WTC(0x395ec1e5), WTC(0x3bb7b587), WTC(0x3deb63cc),
+ WTC(0x4016b320), WTC(0x42584eb2), WTC(0x44b424ca), WTC(0x471ba5b2),
+ WTC(0x49791954), WTC(0x4bc02004), WTC(0x4df3b8c0), WTC(0x501f1e1e),
+ WTC(0x524b93e2), WTC(0x547f0eef), WTC(0x56b23d03), WTC(0x58c99052),
+ WTC(0x5abfc042), WTC(0x5caebf1a), WTC(0x5e9e618b), WTC(0x608595d7),
+ WTC(0x62528e67), WTC(0x6401eb53), WTC(0x65ad0eb1), WTC(0x674f1cd2),
+ WTC(0x68d8804e), WTC(0x6a4ff10e), WTC(0x6bb987a5), WTC(0x6d12e937),
+ WTC(0xaf370652), WTC(0xb36badcf), WTC(0xb77ec321), WTC(0xbb77e364),
+ WTC(0xbf57979e), WTC(0xc31cb589), WTC(0xc6c5e686), WTC(0xca52811d),
+ WTC(0xcdc1d66b), WTC(0xd113d0f0), WTC(0xd4481c98), WTC(0xd75ee41b),
+ WTC(0xda57f7bf), WTC(0xdd33a926), WTC(0xdff1e272), WTC(0xe2931227),
+ WTC(0xe5174232), WTC(0xe77f0b15), WTC(0xe9ca889d), WTC(0xebfa2f7c),
+ WTC(0xee0de002), WTC(0xf0063326), WTC(0xf1e3e5f1), WTC(0xf3a8d749),
+ WTC(0xf5555599), WTC(0xf6e77eb2), WTC(0xf85cb5d6), WTC(0xf9b8e64d),
+ WTC(0xfafe52ad), WTC(0xfc2b37b8), WTC(0xfd420467), WTC(0xfe41412c),
+ WTC(0xff26ded5), WTC(0xfffa6150), WTC(0x00c374a4), WTC(0x01773884),
+ WTC(0x02058de3), WTC(0x0278d689), WTC(0x02e87372), WTC(0x03593268),
+ WTC(0x03ba79ab), WTC(0x03fff32b), WTC(0x042b2341), WTC(0x044690de),
+ WTC(0x045bc96a), WTC(0x046e77e9), WTC(0x047a85c1), WTC(0x0479d8c4),
+ WTC(0x04681aec), WTC(0x0447318f), WTC(0x041e4d13), WTC(0x03f3edad),
+ WTC(0x03c4cc17), WTC(0x038b1f6f), WTC(0x03470909), WTC(0x02fdcebd),
+ WTC(0x02b1cb18), WTC(0x0261730d), WTC(0x020afad0), WTC(0x01b0b9c8),
+ WTC(0x0153c1a0), WTC(0x00f47426), WTC(0x00933db7), WTC(0x003140e9),
+ WTC(0xd5b730bf), WTC(0xd4192c32), WTC(0xd2859479), WTC(0xd0fc3b9d),
+ WTC(0xcf800352), WTC(0xce0e6ab3), WTC(0xccaaf25f), WTC(0xcb4ed003),
+ WTC(0xc9f3ae44), WTC(0xc8948a56), WTC(0xc73226fd), WTC(0xc5b2676a),
+ WTC(0xc3fa2a82), WTC(0xc1f05f70), WTC(0xbf7c884b), WTC(0xbc8b1e86),
+ WTC(0xb93e1633), WTC(0xb63eb483), WTC(0xb3b45d14), WTC(0xb19a8ee2),
+ WTC(0xafecd4aa), WTC(0xaea6b8e7), WTC(0xadc3c6bf), WTC(0xad3f88ac),
+ WTC(0xad158929), WTC(0xad4152b1), WTC(0xadbe7068), WTC(0xae886c76),
+ WTC(0xaf9ad1fe), WTC(0xb0f12b26), WTC(0xb2870347), WTC(0xb457d633),
+ WTC(0xb65f592c), WTC(0xb898eca0), WTC(0xbb00291b), WTC(0xbd90996b),
+ WTC(0xc045c861), WTC(0xc31b4022), WTC(0xc60c8bd5), WTC(0xc91535f2),
+ WTC(0xcc30c94c), WTC(0xcf5ad039), WTC(0xd28ed58a), WTC(0xd5c863e5),
+ WTC(0xd90305e6), WTC(0xdc3a4644), WTC(0xdf69af93), WTC(0xe28ccc93),
+ WTC(0xe59f27d7), WTC(0xe89c4c15), WTC(0xeb7fc3e3), WTC(0xee4519f7),
+ WTC(0xf0e7d8ed), WTC(0xf3638b73), WTC(0xf5b3bc30), WTC(0xf7d3f5d0),
+ WTC(0xf9bfc2f0), WTC(0xfb72ae35), WTC(0xfce84251), WTC(0xfe1c09e5),
+ WTC(0xff098f9a), WTC(0xffac5e15), WTC(0xffffffb2), WTC(0x0000159b),
+};
+
+const FIXP_WTB LowDelaySynthesis120[360] = {
+ WTC(0xdb3ccdcd), WTC(0xdc6e0d69), WTC(0xdda570a7), WTC(0xdee2ef33),
+ WTC(0xe02680f4), WTC(0xe1704397), WTC(0xe2bf5626), WTC(0xe4137c80),
+ WTC(0xe56d30cd), WTC(0xe6cb22fe), WTC(0xe82b9f14), WTC(0xe98d8220),
+ WTC(0xeaf18a17), WTC(0xec57328f), WTC(0xedbae901), WTC(0xef1a42b9),
+ WTC(0xf07481f7), WTC(0xf1c932d4), WTC(0xf3183e19), WTC(0xf460b35f),
+ WTC(0xf5a04ac7), WTC(0xf6d33845), WTC(0xf7f80ec0), WTC(0xf912a5cd),
+ WTC(0xfa282a2e), WTC(0xfb3cd81c), WTC(0xfc51629b), WTC(0xfd69f81f),
+ WTC(0xfe8abdeb), WTC(0xff86f173), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbfec5bfa), WTC(0xbfc50dd8), WTC(0xbf9db88b), WTC(0xbf76683c),
+ WTC(0xbf4f1944), WTC(0xbf27d649), WTC(0xbf00a158), WTC(0xbed9848c),
+ WTC(0xbeb288f1), WTC(0xbe8bb79f), WTC(0xbe651f00), WTC(0xbe3ec6f8),
+ WTC(0xbe18c1f6), WTC(0xbdf315fe), WTC(0xbdcdd79d), WTC(0xbda909c1),
+ WTC(0xbd84beae), WTC(0xbd60f6ab), WTC(0xbd3dc210), WTC(0xbd1b2093),
+ WTC(0xbcf91ae9), WTC(0xbcd7acab), WTC(0xbcb6d5cc), WTC(0xbc969143),
+ WTC(0xbc76dcf4), WTC(0xbc57b317), WTC(0xbc390c4d), WTC(0xbc1ad514),
+ WTC(0xbbfd2fdb), WTC(0xbbdfa548), WTC(0xbbcce946), WTC(0xbbcb39d9),
+ WTC(0xbbd214cf), WTC(0xbbddfb60), WTC(0xbbf3783e), WTC(0xbc11f8d2),
+ WTC(0xbc3509f8), WTC(0xbc5ca2b0), WTC(0xbc8dc0b0), WTC(0xbccd4b2f),
+ WTC(0xbd1b7107), WTC(0xbd74c6a4), WTC(0xbdd635c0), WTC(0xbe3f4cd7),
+ WTC(0xbeb24836), WTC(0xbf31b5df), WTC(0xbfbfe6e2), WTC(0xc05a6dbf),
+ WTC(0xc0f80700), WTC(0xc198449c), WTC(0xc242ea15), WTC(0xc2f8270d),
+ WTC(0xc3b20bd2), WTC(0xc468f554), WTC(0xc522637e), WTC(0xc5e2403b),
+ WTC(0xc69f9771), WTC(0xc7599dd5), WTC(0xc811f85a), WTC(0xc8c687db),
+ WTC(0xb43d8b3b), WTC(0xb1f3fb3c), WTC(0xafb77be9), WTC(0xad87e063),
+ WTC(0xab64dcd5), WTC(0xa94e4cc2), WTC(0xa74418f8), WTC(0xa5465837),
+ WTC(0xa3554252), WTC(0xa1711f59), WTC(0x9f9a62f5), WTC(0x9dd18104),
+ WTC(0x9c17167e), WTC(0x9a6bbbe9), WTC(0x98d0061c), WTC(0x97449e23),
+ WTC(0x95ca1ad6), WTC(0x9460e7a1), WTC(0x93096222), WTC(0x91c3c9da),
+ WTC(0x90902633), WTC(0x8f6e3c5f), WTC(0x8e5d7788), WTC(0x8d5cb789),
+ WTC(0x8c6a42d5), WTC(0x8b833d6f), WTC(0x8aa3cc10), WTC(0x89c7789a),
+ WTC(0x88ef9802), WTC(0x883452c3), WTC(0x87c0bb9a), WTC(0x878c8326),
+ WTC(0x8757eb4c), WTC(0x87222119), WTC(0x86eb5f31), WTC(0x86b3802c),
+ WTC(0x867a73ee), WTC(0x86402cf8), WTC(0x8604a439), WTC(0x85c7cd22),
+ WTC(0x8589a40b), WTC(0x854a1d2f), WTC(0x850944c1), WTC(0x84c71670),
+ WTC(0x8483acc8), WTC(0x843f04b6), WTC(0x83f93cd9), WTC(0x83b2576c),
+ WTC(0x836a7812), WTC(0x8321a764), WTC(0x82d805e8), WTC(0x828da076),
+ WTC(0x824290c3), WTC(0x81f6e6a8), WTC(0x81aab23c), WTC(0x815e05f8),
+ WTC(0x8110e4d6), WTC(0x80c362df), WTC(0x8075781d), WTC(0x80273c0c),
+ WTC(0x0abcb7ed), WTC(0x0b81d183), WTC(0x0c5113e3), WTC(0x0d2867d5),
+ WTC(0x0e082fa5), WTC(0x0ef089ad), WTC(0x0fe1d9cd), WTC(0x10d9e5f4),
+ WTC(0x11d6a2a0), WTC(0x12d814b1), WTC(0x13d98f52), WTC(0x14d221e1),
+ WTC(0x15ba467a), WTC(0x168a9c18), WTC(0x173d1fef), WTC(0x17da3bff),
+ WTC(0x18912cac), WTC(0x196c2a5e), WTC(0x1a68dd2e), WTC(0x1b85250c),
+ WTC(0x1cbea9a1), WTC(0x1e147be7), WTC(0x1f8aa446), WTC(0x2122e73a),
+ WTC(0x22cf6de3), WTC(0x248867f3), WTC(0x265d7937), WTC(0x2847c91b),
+ WTC(0x2a39d98e), WTC(0x2c482abf), WTC(0x2e7ff439), WTC(0x30c31f46),
+ WTC(0x32f5245d), WTC(0x3535070e), WTC(0x37adae38), WTC(0x3a3f151a),
+ WTC(0x3caf861b), WTC(0x3effc08b), WTC(0x415a803b), WTC(0x43d45ca9),
+ WTC(0x46631c69), WTC(0x48ed9c7e), WTC(0x4b608807), WTC(0x4dbbead3),
+ WTC(0x500ca1df), WTC(0x525e3c5d), WTC(0x54b7c199), WTC(0x570df9a2),
+ WTC(0x5940f661), WTC(0x5b542f13), WTC(0x5d64a202), WTC(0x5f738e39),
+ WTC(0x61704027), WTC(0x6348ef5e), WTC(0x65109c5f), WTC(0x66d3e29d),
+ WTC(0x687eb29a), WTC(0x6a125643), WTC(0x6b960b3a), WTC(0x6d07b283),
+ WTC(0xaf5b8daa), WTC(0xb3d557ba), WTC(0xb829feb2), WTC(0xbc6199e7),
+ WTC(0xc07bfbc1), WTC(0xc477a1b6), WTC(0xc8532f30), WTC(0xcc0dd698),
+ WTC(0xcfa71f06), WTC(0xd31ec578), WTC(0xd674c5b9), WTC(0xd9a90516),
+ WTC(0xdcbbc2b6), WTC(0xdfacf934), WTC(0xe27d19ab), WTC(0xe52c3d89),
+ WTC(0xe7bb0f52), WTC(0xea29bdd0), WTC(0xec78bc4a), WTC(0xeea805e6),
+ WTC(0xf0b85a68), WTC(0xf2ab266e), WTC(0xf48234a7), WTC(0xf63cb733),
+ WTC(0xf7d70b3f), WTC(0xf952d4d3), WTC(0xfab4906d), WTC(0xfbfaa858),
+ WTC(0xfd272437), WTC(0xfe392bea), WTC(0xff2e26f1), WTC(0x000efac0),
+ WTC(0x00e36d26), WTC(0x019bd803), WTC(0x0229e357), WTC(0x02a16b25),
+ WTC(0x0319ee5e), WTC(0x038ccea0), WTC(0x03e56d3d), WTC(0x041dc072),
+ WTC(0x043f58cc), WTC(0x04571273), WTC(0x046ba761), WTC(0x0479caa5),
+ WTC(0x047a2279), WTC(0x04673950), WTC(0x04435263), WTC(0x041750da),
+ WTC(0x03e99926), WTC(0x03b4ba1f), WTC(0x03731e2b), WTC(0x0327b303),
+ WTC(0x02d8301b), WTC(0x0284fb11), WTC(0x022b464a), WTC(0x01cc1b40),
+ WTC(0x0169ab7d), WTC(0x01047d1e), WTC(0x009d04e0), WTC(0x003484b0),
+ WTC(0xd5a9348a), WTC(0xd3f05eca), WTC(0xd24339e7), WTC(0xd0a269b7),
+ WTC(0xcf0fe026), WTC(0xcd8aa14b), WTC(0xcc13963e), WTC(0xcaa19c5a),
+ WTC(0xc92cd701), WTC(0xc7b5cd7b), WTC(0xc62a4fe3), WTC(0xc46742be),
+ WTC(0xc24e128c), WTC(0xbfc0b758), WTC(0xbca661e3), WTC(0xb922924b),
+ WTC(0xb5f87ac2), WTC(0xb35308e7), WTC(0xb12cc90f), WTC(0xaf80522c),
+ WTC(0xae483b10), WTC(0xad7f1af9), WTC(0xad1f8874), WTC(0xad241a09),
+ WTC(0xad8766ea), WTC(0xae4405b1), WTC(0xaf548d72), WTC(0xb0b394ad),
+ WTC(0xb25bb297), WTC(0xb4476fa1), WTC(0xb6718d2c), WTC(0xb8d47781),
+ WTC(0xbb6ad37b), WTC(0xbe2f3831), WTC(0xc11c3c6c), WTC(0xc42c76b1),
+ WTC(0xc75a7e40), WTC(0xcaa0e9d1), WTC(0xcdfa502b), WTC(0xd1614803),
+ WTC(0xd4d06850), WTC(0xd84247d3), WTC(0xdbb17d6d), WTC(0xdf189fe3),
+ WTC(0xe272461e), WTC(0xe5b906e1), WTC(0xe8e7790e), WTC(0xebf83366),
+ WTC(0xeee5cccc), WTC(0xf1aadc0a), WTC(0xf441f7fa), WTC(0xf6a5b772),
+ WTC(0xf8d0b146), WTC(0xfabd7c3e), WTC(0xfc66af35), WTC(0xfdc6e101),
+ WTC(0xfed8a875), WTC(0xff969c63), WTC(0xfffb5390), WTC(0x00017ad8),
+};
+
+const FIXP_WTB LowDelaySynthesis512[1536] = {
+ /* part 0 */
+ WTC(0xdac984c0), WTC(0xdb100080), WTC(0xdb56cd00), WTC(0xdb9dec40),
+ WTC(0xdbe55fc0), WTC(0xdc2d2880), WTC(0xdc754780), WTC(0xdcbdbd80),
+ WTC(0xdd068a80), WTC(0xdd4fae80), WTC(0xdd992940), WTC(0xdde2f9c0),
+ WTC(0xde2d1fc0), WTC(0xde779a80), WTC(0xdec26a00), WTC(0xdf0d8e00),
+ WTC(0xdf590680), WTC(0xdfa4d540), WTC(0xdff0fc80), WTC(0xe03d7e20),
+ WTC(0xe08a5900), WTC(0xe0d78a20), WTC(0xe1250cc0), WTC(0xe172dcc0),
+ WTC(0xe1c0f7a0), WTC(0xe20f59a0), WTC(0xe25dfea0), WTC(0xe2ace400),
+ WTC(0xe2fc0be0), WTC(0xe34b7bc0), WTC(0xe39b3c80), WTC(0xe3eb5260),
+ WTC(0xe43bbac0), WTC(0xe48c7160), WTC(0xe4dd7140), WTC(0xe52eb600),
+ WTC(0xe5803c00), WTC(0xe5d1fda0), WTC(0xe623f360), WTC(0xe6761700),
+ WTC(0xe6c86400), WTC(0xe71ad500), WTC(0xe76d63e0), WTC(0xe7c00ba0),
+ WTC(0xe812c8e0), WTC(0xe86598e0), WTC(0xe8b878e0), WTC(0xe90b68a0),
+ WTC(0xe95e6c40), WTC(0xe9b18ae0), WTC(0xea04ce80), WTC(0xea583ba0),
+ WTC(0xeaabcda0), WTC(0xeaff7ee0), WTC(0xeb5348e0), WTC(0xeba722c0),
+ WTC(0xebfb0060), WTC(0xec4ed240), WTC(0xeca28540), WTC(0xecf60c20),
+ WTC(0xed496120), WTC(0xed9c7e80), WTC(0xedef5e40), WTC(0xee41fc00),
+ WTC(0xee945600), WTC(0xeee66ac0), WTC(0xef3839a0), WTC(0xef89c0e0),
+ WTC(0xefdafda0), WTC(0xf02bed60), WTC(0xf07c8e80), WTC(0xf0cce000),
+ WTC(0xf11ce220), WTC(0xf16c9620), WTC(0xf1bbfe30), WTC(0xf20b19e0),
+ WTC(0xf259e5a0), WTC(0xf2a85dc0), WTC(0xf2f67ed0), WTC(0xf34445b0),
+ WTC(0xf391aed0), WTC(0xf3deb590), WTC(0xf42b53e0), WTC(0xf4778140),
+ WTC(0xf4c33190), WTC(0xf50e5660), WTC(0xf558df30), WTC(0xf5a2be50),
+ WTC(0xf5ebea10), WTC(0xf6345780), WTC(0xf67bfab0), WTC(0xf6c2cee0),
+ WTC(0xf708d7b0), WTC(0xf74e19c0), WTC(0xf7929a70), WTC(0xf7d66630),
+ WTC(0xf8199268), WTC(0xf85c3860), WTC(0xf89e7480), WTC(0xf8e058c0),
+ WTC(0xf921ec08), WTC(0xf9633800), WTC(0xf9a44980), WTC(0xf9e53158),
+ WTC(0xfa260158), WTC(0xfa66ca18), WTC(0xfaa79ac0), WTC(0xfae87920),
+ WTC(0xfb295fa0), WTC(0xfb6a42b8), WTC(0xfbab1240), WTC(0xfbebd1c0),
+ WTC(0xfc2c9c24), WTC(0xfc6d8d90), WTC(0xfcaec240), WTC(0xfcf05684),
+ WTC(0xfd326a98), WTC(0xfd75254c), WTC(0xfdb8afd4), WTC(0xfdfccdfc),
+ WTC(0xfe40d694), WTC(0xfe84161c), WTC(0xfec5cf5a), WTC(0xff04e7fc),
+ WTC(0xff3fdfe3), WTC(0xff751ddf), WTC(0xffa2fb0f), WTC(0xffc87c42),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbffb6081), WTC(0xbff22f81), WTC(0xbfe8fc01), WTC(0xbfdfc781),
+ WTC(0xbfd69101), WTC(0xbfcd5a01), WTC(0xbfc42201), WTC(0xbfbae981),
+ WTC(0xbfb1b101), WTC(0xbfa87901), WTC(0xbf9f4181), WTC(0xbf960b01),
+ WTC(0xbf8cd481), WTC(0xbf839d81), WTC(0xbf7a6681), WTC(0xbf712f01),
+ WTC(0xbf67f801), WTC(0xbf5ec101), WTC(0xbf558b01), WTC(0xbf4c5681),
+ WTC(0xbf432281), WTC(0xbf39ee81), WTC(0xbf30bb01), WTC(0xbf278801),
+ WTC(0xbf1e5501), WTC(0xbf152381), WTC(0xbf0bf381), WTC(0xbf02c581),
+ WTC(0xbef99901), WTC(0xbef06d01), WTC(0xbee74281), WTC(0xbede1901),
+ WTC(0xbed4f081), WTC(0xbecbca81), WTC(0xbec2a781), WTC(0xbeb98681),
+ WTC(0xbeb06881), WTC(0xbea74c81), WTC(0xbe9e3281), WTC(0xbe951a81),
+ WTC(0xbe8c0501), WTC(0xbe82f301), WTC(0xbe79e481), WTC(0xbe70da01),
+ WTC(0xbe67d381), WTC(0xbe5ed081), WTC(0xbe55d001), WTC(0xbe4cd381),
+ WTC(0xbe43da81), WTC(0xbe3ae601), WTC(0xbe31f701), WTC(0xbe290d01),
+ WTC(0xbe202801), WTC(0xbe174781), WTC(0xbe0e6c01), WTC(0xbe059481),
+ WTC(0xbdfcc301), WTC(0xbdf3f701), WTC(0xbdeb3101), WTC(0xbde27201),
+ WTC(0xbdd9b981), WTC(0xbdd10681), WTC(0xbdc85981), WTC(0xbdbfb281),
+ WTC(0xbdb71201), WTC(0xbdae7881), WTC(0xbda5e601), WTC(0xbd9d5b81),
+ WTC(0xbd94d801), WTC(0xbd8c5c01), WTC(0xbd83e681), WTC(0xbd7b7781),
+ WTC(0xbd731081), WTC(0xbd6ab101), WTC(0xbd625981), WTC(0xbd5a0b01),
+ WTC(0xbd51c481), WTC(0xbd498601), WTC(0xbd414f01), WTC(0xbd391f81),
+ WTC(0xbd30f881), WTC(0xbd28d981), WTC(0xbd20c401), WTC(0xbd18b781),
+ WTC(0xbd10b381), WTC(0xbd08b781), WTC(0xbd00c381), WTC(0xbcf8d781),
+ WTC(0xbcf0f381), WTC(0xbce91801), WTC(0xbce14601), WTC(0xbcd97c81),
+ WTC(0xbcd1bb81), WTC(0xbcca0301), WTC(0xbcc25181), WTC(0xbcbaa801),
+ WTC(0xbcb30601), WTC(0xbcab6c01), WTC(0xbca3db01), WTC(0xbc9c5281),
+ WTC(0xbc94d201), WTC(0xbc8d5901), WTC(0xbc85e801), WTC(0xbc7e7e01),
+ WTC(0xbc771c01), WTC(0xbc6fc101), WTC(0xbc686e01), WTC(0xbc612301),
+ WTC(0xbc59df81), WTC(0xbc52a381), WTC(0xbc4b6e81), WTC(0xbc444081),
+ WTC(0xbc3d1801), WTC(0xbc35f501), WTC(0xbc2ed681), WTC(0xbc27bd81),
+ WTC(0xbc20ae01), WTC(0xbc19ab01), WTC(0xbc12b801), WTC(0xbc0bcf81),
+ WTC(0xbc04e381), WTC(0xbbfde481), WTC(0xbbf6c601), WTC(0xbbef9b81),
+ WTC(0xbbe89901), WTC(0xbbe1f401), WTC(0xbbdbe201), WTC(0xbbd68c81),
+ WTC(0xbbd21281), WTC(0xbbce9181), WTC(0xbbcc2681), WTC(0xbbcaca01),
+ WTC(0xbbca5081), WTC(0xbbca8d01), WTC(0xbbcb5301), WTC(0xbbcc8201),
+ WTC(0xbbce0601), WTC(0xbbcfca81), WTC(0xbbd1bd81), WTC(0xbbd3e101),
+ WTC(0xbbd64d01), WTC(0xbbd91b81), WTC(0xbbdc6481), WTC(0xbbe03801),
+ WTC(0xbbe49d01), WTC(0xbbe99981), WTC(0xbbef3301), WTC(0xbbf56181),
+ WTC(0xbbfc0f81), WTC(0xbc032601), WTC(0xbc0a8f01), WTC(0xbc123b81),
+ WTC(0xbc1a2401), WTC(0xbc224181), WTC(0xbc2a8c81), WTC(0xbc330781),
+ WTC(0xbc3bbc01), WTC(0xbc44b481), WTC(0xbc4dfb81), WTC(0xbc57a301),
+ WTC(0xbc61c401), WTC(0xbc6c7781), WTC(0xbc77d601), WTC(0xbc83f201),
+ WTC(0xbc90d481), WTC(0xbc9e8801), WTC(0xbcad1501), WTC(0xbcbc7e01),
+ WTC(0xbcccbd01), WTC(0xbcddcc81), WTC(0xbcefa601), WTC(0xbd023f01),
+ WTC(0xbd158801), WTC(0xbd297181), WTC(0xbd3deb81), WTC(0xbd52eb01),
+ WTC(0xbd686681), WTC(0xbd7e5581), WTC(0xbd94b001), WTC(0xbdab7181),
+ WTC(0xbdc29a81), WTC(0xbdda2a01), WTC(0xbdf22181), WTC(0xbe0a8581),
+ WTC(0xbe236001), WTC(0xbe3cbc01), WTC(0xbe56a381), WTC(0xbe712001),
+ WTC(0xbe8c3781), WTC(0xbea7f301), WTC(0xbec45881), WTC(0xbee17201),
+ WTC(0xbeff4801), WTC(0xbf1de601), WTC(0xbf3d5501), WTC(0xbf5d9a81),
+ WTC(0xbf7eb581), WTC(0xbfa0a581), WTC(0xbfc36a01), WTC(0xbfe6ed01),
+ WTC(0xc00b04c0), WTC(0xc02f86c0), WTC(0xc0544940), WTC(0xc0792ec0),
+ WTC(0xc09e2640), WTC(0xc0c31f00), WTC(0xc0e80a00), WTC(0xc10cf480),
+ WTC(0xc1320940), WTC(0xc15773c0), WTC(0xc17d5f00), WTC(0xc1a3e340),
+ WTC(0xc1cb05c0), WTC(0xc1f2cbc0), WTC(0xc21b3940), WTC(0xc2444b00),
+ WTC(0xc26df5c0), WTC(0xc2982d80), WTC(0xc2c2e640), WTC(0xc2ee0a00),
+ WTC(0xc3197940), WTC(0xc34513c0), WTC(0xc370b9c0), WTC(0xc39c4f00),
+ WTC(0xc3c7bc00), WTC(0xc3f2e940), WTC(0xc41dc140), WTC(0xc44856c0),
+ WTC(0xc472e640), WTC(0xc49dad80), WTC(0xc4c8e880), WTC(0xc4f4acc0),
+ WTC(0xc520e840), WTC(0xc54d8780), WTC(0xc57a76c0), WTC(0xc5a79640),
+ WTC(0xc5d4bac0), WTC(0xc601b880), WTC(0xc62e6580), WTC(0xc65ab600),
+ WTC(0xc686bd40), WTC(0xc6b28fc0), WTC(0xc6de41c0), WTC(0xc709de40),
+ WTC(0xc7356640), WTC(0xc760da80), WTC(0xc78c3c40), WTC(0xc7b78640),
+ WTC(0xc7e2afc0), WTC(0xc80dae80), WTC(0xc83878c0), WTC(0xc86304c0),
+ WTC(0xc88d4900), WTC(0xc8b73b80), WTC(0xc8e0d280), WTC(0xc90a0440),
+ /* part 1 */
+ WTC(0xb5212e81), WTC(0xb4959501), WTC(0xb40ab501), WTC(0xb3808d81),
+ WTC(0xb2f71f01), WTC(0xb26e6881), WTC(0xb1e66a01), WTC(0xb15f2381),
+ WTC(0xb0d89401), WTC(0xb052bc01), WTC(0xafcd9a81), WTC(0xaf492f01),
+ WTC(0xaec57801), WTC(0xae427481), WTC(0xadc02281), WTC(0xad3e8101),
+ WTC(0xacbd9081), WTC(0xac3d5001), WTC(0xabbdc001), WTC(0xab3edf01),
+ WTC(0xaac0ad01), WTC(0xaa432981), WTC(0xa9c65401), WTC(0xa94a2c01),
+ WTC(0xa8ceb201), WTC(0xa853e501), WTC(0xa7d9c681), WTC(0xa7605601),
+ WTC(0xa6e79401), WTC(0xa66f8201), WTC(0xa5f81f81), WTC(0xa5816e81),
+ WTC(0xa50b6e81), WTC(0xa4962181), WTC(0xa4218801), WTC(0xa3ada281),
+ WTC(0xa33a7201), WTC(0xa2c7f801), WTC(0xa2563501), WTC(0xa1e52a81),
+ WTC(0xa174da81), WTC(0xa1054701), WTC(0xa0967201), WTC(0xa0285d81),
+ WTC(0x9fbb0981), WTC(0x9f4e7801), WTC(0x9ee2a901), WTC(0x9e779f81),
+ WTC(0x9e0d5e01), WTC(0x9da3e601), WTC(0x9d3b3b81), WTC(0x9cd35f81),
+ WTC(0x9c6c5481), WTC(0x9c061b81), WTC(0x9ba0b701), WTC(0x9b3c2801),
+ WTC(0x9ad87081), WTC(0x9a759301), WTC(0x9a139101), WTC(0x99b26c81),
+ WTC(0x99522801), WTC(0x98f2c601), WTC(0x98944901), WTC(0x9836b201),
+ WTC(0x97da0481), WTC(0x977e4181), WTC(0x97236b01), WTC(0x96c98381),
+ WTC(0x96708b81), WTC(0x96188501), WTC(0x95c17081), WTC(0x956b4f81),
+ WTC(0x95162381), WTC(0x94c1ee01), WTC(0x946eaf81), WTC(0x941c6901),
+ WTC(0x93cb1c81), WTC(0x937acb01), WTC(0x932b7501), WTC(0x92dd1b01),
+ WTC(0x928fbe01), WTC(0x92435d01), WTC(0x91f7f981), WTC(0x91ad9281),
+ WTC(0x91642781), WTC(0x911bb981), WTC(0x90d44781), WTC(0x908dd101),
+ WTC(0x90485401), WTC(0x9003ce81), WTC(0x8fc03f01), WTC(0x8f7da401),
+ WTC(0x8f3bfb01), WTC(0x8efb4181), WTC(0x8ebb7581), WTC(0x8e7c9301),
+ WTC(0x8e3e9481), WTC(0x8e017581), WTC(0x8dc53001), WTC(0x8d89be81),
+ WTC(0x8d4f1b01), WTC(0x8d154081), WTC(0x8cdc2901), WTC(0x8ca3cb01),
+ WTC(0x8c6c1b01), WTC(0x8c350d01), WTC(0x8bfe9401), WTC(0x8bc8a401),
+ WTC(0x8b933001), WTC(0x8b5e2c81), WTC(0x8b298b81), WTC(0x8af53e81),
+ WTC(0x8ac13381), WTC(0x8a8d5801), WTC(0x8a599a81), WTC(0x8a25f301),
+ WTC(0x89f26101), WTC(0x89bee581), WTC(0x898b8301), WTC(0x89586901),
+ WTC(0x8925f101), WTC(0x88f47901), WTC(0x88c45e81), WTC(0x88962981),
+ WTC(0x886a8a81), WTC(0x88423301), WTC(0x881dd301), WTC(0x87fdd781),
+ WTC(0x87d0ca81), WTC(0x87c76201), WTC(0x87bcab81), WTC(0x87b0ef01),
+ WTC(0x87a48b01), WTC(0x8797dd81), WTC(0x878b4301), WTC(0x877ede01),
+ WTC(0x87729701), WTC(0x87665481), WTC(0x8759fd01), WTC(0x874d8681),
+ WTC(0x8740f681), WTC(0x87345381), WTC(0x8727a381), WTC(0x871ae981),
+ WTC(0x870e2301), WTC(0x87014f81), WTC(0x86f46d81), WTC(0x86e77b81),
+ WTC(0x86da7901), WTC(0x86cd6681), WTC(0x86c04381), WTC(0x86b30f01),
+ WTC(0x86a5ca81), WTC(0x86987581), WTC(0x868b1001), WTC(0x867d9a81),
+ WTC(0x86701381), WTC(0x86627b01), WTC(0x8654d001), WTC(0x86471281),
+ WTC(0x86394301), WTC(0x862b6201), WTC(0x861d7081), WTC(0x860f6e01),
+ WTC(0x86015981), WTC(0x85f33281), WTC(0x85e4f801), WTC(0x85d6a981),
+ WTC(0x85c84801), WTC(0x85b9d481), WTC(0x85ab4f01), WTC(0x859cb781),
+ WTC(0x858e0e01), WTC(0x857f5101), WTC(0x85707f81), WTC(0x85619a01),
+ WTC(0x8552a181), WTC(0x85439601), WTC(0x85347901), WTC(0x85254a81),
+ WTC(0x85160981), WTC(0x8506b581), WTC(0x84f74e01), WTC(0x84e7d381),
+ WTC(0x84d84601), WTC(0x84c8a701), WTC(0x84b8f801), WTC(0x84a93801),
+ WTC(0x84996701), WTC(0x84898481), WTC(0x84798f81), WTC(0x84698881),
+ WTC(0x84597081), WTC(0x84494881), WTC(0x84391081), WTC(0x8428ca01),
+ WTC(0x84187401), WTC(0x84080d81), WTC(0x83f79681), WTC(0x83e70f01),
+ WTC(0x83d67881), WTC(0x83c5d381), WTC(0x83b52101), WTC(0x83a46181),
+ WTC(0x83939501), WTC(0x8382ba01), WTC(0x8371d081), WTC(0x8360d901),
+ WTC(0x834fd481), WTC(0x833ec381), WTC(0x832da781), WTC(0x831c8101),
+ WTC(0x830b4f81), WTC(0x82fa1181), WTC(0x82e8c801), WTC(0x82d77201),
+ WTC(0x82c61101), WTC(0x82b4a601), WTC(0x82a33281), WTC(0x8291b601),
+ WTC(0x82803101), WTC(0x826ea201), WTC(0x825d0901), WTC(0x824b6601),
+ WTC(0x8239b981), WTC(0x82280581), WTC(0x82164a81), WTC(0x82048881),
+ WTC(0x81f2bf81), WTC(0x81e0ee81), WTC(0x81cf1581), WTC(0x81bd3401),
+ WTC(0x81ab4b01), WTC(0x81995c01), WTC(0x81876781), WTC(0x81756d81),
+ WTC(0x81636d81), WTC(0x81516701), WTC(0x813f5981), WTC(0x812d4481),
+ WTC(0x811b2981), WTC(0x81090981), WTC(0x80f6e481), WTC(0x80e4bb81),
+ WTC(0x80d28d81), WTC(0x80c05a01), WTC(0x80ae1f81), WTC(0x809bdf01),
+ WTC(0x80899881), WTC(0x80774c81), WTC(0x8064fc81), WTC(0x8052a881),
+ WTC(0x80405101), WTC(0x802df701), WTC(0x801b9b01), WTC(0x80093e01),
+ WTC(0x0a74b120), WTC(0x0aa08a90), WTC(0x0acd2b80), WTC(0x0afa8860),
+ WTC(0x0b289590), WTC(0x0b574790), WTC(0x0b8692d0), WTC(0x0bb66bb0),
+ WTC(0x0be6c6b0), WTC(0x0c179830), WTC(0x0c48d500), WTC(0x0c7a7ad0),
+ WTC(0x0cac9000), WTC(0x0cdf1b60), WTC(0x0d122390), WTC(0x0d45a8f0),
+ WTC(0x0d79a5e0), WTC(0x0dae1480), WTC(0x0de2ef30), WTC(0x0e183800),
+ WTC(0x0e4df8c0), WTC(0x0e843b90), WTC(0x0ebb0a20), WTC(0x0ef26430),
+ WTC(0x0f2a3fc0), WTC(0x0f629280), WTC(0x0f9b5210), WTC(0x0fd47690),
+ WTC(0x100dfa80), WTC(0x1047d8a0), WTC(0x10820b40), WTC(0x10bc8b80),
+ WTC(0x10f75080), WTC(0x11325100), WTC(0x116d84e0), WTC(0x11a8ece0),
+ WTC(0x11e49420), WTC(0x122085a0), WTC(0x125ccbc0), WTC(0x12995a40),
+ WTC(0x12d60e80), WTC(0x1312c4c0), WTC(0x134f59e0), WTC(0x138bae60),
+ WTC(0x13c7a740), WTC(0x140329e0), WTC(0x143e1b60), WTC(0x147862a0),
+ WTC(0x14b1e840), WTC(0x14ea94c0), WTC(0x152250a0), WTC(0x15590380),
+ WTC(0x158e93e0), WTC(0x15c2e820), WTC(0x15f5e6e0), WTC(0x162779a0),
+ WTC(0x16578ca0), WTC(0x16860ca0), WTC(0x16b2e640), WTC(0x16de0b00),
+ WTC(0x17077140), WTC(0x172f0fa0), WTC(0x1754e200), WTC(0x17796080),
+ WTC(0x179d7f20), WTC(0x17c23760), WTC(0x17e87da0), WTC(0x1810cc80),
+ WTC(0x183b25a0), WTC(0x18678520), WTC(0x1895e700), WTC(0x18c64540),
+ WTC(0x18f89780), WTC(0x192cd560), WTC(0x1962f680), WTC(0x199af2a0),
+ WTC(0x19d4c1e0), WTC(0x1a105ca0), WTC(0x1a4dbae0), WTC(0x1a8cd660),
+ WTC(0x1acdaa60), WTC(0x1b103260), WTC(0x1b546940), WTC(0x1b9a4600),
+ WTC(0x1be1bb80), WTC(0x1c2abc60), WTC(0x1c753b80), WTC(0x1cc13860),
+ WTC(0x1d0ebe20), WTC(0x1d5dd8c0), WTC(0x1dae9480), WTC(0x1e010060),
+ WTC(0x1e552f40), WTC(0x1eab33e0), WTC(0x1f032060), WTC(0x1f5cfce0),
+ WTC(0x1fb8c660), WTC(0x201679c0), WTC(0x207611c0), WTC(0x20d75f00),
+ WTC(0x213a0640), WTC(0x219dab80), WTC(0x2201f480), WTC(0x2266ba80),
+ WTC(0x22cc0ac0), WTC(0x2331f4c0), WTC(0x23988940), WTC(0x23ffff40),
+ WTC(0x2468b340), WTC(0x24d30300), WTC(0x253f4900), WTC(0x25ad8980),
+ WTC(0x261d72c0), WTC(0x268eaec0), WTC(0x2700e880), WTC(0x2773db40),
+ WTC(0x27e751c0), WTC(0x285b1780), WTC(0x28cefbc0), WTC(0x29431f80),
+ WTC(0x29b7f680), WTC(0x2a2df780), WTC(0x2aa59880), WTC(0x2b1f3280),
+ WTC(0x2b9b0140), WTC(0x2c194000), WTC(0x2c9a2540), WTC(0x2d1d8dc0),
+ WTC(0x2da2fc40), WTC(0x2e29ee80), WTC(0x2eb1e340), WTC(0x2f3a4e40),
+ WTC(0x2fc29980), WTC(0x304a2ec0), WTC(0x30d07cc0), WTC(0x315566c0),
+ WTC(0x31d94480), WTC(0x325c72c0), WTC(0x32df51c0), WTC(0x33628c80),
+ WTC(0x33e71a00), WTC(0x346df400), WTC(0x34f80dc0), WTC(0x3585c640),
+ WTC(0x3616e700), WTC(0x36ab3380), WTC(0x37426ac0), WTC(0x37dbe840),
+ WTC(0x3876a340), WTC(0x39118f40), WTC(0x39aba2c0), WTC(0x3a4422c0),
+ WTC(0x3adaa200), WTC(0x3b6eb6c0), WTC(0x3bfffd80), WTC(0x3c8e9380),
+ WTC(0x3d1b1780), WTC(0x3da62e00), WTC(0x3e307b00), WTC(0x3eba97c0),
+ WTC(0x3f451280), WTC(0x3fd07940), WTC(0x405d577f), WTC(0x40ebf57f),
+ WTC(0x417c59ff), WTC(0x420e897f), WTC(0x42a2857f), WTC(0x4338307f),
+ WTC(0x43cf4d7f), WTC(0x44679cff), WTC(0x4500dfff), WTC(0x459ac2ff),
+ WTC(0x4634e2ff), WTC(0x46ced9ff), WTC(0x4768437f), WTC(0x4800d27f),
+ WTC(0x489850ff), WTC(0x492e88ff), WTC(0x49c346ff), WTC(0x4a5678ff),
+ WTC(0x4ae82f7f), WTC(0x4b787c7f), WTC(0x4c07717f), WTC(0x4c95337f),
+ WTC(0x4d21f77f), WTC(0x4dadf3ff), WTC(0x4e395eff), WTC(0x4ec4657f),
+ WTC(0x4f4f297f), WTC(0x4fd9cd7f), WTC(0x5064737f), WTC(0x50ef3cff),
+ WTC(0x517a46ff), WTC(0x5205b0ff), WTC(0x529197ff), WTC(0x531e04ff),
+ WTC(0x53aaeb7f), WTC(0x54383eff), WTC(0x54c5ef7f), WTC(0x5553a8ff),
+ WTC(0x55e0d57f), WTC(0x566cda7f), WTC(0x56f720ff), WTC(0x577f4aff),
+ WTC(0x580534ff), WTC(0x5888bd7f), WTC(0x5909c6ff), WTC(0x598890ff),
+ WTC(0x5a05b7ff), WTC(0x5a81db7f), WTC(0x5afd99ff), WTC(0x5b794a7f),
+ WTC(0x5bf5007f), WTC(0x5c70cbff), WTC(0x5cecbb7f), WTC(0x5d68c47f),
+ WTC(0x5de4c3ff), WTC(0x5e6094ff), WTC(0x5edc127f), WTC(0x5f56fdff),
+ WTC(0x5fd1017f), WTC(0x6049c67f), WTC(0x60c0f67f), WTC(0x613650ff),
+ WTC(0x61a9a9ff), WTC(0x621ad77f), WTC(0x6289b37f), WTC(0x62f67fff),
+ WTC(0x6361e87f), WTC(0x63cc9bff), WTC(0x6437457f), WTC(0x64a2247f),
+ WTC(0x650d0c7f), WTC(0x6577cc7f), WTC(0x65e2327f), WTC(0x664bf57f),
+ WTC(0x66b4b5ff), WTC(0x671c137f), WTC(0x6781afff), WTC(0x67e579ff),
+ WTC(0x6847abff), WTC(0x68a882ff), WTC(0x69083bff), WTC(0x6966fbff),
+ WTC(0x69c4cfff), WTC(0x6a21c57f), WTC(0x6a7de87f), WTC(0x6ad9377f),
+ WTC(0x6b33a5ff), WTC(0x6b8d257f), WTC(0x6be5a8ff), WTC(0x6c3d20ff),
+ WTC(0x6c9380ff), WTC(0x6ce8ba7f), WTC(0x6d3cbfff), WTC(0x6d8f827f),
+ /* part 2 */
+ WTC(0xad98b481), WTC(0xaead9d01), WTC(0xafbfc381), WTC(0xb0cf4d01),
+ WTC(0xb1dc5f81), WTC(0xb2e72081), WTC(0xb3efb501), WTC(0xb4f64381),
+ WTC(0xb5faf101), WTC(0xb6fde401), WTC(0xb7ff4001), WTC(0xb8ff1601),
+ WTC(0xb9fd6181), WTC(0xbafa1d01), WTC(0xbbf54401), WTC(0xbceed101),
+ WTC(0xbde6c081), WTC(0xbedd0e81), WTC(0xbfd1b701), WTC(0xc0c4b440),
+ WTC(0xc1b5ffc0), WTC(0xc2a59340), WTC(0xc3936780), WTC(0xc47f78c0),
+ WTC(0xc569c600), WTC(0xc6524d40), WTC(0xc7390dc0), WTC(0xc81e04c0),
+ WTC(0xc9012e00), WTC(0xc9e28540), WTC(0xcac20700), WTC(0xcb9fb1c0),
+ WTC(0xcc7b8640), WTC(0xcd558600), WTC(0xce2db200), WTC(0xcf0409c0),
+ WTC(0xcfd88a40), WTC(0xd0ab3080), WTC(0xd17bfa00), WTC(0xd24ae640),
+ WTC(0xd317f7c0), WTC(0xd3e33080), WTC(0xd4ac9340), WTC(0xd5741f40),
+ WTC(0xd639d2c0), WTC(0xd6fdab00), WTC(0xd7bfa5c0), WTC(0xd87fc300),
+ WTC(0xd93e0600), WTC(0xd9fa7180), WTC(0xdab50900), WTC(0xdb6dccc0),
+ WTC(0xdc24ba80), WTC(0xdcd9d000), WTC(0xdd8d0b80), WTC(0xde3e6dc0),
+ WTC(0xdeedf9c0), WTC(0xdf9bb340), WTC(0xe0479e20), WTC(0xe0f1bac0),
+ WTC(0xe19a07e0), WTC(0xe2408380), WTC(0xe2e52c00), WTC(0xe38802e0),
+ WTC(0xe4290c00), WTC(0xe4c84c20), WTC(0xe565c760), WTC(0xe6017f20),
+ WTC(0xe69b7240), WTC(0xe7339f60), WTC(0xe7ca0500), WTC(0xe85ea480),
+ WTC(0xe8f18180), WTC(0xe9829fc0), WTC(0xea1202e0), WTC(0xea9fab80),
+ WTC(0xeb2b9700), WTC(0xebb5c2a0), WTC(0xec3e2bc0), WTC(0xecc4d300),
+ WTC(0xed49bc80), WTC(0xedccec60), WTC(0xee4e66a0), WTC(0xeece2d80),
+ WTC(0xef4c41e0), WTC(0xefc8a480), WTC(0xf0435610), WTC(0xf0bc5c60),
+ WTC(0xf133c230), WTC(0xf1a99270), WTC(0xf21dd7b0), WTC(0xf29097e0),
+ WTC(0xf301d3d0), WTC(0xf3718c20), WTC(0xf3dfc180), WTC(0xf44c7100),
+ WTC(0xf4b79480), WTC(0xf52125b0), WTC(0xf5891df0), WTC(0xf5ef6fe0),
+ WTC(0xf6540730), WTC(0xf6b6cf50), WTC(0xf717b490), WTC(0xf776b9a0),
+ WTC(0xf7d3f720), WTC(0xf82f86e8), WTC(0xf8898260), WTC(0xf8e1fc50),
+ WTC(0xf93900f0), WTC(0xf98e9c28), WTC(0xf9e2d940), WTC(0xfa35b4a0),
+ WTC(0xfa871bd8), WTC(0xfad6fbd0), WTC(0xfb254250), WTC(0xfb71f0c0),
+ WTC(0xfbbd1c28), WTC(0xfc06da60), WTC(0xfc4f40a4), WTC(0xfc965500),
+ WTC(0xfcdc0e5c), WTC(0xfd2062f4), WTC(0xfd6348d0), WTC(0xfda4b1b8),
+ WTC(0xfde48b2c), WTC(0xfe22c280), WTC(0xfe5f462a), WTC(0xfe9a1f2e),
+ WTC(0xfed3711c), WTC(0xff0b60ac), WTC(0xff4212dd), WTC(0xff77b344),
+ WTC(0xffac7407), WTC(0xffe08796), WTC(0x00141e37), WTC(0x00473665),
+ WTC(0x00799cd0), WTC(0x00ab1bff), WTC(0x00db7d8b), WTC(0x010a75ea),
+ WTC(0x0137a46e), WTC(0x0162a77a), WTC(0x018b20ac), WTC(0x01b0fb7a),
+ WTC(0x01d46d3c), WTC(0x01f5ae7c), WTC(0x0214f91c), WTC(0x0232a5cc),
+ WTC(0x024f2c04), WTC(0x026b048c), WTC(0x0286a628), WTC(0x02a25808),
+ WTC(0x02be31c0), WTC(0x02da48e0), WTC(0x02f6b09c), WTC(0x031345dc),
+ WTC(0x032faf50), WTC(0x034b9148), WTC(0x036690e8), WTC(0x0380658c),
+ WTC(0x0398d8e4), WTC(0x03afb568), WTC(0x03c4c6e0), WTC(0x03d7f770),
+ WTC(0x03e94f9c), WTC(0x03f8d938), WTC(0x04069ee8), WTC(0x0412bef8),
+ WTC(0x041d6b30), WTC(0x0426d638), WTC(0x042f3288), WTC(0x0436ad98),
+ WTC(0x043d6fd0), WTC(0x0443a170), WTC(0x04496a40), WTC(0x044ee728),
+ WTC(0x04542a40), WTC(0x04594520), WTC(0x045e4890), WTC(0x04633210),
+ WTC(0x0467ebe8), WTC(0x046c5f80), WTC(0x04707630), WTC(0x047417f0),
+ WTC(0x04772b58), WTC(0x047996e8), WTC(0x047b4140), WTC(0x047c12a0),
+ WTC(0x047bf520), WTC(0x047ad2e0), WTC(0x04789690), WTC(0x047539c8),
+ WTC(0x0470c4b8), WTC(0x046b4058), WTC(0x0464b600), WTC(0x045d3a08),
+ WTC(0x0454ebc8), WTC(0x044beb00), WTC(0x04425798), WTC(0x043853b0),
+ WTC(0x042e0398), WTC(0x04238bd8), WTC(0x04190f98), WTC(0x040e9670),
+ WTC(0x04040c18), WTC(0x03f95b30), WTC(0x03ee6e20), WTC(0x03e32b64),
+ WTC(0x03d77598), WTC(0x03cb2f24), WTC(0x03be3b18), WTC(0x03b08b18),
+ WTC(0x03a21f64), WTC(0x0392f8d4), WTC(0x038318e0), WTC(0x03728e94),
+ WTC(0x03617694), WTC(0x034fee18), WTC(0x033e11f4), WTC(0x032bf530),
+ WTC(0x0319a114), WTC(0x03071e80), WTC(0x02f475f4), WTC(0x02e1a7c0),
+ WTC(0x02ceac04), WTC(0x02bb7a84), WTC(0x02a80af0), WTC(0x029452b0),
+ WTC(0x028044e0), WTC(0x026bd488), WTC(0x0256f558), WTC(0x0241a940),
+ WTC(0x022c0084), WTC(0x02160c08), WTC(0x01ffdc5a), WTC(0x01e97ad2),
+ WTC(0x01d2e982), WTC(0x01bc2a2a), WTC(0x01a53e8c), WTC(0x018e2860),
+ WTC(0x0176e94c), WTC(0x015f82fa), WTC(0x0147f70e), WTC(0x013046c2),
+ WTC(0x011872e8), WTC(0x01007c4a), WTC(0x00e863cf), WTC(0x00d02c81),
+ WTC(0x00b7db94), WTC(0x009f7651), WTC(0x00870204), WTC(0x006e83f8),
+ WTC(0x00560176), WTC(0x003d7fcb), WTC(0x0025043f), WTC(0x000c941f),
+ WTC(0xd65574c0), WTC(0xd5ebc100), WTC(0xd582d080), WTC(0xd51a9cc0),
+ WTC(0xd4b31f80), WTC(0xd44c5280), WTC(0xd3e62f80), WTC(0xd380b040),
+ WTC(0xd31bce40), WTC(0xd2b78380), WTC(0xd253ca40), WTC(0xd1f0acc0),
+ WTC(0xd18e4580), WTC(0xd12caf40), WTC(0xd0cc0400), WTC(0xd06c40c0),
+ WTC(0xd00d4740), WTC(0xcfaef6c0), WTC(0xcf513140), WTC(0xcef3fa80),
+ WTC(0xce977a40), WTC(0xce3bd980), WTC(0xcde13f40), WTC(0xcd87a880),
+ WTC(0xcd2ee800), WTC(0xccd6cf00), WTC(0xcc7f2f40), WTC(0xcc27e880),
+ WTC(0xcbd0ea00), WTC(0xcb7a2380), WTC(0xcb238380), WTC(0xcaccee80),
+ WTC(0xca763ec0), WTC(0xca1f4d00), WTC(0xc9c7f480), WTC(0xc9703b40),
+ WTC(0xc9185200), WTC(0xc8c06b00), WTC(0xc868b4c0), WTC(0xc81100c0),
+ WTC(0xc7b8c280), WTC(0xc75f6a40), WTC(0xc7046900), WTC(0xc6a74340),
+ WTC(0xc6479300), WTC(0xc5e4f200), WTC(0xc57efac0), WTC(0xc5154880),
+ WTC(0xc4a77780), WTC(0xc4352440), WTC(0xc3bdeac0), WTC(0xc3416740),
+ WTC(0xc2bf33c0), WTC(0xc236eb40), WTC(0xc1a82900), WTC(0xc11290c0),
+ WTC(0xc075cf00), WTC(0xbfd19081), WTC(0xbf258401), WTC(0xbe716d81),
+ WTC(0xbdb52b81), WTC(0xbcf09a81), WTC(0xbc23af81), WTC(0xbb505c01),
+ WTC(0xba7a9081), WTC(0xb9a65281), WTC(0xb8d79301), WTC(0xb8104c01),
+ WTC(0xb7508181), WTC(0xb6982201), WTC(0xb5e71b01), WTC(0xb53d5b01),
+ WTC(0xb49ad081), WTC(0xb3ff6901), WTC(0xb36b1301), WTC(0xb2ddbd01),
+ WTC(0xb2575481), WTC(0xb1d7c801), WTC(0xb15f0601), WTC(0xb0ecfc01),
+ WTC(0xb0819881), WTC(0xb01cca01), WTC(0xafbe7e01), WTC(0xaf66a301),
+ WTC(0xaf152701), WTC(0xaec9f881), WTC(0xae850601), WTC(0xae463c81),
+ WTC(0xae0d8b01), WTC(0xaddae001), WTC(0xadae2881), WTC(0xad875381),
+ WTC(0xad664f81), WTC(0xad4b0981), WTC(0xad357081), WTC(0xad257301),
+ WTC(0xad1afe01), WTC(0xad160081), WTC(0xad166901), WTC(0xad1c2481),
+ WTC(0xad272201), WTC(0xad374f81), WTC(0xad4c9b01), WTC(0xad66f381),
+ WTC(0xad864601), WTC(0xadaa8101), WTC(0xadd39301), WTC(0xae016a01),
+ WTC(0xae33f481), WTC(0xae6b2001), WTC(0xaea6db01), WTC(0xaee71381),
+ WTC(0xaf2bb801), WTC(0xaf74b681), WTC(0xafc1fd01), WTC(0xb0137a01),
+ WTC(0xb0691b81), WTC(0xb0c2cf81), WTC(0xb1208481), WTC(0xb1822881),
+ WTC(0xb1e7a981), WTC(0xb250f601), WTC(0xb2bdfc01), WTC(0xb32eaa01),
+ WTC(0xb3a2ed01), WTC(0xb41ab481), WTC(0xb495ee01), WTC(0xb5148801),
+ WTC(0xb5967081), WTC(0xb61b9581), WTC(0xb6a3e581), WTC(0xb72f4e01),
+ WTC(0xb7bdbe01), WTC(0xb84f2381), WTC(0xb8e36c81), WTC(0xb97a8701),
+ WTC(0xba146101), WTC(0xbab0e981), WTC(0xbb500d81), WTC(0xbbf1bc81),
+ WTC(0xbc95e381), WTC(0xbd3c7181), WTC(0xbde55481), WTC(0xbe907a01),
+ WTC(0xbf3dd101), WTC(0xbfed4701), WTC(0xc09ecac0), WTC(0xc1524a00),
+ WTC(0xc207b300), WTC(0xc2bef440), WTC(0xc377fb80), WTC(0xc432b700),
+ WTC(0xc4ef1500), WTC(0xc5ad03c0), WTC(0xc66c7140), WTC(0xc72d4bc0),
+ WTC(0xc7ef8180), WTC(0xc8b30080), WTC(0xc977b700), WTC(0xca3d9340),
+ WTC(0xcb048340), WTC(0xcbcc7540), WTC(0xcc955740), WTC(0xcd5f17c0),
+ WTC(0xce29a480), WTC(0xcef4ec00), WTC(0xcfc0dc80), WTC(0xd08d63c0),
+ WTC(0xd15a7040), WTC(0xd227f000), WTC(0xd2f5d140), WTC(0xd3c40240),
+ WTC(0xd4927100), WTC(0xd5610b80), WTC(0xd62fc080), WTC(0xd6fe7dc0),
+ WTC(0xd7cd3140), WTC(0xd89bc980), WTC(0xd96a34c0), WTC(0xda3860c0),
+ WTC(0xdb063c00), WTC(0xdbd3b480), WTC(0xdca0b880), WTC(0xdd6d3640),
+ WTC(0xde391bc0), WTC(0xdf045740), WTC(0xdfced6c0), WTC(0xe09888c0),
+ WTC(0xe1615b20), WTC(0xe2293c20), WTC(0xe2f01a00), WTC(0xe3b5e2c0),
+ WTC(0xe47a84c0), WTC(0xe53dee00), WTC(0xe6000cc0), WTC(0xe6c0cf20),
+ WTC(0xe7802360), WTC(0xe83df7a0), WTC(0xe8fa39e0), WTC(0xe9b4d880),
+ WTC(0xea6dc1a0), WTC(0xeb24e360), WTC(0xebda2be0), WTC(0xec8d8960),
+ WTC(0xed3eea20), WTC(0xedee3c00), WTC(0xee9b6d80), WTC(0xef466ca0),
+ WTC(0xefef2780), WTC(0xf0958c50), WTC(0xf1398950), WTC(0xf1db0ca0),
+ WTC(0xf27a0470), WTC(0xf3165ed0), WTC(0xf3b00a10), WTC(0xf446f440),
+ WTC(0xf4db0b90), WTC(0xf56c3e30), WTC(0xf5fa7a50), WTC(0xf685ae10),
+ WTC(0xf70dc7a0), WTC(0xf792b520), WTC(0xf81464c8), WTC(0xf892c4c0),
+ WTC(0xf90dc330), WTC(0xf9854e40), WTC(0xf9f95418), WTC(0xfa69c2f0),
+ WTC(0xfad688e8), WTC(0xfb3f9428), WTC(0xfba4d2e8), WTC(0xfc063344),
+ WTC(0xfc63a370), WTC(0xfcbd1194), WTC(0xfd126bdc), WTC(0xfd63a06c),
+ WTC(0xfdb09d78), WTC(0xfdf95124), WTC(0xfe3da99e), WTC(0xfe7d950e),
+ WTC(0xfeb901a2), WTC(0xfeefdd80), WTC(0xff2216d7), WTC(0xff4f9bcf),
+ WTC(0xff785a93), WTC(0xff9c414e), WTC(0xffbb3e2b), WTC(0xffd53f54),
+ WTC(0xffea32f4), WTC(0xfffa0735), WTC(0x0004aa43), WTC(0x000a0a47),
+ WTC(0x000a156c), WTC(0x0004b9de), WTC(0xfff9e5c5), WTC(0xffe9874e)};
+
+const FIXP_WTB LowDelaySynthesis480[1440] = {
+ WTC(0xdad2e6c0), WTC(0xdb1da900), WTC(0xdb68ce40), WTC(0xdbb45840),
+ WTC(0xdc004940), WTC(0xdc4ca280), WTC(0xdc996500), WTC(0xdce69140),
+ WTC(0xdd342780), WTC(0xdd822700), WTC(0xddd08a80), WTC(0xde1f4d00),
+ WTC(0xde6e6ec0), WTC(0xdebdec40), WTC(0xdf0dba80), WTC(0xdf5dd540),
+ WTC(0xdfae3cc0), WTC(0xdfff0500), WTC(0xe0505140), WTC(0xe0a22980),
+ WTC(0xe0f488e0), WTC(0xe1476180), WTC(0xe19aa480), WTC(0xe1ee4d80),
+ WTC(0xe2425400), WTC(0xe29689a0), WTC(0xe2eacd60), WTC(0xe33f2420),
+ WTC(0xe393a300), WTC(0xe3e87f20), WTC(0xe43dcee0), WTC(0xe4938a80),
+ WTC(0xe4e9b0a0), WTC(0xe5404300), WTC(0xe5973e60), WTC(0xe5ee9b80),
+ WTC(0xe64649e0), WTC(0xe69e37e0), WTC(0xe6f65ec0), WTC(0xe74eb6c0),
+ WTC(0xe7a73000), WTC(0xe7ffbe40), WTC(0xe8585ee0), WTC(0xe8b10740),
+ WTC(0xe9099c40), WTC(0xe96214e0), WTC(0xe9ba79a0), WTC(0xea12e7c0),
+ WTC(0xea6b89c0), WTC(0xeac46580), WTC(0xeb1d7260), WTC(0xeb76b620),
+ WTC(0xebd036c0), WTC(0xec29e520), WTC(0xec83aa60), WTC(0xecdd5a00),
+ WTC(0xed36d500), WTC(0xed901540), WTC(0xede91160), WTC(0xee41bc20),
+ WTC(0xee9a0ee0), WTC(0xeef20860), WTC(0xef49a7e0), WTC(0xefa0ec00),
+ WTC(0xeff7d1c0), WTC(0xf04e56b0), WTC(0xf0a476e0), WTC(0xf0fa2f60),
+ WTC(0xf14f80e0), WTC(0xf1a46e10), WTC(0xf1f8fe80), WTC(0xf24d34a0),
+ WTC(0xf2a10bb0), WTC(0xf2f48210), WTC(0xf3479cc0), WTC(0xf39a5be0),
+ WTC(0xf3ecb8f0), WTC(0xf43eafa0), WTC(0xf4903b50), WTC(0xf4e14e80),
+ WTC(0xf531d6a0), WTC(0xf581bc10), WTC(0xf5d0e9c0), WTC(0xf61f5250),
+ WTC(0xf66ce6e0), WTC(0xf6b99330), WTC(0xf7054eb0), WTC(0xf7501f20),
+ WTC(0xf79a0750), WTC(0xf7e30700), WTC(0xf82b2fc0), WTC(0xf872a138),
+ WTC(0xf8b97f18), WTC(0xf8ffe668), WTC(0xf945e538), WTC(0xf98b8860),
+ WTC(0xf9d0f380), WTC(0xfa165148), WTC(0xfa5bb8a8), WTC(0xfaa13df8),
+ WTC(0xfae6fb00), WTC(0xfb2cf8c8), WTC(0xfb732a80), WTC(0xfbb97910),
+ WTC(0xfbffcd10), WTC(0xfc463478), WTC(0xfc8cd3fc), WTC(0xfcd3be5c),
+ WTC(0xfd1afa90), WTC(0xfd62aa84), WTC(0xfdab0288), WTC(0xfdf404b4),
+ WTC(0xfe3d3006), WTC(0xfe85b20e), WTC(0xfecca4cc), WTC(0xff10d559),
+ WTC(0xff50579b), WTC(0xff8a40d2), WTC(0xffb7d86e), WTC(0xffef6bbb),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000),
+ WTC(0xbff67a01), WTC(0xbfecaa81), WTC(0xbfe2d901), WTC(0xbfd90601),
+ WTC(0xbfcf3181), WTC(0xbfc55c81), WTC(0xbfbb8701), WTC(0xbfb1b101),
+ WTC(0xbfa7dc01), WTC(0xbf9e0701), WTC(0xbf943301), WTC(0xbf8a5f81),
+ WTC(0xbf808b81), WTC(0xbf76b701), WTC(0xbf6ce201), WTC(0xbf630d81),
+ WTC(0xbf593a01), WTC(0xbf4f6801), WTC(0xbf459681), WTC(0xbf3bc601),
+ WTC(0xbf31f501), WTC(0xbf282501), WTC(0xbf1e5501), WTC(0xbf148681),
+ WTC(0xbf0aba01), WTC(0xbf00ef81), WTC(0xbef72681), WTC(0xbeed5f01),
+ WTC(0xbee39801), WTC(0xbed9d281), WTC(0xbed00f81), WTC(0xbec64e81),
+ WTC(0xbebc9181), WTC(0xbeb2d681), WTC(0xbea91f01), WTC(0xbe9f6901),
+ WTC(0xbe95b581), WTC(0xbe8c0501), WTC(0xbe825801), WTC(0xbe78b001),
+ WTC(0xbe6f0c01), WTC(0xbe656c01), WTC(0xbe5bd001), WTC(0xbe523781),
+ WTC(0xbe48a301), WTC(0xbe3f1381), WTC(0xbe358901), WTC(0xbe2c0501),
+ WTC(0xbe228681), WTC(0xbe190d81), WTC(0xbe0f9a01), WTC(0xbe062b81),
+ WTC(0xbdfcc301), WTC(0xbdf36101), WTC(0xbdea0681), WTC(0xbde0b301),
+ WTC(0xbdd76701), WTC(0xbdce2181), WTC(0xbdc4e301), WTC(0xbdbbab01),
+ WTC(0xbdb27b01), WTC(0xbda95301), WTC(0xbda03381), WTC(0xbd971c81),
+ WTC(0xbd8e0e01), WTC(0xbd850701), WTC(0xbd7c0781), WTC(0xbd731081),
+ WTC(0xbd6a2201), WTC(0xbd613d81), WTC(0xbd586281), WTC(0xbd4f9101),
+ WTC(0xbd46c801), WTC(0xbd3e0801), WTC(0xbd355081), WTC(0xbd2ca281),
+ WTC(0xbd23ff01), WTC(0xbd1b6501), WTC(0xbd12d581), WTC(0xbd0a4f81),
+ WTC(0xbd01d281), WTC(0xbcf95e81), WTC(0xbcf0f381), WTC(0xbce89281),
+ WTC(0xbce03b81), WTC(0xbcd7ef01), WTC(0xbccfac01), WTC(0xbcc77181),
+ WTC(0xbcbf4001), WTC(0xbcb71701), WTC(0xbcaef701), WTC(0xbca6e101),
+ WTC(0xbc9ed481), WTC(0xbc96d101), WTC(0xbc8ed701), WTC(0xbc86e581),
+ WTC(0xbc7efc81), WTC(0xbc771c01), WTC(0xbc6f4401), WTC(0xbc677501),
+ WTC(0xbc5fae81), WTC(0xbc57f101), WTC(0xbc503b81), WTC(0xbc488e81),
+ WTC(0xbc40e881), WTC(0xbc394901), WTC(0xbc31af01), WTC(0xbc2a1a81),
+ WTC(0xbc228f01), WTC(0xbc1b1081), WTC(0xbc13a481), WTC(0xbc0c4581),
+ WTC(0xbc04e381), WTC(0xbbfd6c01), WTC(0xbbf5d181), WTC(0xbbee2f81),
+ WTC(0xbbe6c801), WTC(0xbbdfdb81), WTC(0xbbd9a781), WTC(0xbbd45881),
+ WTC(0xbbd01301), WTC(0xbbccfc81), WTC(0xbbcb2281), WTC(0xbbca5d01),
+ WTC(0xbbca7481), WTC(0xbbcb3201), WTC(0xbbcc6b01), WTC(0xbbce0601),
+ WTC(0xbbcfea81), WTC(0xbbd20301), WTC(0xbbd45601), WTC(0xbbd70201),
+ WTC(0xbbda2501), WTC(0xbbdddb01), WTC(0xbbe23281), WTC(0xbbe73201),
+ WTC(0xbbece281), WTC(0xbbf34281), WTC(0xbbfa3c01), WTC(0xbc01b381),
+ WTC(0xbc098d81), WTC(0xbc11b681), WTC(0xbc1a2401), WTC(0xbc22cd81),
+ WTC(0xbc2bab01), WTC(0xbc34c081), WTC(0xbc3e1981), WTC(0xbc47c281),
+ WTC(0xbc51cb01), WTC(0xbc5c4c81), WTC(0xbc676501), WTC(0xbc733401),
+ WTC(0xbc7fd301), WTC(0xbc8d5101), WTC(0xbc9bb901), WTC(0xbcab1781),
+ WTC(0xbcbb7001), WTC(0xbcccbd01), WTC(0xbcdef701), WTC(0xbcf21601),
+ WTC(0xbd060c81), WTC(0xbd1ac801), WTC(0xbd303581), WTC(0xbd464281),
+ WTC(0xbd5ce281), WTC(0xbd740b81), WTC(0xbd8bb281), WTC(0xbda3d081),
+ WTC(0xbdbc6381), WTC(0xbdd56b81), WTC(0xbdeee981), WTC(0xbe08e181),
+ WTC(0xbe236001), WTC(0xbe3e7201), WTC(0xbe5a2301), WTC(0xbe767e81),
+ WTC(0xbe938c81), WTC(0xbeb15701), WTC(0xbecfe601), WTC(0xbeef4601),
+ WTC(0xbf0f8301), WTC(0xbf30a901), WTC(0xbf52c101), WTC(0xbf75cc81),
+ WTC(0xbf99cb01), WTC(0xbfbebb81), WTC(0xbfe48981), WTC(0xc00b04c0),
+ WTC(0xc031f880), WTC(0xc0593340), WTC(0xc0809280), WTC(0xc0a802c0),
+ WTC(0xc0cf6ec0), WTC(0xc0f6cc00), WTC(0xc11e3a80), WTC(0xc145f040),
+ WTC(0xc16e22c0), WTC(0xc196fb00), WTC(0xc1c08680), WTC(0xc1eaca00),
+ WTC(0xc215cbc0), WTC(0xc2418940), WTC(0xc26df5c0), WTC(0xc29b02c0),
+ WTC(0xc2c8a140), WTC(0xc2f6b500), WTC(0xc3251740), WTC(0xc353a0c0),
+ WTC(0xc3822c00), WTC(0xc3b09940), WTC(0xc3deccc0), WTC(0xc40ca800),
+ WTC(0xc43a28c0), WTC(0xc4678a00), WTC(0xc4951780), WTC(0xc4c31d00),
+ WTC(0xc4f1bdc0), WTC(0xc520e840), WTC(0xc5508440), WTC(0xc5807900),
+ WTC(0xc5b09e80), WTC(0xc5e0bfc0), WTC(0xc610a740), WTC(0xc64029c0),
+ WTC(0xc66f49c0), WTC(0xc69e2180), WTC(0xc6ccca40), WTC(0xc6fb5700),
+ WTC(0xc729cc80), WTC(0xc7582b40), WTC(0xc7867480), WTC(0xc7b4a480),
+ WTC(0xc7e2afc0), WTC(0xc8108a80), WTC(0xc83e28c0), WTC(0xc86b7f00),
+ WTC(0xc8988100), WTC(0xc8c52340), WTC(0xc8f15980), WTC(0xc91d1840),
+ WTC(0xb4d6a381), WTC(0xb4422b81), WTC(0xb3ae8601), WTC(0xb31bb301),
+ WTC(0xb289b181), WTC(0xb1f88181), WTC(0xb1682281), WTC(0xb0d89401),
+ WTC(0xb049d601), WTC(0xafbbe801), WTC(0xaf2ec901), WTC(0xaea27681),
+ WTC(0xae16f001), WTC(0xad8c3301), WTC(0xad023f01), WTC(0xac791401),
+ WTC(0xabf0b181), WTC(0xab691681), WTC(0xaae24301), WTC(0xaa5c3601),
+ WTC(0xa9d6ef01), WTC(0xa9526d81), WTC(0xa8ceb201), WTC(0xa84bbb81),
+ WTC(0xa7c98b01), WTC(0xa7482101), WTC(0xa6c77e01), WTC(0xa647a301),
+ WTC(0xa5c89001), WTC(0xa54a4701), WTC(0xa4ccc901), WTC(0xa4501601),
+ WTC(0xa3d43001), WTC(0xa3591801), WTC(0xa2dece81), WTC(0xa2655581),
+ WTC(0xa1ecae01), WTC(0xa174da81), WTC(0xa0fddd81), WTC(0xa087b981),
+ WTC(0xa0127081), WTC(0x9f9e0301), WTC(0x9f2a7281), WTC(0x9eb7c101),
+ WTC(0x9e45f081), WTC(0x9dd50481), WTC(0x9d650081), WTC(0x9cf5e701),
+ WTC(0x9c87ba81), WTC(0x9c1a7c81), WTC(0x9bae2f81), WTC(0x9b42d581),
+ WTC(0x9ad87081), WTC(0x9a6f0381), WTC(0x9a069001), WTC(0x999f1981),
+ WTC(0x9938a281), WTC(0x98d32d81), WTC(0x986ebd81), WTC(0x980b5501),
+ WTC(0x97a8f681), WTC(0x9747a481), WTC(0x96e76101), WTC(0x96882e01),
+ WTC(0x962a0c81), WTC(0x95ccff01), WTC(0x95710601), WTC(0x95162381),
+ WTC(0x94bc5981), WTC(0x9463a881), WTC(0x940c1281), WTC(0x93b59901),
+ WTC(0x93603d01), WTC(0x930bff81), WTC(0x92b8e101), WTC(0x9266e281),
+ WTC(0x92160301), WTC(0x91c64301), WTC(0x9177a301), WTC(0x912a2201),
+ WTC(0x90ddc001), WTC(0x90927b81), WTC(0x90485401), WTC(0x8fff4601),
+ WTC(0x8fb74f81), WTC(0x8f706f01), WTC(0x8f2aa101), WTC(0x8ee5e301),
+ WTC(0x8ea23201), WTC(0x8e5f8881), WTC(0x8e1de001), WTC(0x8ddd3201),
+ WTC(0x8d9d7781), WTC(0x8d5eaa01), WTC(0x8d20c301), WTC(0x8ce3ba81),
+ WTC(0x8ca78781), WTC(0x8c6c1b01), WTC(0x8c316681), WTC(0x8bf75b01),
+ WTC(0x8bbde981), WTC(0x8b850281), WTC(0x8b4c9701), WTC(0x8b149701),
+ WTC(0x8adcee01), WTC(0x8aa58681), WTC(0x8a6e4a01), WTC(0x8a372881),
+ WTC(0x8a001f01), WTC(0x89c92f81), WTC(0x89925a81), WTC(0x895bcd01),
+ WTC(0x8925f101), WTC(0x88f13801), WTC(0x88be1681), WTC(0x888d3181),
+ WTC(0x885f8481), WTC(0x88353501), WTC(0x88124281), WTC(0x87e73d81),
+ WTC(0x87d4ac81), WTC(0x87cb5101), WTC(0x87c05e81), WTC(0x87b42481),
+ WTC(0x87a70e81), WTC(0x87998f01), WTC(0x878c1881), WTC(0x877ede01),
+ WTC(0x8771c601), WTC(0x8764b101), WTC(0x87578181), WTC(0x874a2f01),
+ WTC(0x873cc201), WTC(0x872f4201), WTC(0x8721b481), WTC(0x87141b01),
+ WTC(0x87067281), WTC(0x86f8ba81), WTC(0x86eaf081), WTC(0x86dd1481),
+ WTC(0x86cf2601), WTC(0x86c12401), WTC(0x86b30f01), WTC(0x86a4e781),
+ WTC(0x8696ad01), WTC(0x86886001), WTC(0x867a0081), WTC(0x866b8d81),
+ WTC(0x865d0581), WTC(0x864e6901), WTC(0x863fb701), WTC(0x8630f181),
+ WTC(0x86221801), WTC(0x86132c01), WTC(0x86042c01), WTC(0x85f51681),
+ WTC(0x85e5eb81), WTC(0x85d6a981), WTC(0x85c75201), WTC(0x85b7e601),
+ WTC(0x85a86581), WTC(0x8598d081), WTC(0x85892681), WTC(0x85796601),
+ WTC(0x85698e81), WTC(0x8559a081), WTC(0x85499d01), WTC(0x85398481),
+ WTC(0x85295881), WTC(0x85191801), WTC(0x8508c181), WTC(0x84f85581),
+ WTC(0x84e7d381), WTC(0x84d73c01), WTC(0x84c69101), WTC(0x84b5d301),
+ WTC(0x84a50201), WTC(0x84941d81), WTC(0x84832481), WTC(0x84721701),
+ WTC(0x8460f581), WTC(0x844fc081), WTC(0x843e7a81), WTC(0x842d2281),
+ WTC(0x841bb981), WTC(0x840a3e81), WTC(0x83f8b001), WTC(0x83e70f01),
+ WTC(0x83d55d01), WTC(0x83c39a81), WTC(0x83b1c881), WTC(0x839fe801),
+ WTC(0x838df801), WTC(0x837bf801), WTC(0x8369e781), WTC(0x8357c701),
+ WTC(0x83459881), WTC(0x83335c81), WTC(0x83211501), WTC(0x830ec081),
+ WTC(0x82fc5f01), WTC(0x82e9ef01), WTC(0x82d77201), WTC(0x82c4e801),
+ WTC(0x82b25301), WTC(0x829fb401), WTC(0x828d0b01), WTC(0x827a5801),
+ WTC(0x82679901), WTC(0x8254cf01), WTC(0x8241fa01), WTC(0x822f1b01),
+ WTC(0x821c3401), WTC(0x82094581), WTC(0x81f64f01), WTC(0x81e34f81),
+ WTC(0x81d04681), WTC(0x81bd3401), WTC(0x81aa1981), WTC(0x8196f781),
+ WTC(0x8183cf81), WTC(0x8170a181), WTC(0x815d6c01), WTC(0x814a2f81),
+ WTC(0x8136ea01), WTC(0x81239d81), WTC(0x81104a01), WTC(0x80fcf181),
+ WTC(0x80e99401), WTC(0x80d63101), WTC(0x80c2c781), WTC(0x80af5701),
+ WTC(0x809bdf01), WTC(0x80886081), WTC(0x8074dc01), WTC(0x80615281),
+ WTC(0x804dc481), WTC(0x803a3381), WTC(0x80269f81), WTC(0x80130981),
+ WTC(0x0a608220), WTC(0x0a8ee7d0), WTC(0x0abe35c0), WTC(0x0aee5de0),
+ WTC(0x0b1f5230), WTC(0x0b5104a0), WTC(0x0b836720), WTC(0x0bb66bb0),
+ WTC(0x0bea0440), WTC(0x0c1e22c0), WTC(0x0c52ba70), WTC(0x0c87ca90),
+ WTC(0x0cbd5ba0), WTC(0x0cf375e0), WTC(0x0d2a1f50), WTC(0x0d615480),
+ WTC(0x0d990e40), WTC(0x0dd14500), WTC(0x0e09f730), WTC(0x0e432e90),
+ WTC(0x0e7cf790), WTC(0x0eb75e50), WTC(0x0ef26430), WTC(0x0f2dfd70),
+ WTC(0x0f6a1d70), WTC(0x0fa6b7e0), WTC(0x0fe3c3d0), WTC(0x10213ac0),
+ WTC(0x105f1640), WTC(0x109d4f20), WTC(0x10dbdb80), WTC(0x111ab0c0),
+ WTC(0x1159c360), WTC(0x11990fc0), WTC(0x11d8a060), WTC(0x121882c0),
+ WTC(0x1258c480), WTC(0x12995a40), WTC(0x12da1b00), WTC(0x131adb60),
+ WTC(0x135b70c0), WTC(0x139bb680), WTC(0x13db8c00), WTC(0x141ad080),
+ WTC(0x14596460), WTC(0x149729e0), WTC(0x14d404e0), WTC(0x150fd8e0),
+ WTC(0x154a88c0), WTC(0x1583f5e0), WTC(0x15bc0120), WTC(0x15f28ba0),
+ WTC(0x162779a0), WTC(0x165ab300), WTC(0x168c2040), WTC(0x16bbaa80),
+ WTC(0x16e94120), WTC(0x1714d9e0), WTC(0x173e6440), WTC(0x17660680),
+ WTC(0x178ca020), WTC(0x17b36400), WTC(0x17db84e0), WTC(0x1805d920),
+ WTC(0x18328400), WTC(0x18617cc0), WTC(0x1892bfa0), WTC(0x18c64540),
+ WTC(0x18fc0400), WTC(0x1933f140), WTC(0x196e0320), WTC(0x19aa2fc0),
+ WTC(0x19e86d80), WTC(0x1a28b2e0), WTC(0x1a6af700), WTC(0x1aaf3320),
+ WTC(0x1af56180), WTC(0x1b3d7ce0), WTC(0x1b877c40), WTC(0x1bd350c0),
+ WTC(0x1c20ea40), WTC(0x1c703840), WTC(0x1cc13860), WTC(0x1d13f760),
+ WTC(0x1d688420), WTC(0x1dbeed40), WTC(0x1e174660), WTC(0x1e71a640),
+ WTC(0x1ece2400), WTC(0x1f2cd220), WTC(0x1f8db3c0), WTC(0x1ff0c3e0),
+ WTC(0x20560080), WTC(0x20bd46c0), WTC(0x21263400), WTC(0x21905740),
+ WTC(0x21fb4100), WTC(0x2266ba80), WTC(0x22d2d140), WTC(0x233f9780),
+ WTC(0x23ad25c0), WTC(0x241bc800), WTC(0x248bf040), WTC(0x24fe1380),
+ WTC(0x25728180), WTC(0x25e90a00), WTC(0x26614080), WTC(0x26dabdc0),
+ WTC(0x27552540), WTC(0x27d03200), WTC(0x284ba580), WTC(0x28c740c0),
+ WTC(0x29431f80), WTC(0x29bfc9c0), WTC(0x2a3dd080), WTC(0x2abdc000),
+ WTC(0x2b3ffd00), WTC(0x2bc4cd80), WTC(0x2c4c7d40), WTC(0x2cd72ec0),
+ WTC(0x2d647f80), WTC(0x2df3cd80), WTC(0x2e847d80), WTC(0x2f15ea40),
+ WTC(0x2fa760c0), WTC(0x30382b80), WTC(0x30c79440), WTC(0x315566c0),
+ WTC(0x31e20800), WTC(0x326de7c0), WTC(0x32f98200), WTC(0x3385ba00),
+ WTC(0x3413bec0), WTC(0x34a4c480), WTC(0x3539bf00), WTC(0x35d2c4c0),
+ WTC(0x366f8340), WTC(0x370fb800), WTC(0x37b2cf80), WTC(0x3857a480),
+ WTC(0x38fcee80), WTC(0x39a16840), WTC(0x3a4422c0), WTC(0x3ae495c0),
+ WTC(0x3b824000), WTC(0x3c1cb500), WTC(0x3cb438c0), WTC(0x3d4994c0),
+ WTC(0x3ddd8f40), WTC(0x3e70ec00), WTC(0x3f045e40), WTC(0x3f989080),
+ WTC(0x402e32ff), WTC(0x40c5c07f), WTC(0x415f547f), WTC(0x41faf07f),
+ WTC(0x4298997f), WTC(0x4338307f), WTC(0x43d96bff), WTC(0x447bffff),
+ WTC(0x451f9cff), WTC(0x45c3daff), WTC(0x46683eff), WTC(0x470c4cff),
+ WTC(0x47af93ff), WTC(0x4851c3ff), WTC(0x48f29d7f), WTC(0x4991de7f),
+ WTC(0x4a2f5e7f), WTC(0x4acb287f), WTC(0x4b65537f), WTC(0x4bfdf37f),
+ WTC(0x4c95337f), WTC(0x4d2b51ff), WTC(0x4dc091ff), WTC(0x4e5533ff),
+ WTC(0x4ee96b7f), WTC(0x4f7d61ff), WTC(0x501140ff), WTC(0x50a5317f),
+ WTC(0x51395a7f), WTC(0x51cddf7f), WTC(0x5262e6ff), WTC(0x52f885ff),
+ WTC(0x538eb47f), WTC(0x542560ff), WTC(0x54bc7b7f), WTC(0x5553a8ff),
+ WTC(0x55ea35ff), WTC(0x567f66ff), WTC(0x5712897f), WTC(0x57a33a7f),
+ WTC(0x583152ff), WTC(0x58bca5ff), WTC(0x594530ff), WTC(0x59cb79ff),
+ WTC(0x5a5047ff), WTC(0x5ad45eff), WTC(0x5b584e7f), WTC(0x5bdc417f),
+ WTC(0x5c60487f), WTC(0x5ce476ff), WTC(0x5d68c47f), WTC(0x5ded06ff),
+ WTC(0x5e7111ff), WTC(0x5ef4b5ff), WTC(0x5f77a17f), WTC(0x5ff96aff),
+ WTC(0x6079a7ff), WTC(0x60f7f7ff), WTC(0x617417ff), WTC(0x61edd87f),
+ WTC(0x6264ffff), WTC(0x62d9a6ff), WTC(0x634c817f), WTC(0x63be657f),
+ WTC(0x6430277f), WTC(0x64a2247f), WTC(0x65142bff), WTC(0x6586027f),
+ WTC(0x65f7697f), WTC(0x666801ff), WTC(0x66d756ff), WTC(0x6744f0ff),
+ WTC(0x67b0787f), WTC(0x681a077f), WTC(0x6881ebff), WTC(0x68e8707f),
+ WTC(0x694dceff), WTC(0x69b21e7f), WTC(0x6a156cff), WTC(0x6a77ca7f),
+ WTC(0x6ad9377f), WTC(0x6b39a4ff), WTC(0x6b9901ff), WTC(0x6bf73cff),
+ WTC(0x6c54457f), WTC(0x6cb00aff), WTC(0x6d0a7bff), WTC(0x6d6387ff),
+ WTC(0xae2cbe01), WTC(0xaf526d01), WTC(0xb0751201), WTC(0xb194da81),
+ WTC(0xb2b1f401), WTC(0xb3cc8d01), WTC(0xb4e4d201), WTC(0xb5faf101),
+ WTC(0xb70f1881), WTC(0xb8217301), WTC(0xb9321181), WTC(0xba40ee01),
+ WTC(0xbb4e0201), WTC(0xbc594781), WTC(0xbd62b881), WTC(0xbe6a5181),
+ WTC(0xbf700d01), WTC(0xc073e4c0), WTC(0xc175d240), WTC(0xc275cc80),
+ WTC(0xc373cb80), WTC(0xc46fca00), WTC(0xc569c600), WTC(0xc661bdc0),
+ WTC(0xc757af80), WTC(0xc84b9840), WTC(0xc93d7300), WTC(0xca2d3a40),
+ WTC(0xcb1aea40), WTC(0xcc068280), WTC(0xccf00480), WTC(0xcdd77200),
+ WTC(0xcebccb40), WTC(0xcfa00d80), WTC(0xd0813540), WTC(0xd1603f00),
+ WTC(0xd23d2980), WTC(0xd317f7c0), WTC(0xd3f0ac40), WTC(0xd4c74980),
+ WTC(0xd59bcf80), WTC(0xd66e3b00), WTC(0xd73e8900), WTC(0xd80cb740),
+ WTC(0xd8d8c7c0), WTC(0xd9a2be00), WTC(0xda6a9e40), WTC(0xdb306a40),
+ WTC(0xdbf42080), WTC(0xdcb5be80), WTC(0xdd754140), WTC(0xde32a900),
+ WTC(0xdeedf9c0), WTC(0xdfa737c0), WTC(0xe05e6740), WTC(0xe1138900),
+ WTC(0xe1c69ac0), WTC(0xe2779a40), WTC(0xe3268680), WTC(0xe3d36260),
+ WTC(0xe47e33a0), WTC(0xe526ff80), WTC(0xe5cdc960), WTC(0xe6729100),
+ WTC(0xe7155460), WTC(0xe7b611c0), WTC(0xe854ca20), WTC(0xe8f18180),
+ WTC(0xe98c3ca0), WTC(0xea24ffe0), WTC(0xeabbcb20), WTC(0xeb509b60),
+ WTC(0xebe36d00), WTC(0xec743e00), WTC(0xed0310e0), WTC(0xed8feaa0),
+ WTC(0xee1ad060), WTC(0xeea3c640), WTC(0xef2acd60), WTC(0xefafe6a0),
+ WTC(0xf03312f0), WTC(0xf0b45800), WTC(0xf133c230), WTC(0xf1b15ef0),
+ WTC(0xf22d3af0), WTC(0xf2a75c80), WTC(0xf31fc460), WTC(0xf39673b0),
+ WTC(0xf40b6a00), WTC(0xf47ea230), WTC(0xf4f01450), WTC(0xf55fb930),
+ WTC(0xf5cd84c0), WTC(0xf6396090), WTC(0xf6a333e0), WTC(0xf70ae540),
+ WTC(0xf7707260), WTC(0xf7d3f720), WTC(0xf83592f0), WTC(0xf8956450),
+ WTC(0xf8f38120), WTC(0xf94ff7c8), WTC(0xf9aad740), WTC(0xfa042920),
+ WTC(0xfa5be110), WTC(0xfab1e778), WTC(0xfb062478), WTC(0xfb588d78),
+ WTC(0xfba93530), WTC(0xfbf836c8), WTC(0xfc45ace0), WTC(0xfc91a294),
+ WTC(0xfcdc0e5c), WTC(0xfd24e438), WTC(0xfd6c17dc), WTC(0xfdb19758),
+ WTC(0xfdf54c3c), WTC(0xfe371ef8), WTC(0xfe7701aa), WTC(0xfeb50d62),
+ WTC(0xfef1700a), WTC(0xff2c5574), WTC(0xff65ee7b), WTC(0xff9e75de),
+ WTC(0xffd62863), WTC(0x000d4401), WTC(0x0043d345), WTC(0x00799cd0),
+ WTC(0x00ae5f49), WTC(0x00e1d7a4), WTC(0x0113a6f2), WTC(0x0143575c),
+ WTC(0x01707024), WTC(0x019a9346), WTC(0x01c1cf08), WTC(0x01e66c12),
+ WTC(0x0208ac48), WTC(0x0228e868), WTC(0x0247a6c8), WTC(0x02657aa0),
+ WTC(0x0282f710), WTC(0x02a07e50), WTC(0x02be31c0), WTC(0x02dc2b30),
+ WTC(0x02fa7f34), WTC(0x0318fb10), WTC(0x03372fdc), WTC(0x0354ae54),
+ WTC(0x03710d18), WTC(0x038bfdb4), WTC(0x03a54084), WTC(0x03bc92b8),
+ WTC(0x03d1c710), WTC(0x03e4dd20), WTC(0x03f5e25c), WTC(0x0404e218),
+ WTC(0x0411fc30), WTC(0x041d6b30), WTC(0x04276cd0), WTC(0x04303e00),
+ WTC(0x04381528), WTC(0x043f2310), WTC(0x04459908), WTC(0x044ba430),
+ WTC(0x045161f8), WTC(0x0456e6f8), WTC(0x045c49a8), WTC(0x046192f8),
+ WTC(0x0466af40), WTC(0x046b8240), WTC(0x046ff0d8), WTC(0x0473de18),
+ WTC(0x04772b58), WTC(0x0479b9a0), WTC(0x047b6a30), WTC(0x047c2088),
+ WTC(0x047bc230), WTC(0x047a3418), WTC(0x04776098), WTC(0x04734790),
+ WTC(0x046df4c0), WTC(0x04677220), WTC(0x045fd1b0), WTC(0x04573588),
+ WTC(0x044dc4b8), WTC(0x0443a5b8), WTC(0x04390160), WTC(0x042e0398),
+ WTC(0x0422d8c0), WTC(0x0417aa30), WTC(0x040c7ce0), WTC(0x040136e0),
+ WTC(0x03f5beb0), WTC(0x03e9f8ec), WTC(0x03ddc484), WTC(0x03d0fd9c),
+ WTC(0x03c37fa0), WTC(0x03b53014), WTC(0x03a60a18), WTC(0x03960f88),
+ WTC(0x03854110), WTC(0x0373ad9c), WTC(0x03617694), WTC(0x034ebf9c),
+ WTC(0x033bab30), WTC(0x03284ef0), WTC(0x0314b598), WTC(0x0300ea54),
+ WTC(0x02ecf524), WTC(0x02d8d210), WTC(0x02c476ac), WTC(0x02afd940),
+ WTC(0x029aee4c), WTC(0x0285a6f4), WTC(0x026ff398), WTC(0x0259c448),
+ WTC(0x024317cc), WTC(0x022c0084), WTC(0x02149310), WTC(0x01fce334),
+ WTC(0x01e4fb24), WTC(0x01ccdd0a), WTC(0x01b48b20), WTC(0x019c077e),
+ WTC(0x01835432), WTC(0x016a733c), WTC(0x015166a6), WTC(0x0138302e),
+ WTC(0x011ed0f6), WTC(0x010549f8), WTC(0x00eb9c25), WTC(0x00d1caa6),
+ WTC(0x00b7db94), WTC(0x009dd560), WTC(0x0083be75), WTC(0x00699d41),
+ WTC(0x004f782f), WTC(0x003555ab), WTC(0x001b3c21), WTC(0x000131fe),
+ WTC(0xd61cfc40), WTC(0xd5acb340), WTC(0xd53d4400), WTC(0xd4cea6c0),
+ WTC(0xd460d440), WTC(0xd3f3c440), WTC(0xd3876f80), WTC(0xd31bce40),
+ WTC(0xd2b0d900), WTC(0xd2468980), WTC(0xd1dcef00), WTC(0xd17429c0),
+ WTC(0xd10c5b80), WTC(0xd0a59b80), WTC(0xd03fd780), WTC(0xcfdae780),
+ WTC(0xcf76a380), WTC(0xcf12fac0), WTC(0xceb01100), WTC(0xce4e18c0),
+ WTC(0xcded4440), WTC(0xcd8d9a40), WTC(0xcd2ee800), WTC(0xccd0f440),
+ WTC(0xcc738780), WTC(0xcc167d40), WTC(0xcbb9c180), WTC(0xcb5d4040),
+ WTC(0xcb00e240), WTC(0xcaa48000), WTC(0xca47eac0), WTC(0xc9eaf1c0),
+ WTC(0xc98d8100), WTC(0xc92fc580), WTC(0xc8d1fc80), WTC(0xc8746480),
+ WTC(0xc816dc40), WTC(0xc7b8c280), WTC(0xc7596800), WTC(0xc6f81f80),
+ WTC(0xc6945740), WTC(0xc62d93c0), WTC(0xc5c358c0), WTC(0xc5552b80),
+ WTC(0xc4e29240), WTC(0xc46b1440), WTC(0xc3ee3840), WTC(0xc36b8500),
+ WTC(0xc2e28040), WTC(0xc252ae80), WTC(0xc1bb9540), WTC(0xc11cc200),
+ WTC(0xc075cf00), WTC(0xbfc65781), WTC(0xbf0df881), WTC(0xbe4c6f01),
+ WTC(0xbd819401), WTC(0xbcad2d01), WTC(0xbbcfb981), WTC(0xbaeca681),
+ WTC(0xba08e781), WTC(0xb9297081), WTC(0xb851e081), WTC(0xb782ed01),
+ WTC(0xb6bc6a81), WTC(0xb5fe4981), WTC(0xb5487281), WTC(0xb49ad081),
+ WTC(0xb3f54d81), WTC(0xb357d401), WTC(0xb2c24e01), WTC(0xb234a681),
+ WTC(0xb1aec701), WTC(0xb1309b01), WTC(0xb0ba0c01), WTC(0xb04b0481),
+ WTC(0xafe36f01), WTC(0xaf833601), WTC(0xaf2a4381), WTC(0xaed88201),
+ WTC(0xae8ddb81), WTC(0xae4a3b81), WTC(0xae0d8b01), WTC(0xadd7b581),
+ WTC(0xada8a481), WTC(0xad804281), WTC(0xad5e7a81), WTC(0xad433601),
+ WTC(0xad2e6001), WTC(0xad1fe281), WTC(0xad17a801), WTC(0xad159a81),
+ WTC(0xad19a501), WTC(0xad23b101), WTC(0xad33aa01), WTC(0xad497981),
+ WTC(0xad650a01), WTC(0xad864601), WTC(0xadad1781), WTC(0xadd96981),
+ WTC(0xae0b2601), WTC(0xae423781), WTC(0xae7e8801), WTC(0xaec00201),
+ WTC(0xaf069081), WTC(0xaf521c81), WTC(0xafa29201), WTC(0xaff7da01),
+ WTC(0xb051df01), WTC(0xb0b08c81), WTC(0xb113cb81), WTC(0xb17b8701),
+ WTC(0xb1e7a981), WTC(0xb2581d81), WTC(0xb2cccc81), WTC(0xb345a181),
+ WTC(0xb3c28701), WTC(0xb4436681), WTC(0xb4c82b81), WTC(0xb550bf81),
+ WTC(0xb5dd0d01), WTC(0xb66cff01), WTC(0xb7007f01), WTC(0xb7977781),
+ WTC(0xb831d381), WTC(0xb8cf7d01), WTC(0xb9705e01), WTC(0xba146101),
+ WTC(0xbabb7081), WTC(0xbb657781), WTC(0xbc125f01), WTC(0xbcc21281),
+ WTC(0xbd747b81), WTC(0xbe298581), WTC(0xbee11981), WTC(0xbf9b2301),
+ WTC(0xc0578b80), WTC(0xc1163dc0), WTC(0xc1d72400), WTC(0xc29a28c0),
+ WTC(0xc35f3640), WTC(0xc42636c0), WTC(0xc4ef1500), WTC(0xc5b9bb00),
+ WTC(0xc6861340), WTC(0xc7540840), WTC(0xc8238400), WTC(0xc8f47100),
+ WTC(0xc9c6b9c0), WTC(0xca9a4840), WTC(0xcb6f0780), WTC(0xcc44e140),
+ WTC(0xcd1bc000), WTC(0xcdf38e00), WTC(0xcecc3600), WTC(0xcfa5a240),
+ WTC(0xd07fbcc0), WTC(0xd15a7040), WTC(0xd235a6c0), WTC(0xd3114b00),
+ WTC(0xd3ed4740), WTC(0xd4c98580), WTC(0xd5a5f080), WTC(0xd6827280),
+ WTC(0xd75ef600), WTC(0xd83b6500), WTC(0xd917aa00), WTC(0xd9f3af80),
+ WTC(0xdacf5fc0), WTC(0xdbaaa540), WTC(0xdc856a00), WTC(0xdd5f98c0),
+ WTC(0xde391bc0), WTC(0xdf11dd40), WTC(0xdfe9c780), WTC(0xe0c0c540),
+ WTC(0xe196c080), WTC(0xe26ba3c0), WTC(0xe33f5960), WTC(0xe411cba0),
+ WTC(0xe4e2e500), WTC(0xe5b28fc0), WTC(0xe680b640), WTC(0xe74d42e0),
+ WTC(0xe8181fe0), WTC(0xe8e137e0), WTC(0xe9a87500), WTC(0xea6dc1a0),
+ WTC(0xeb310820), WTC(0xebf23300), WTC(0xecb12c60), WTC(0xed6ddee0),
+ WTC(0xee2834a0), WTC(0xeee01800), WTC(0xef957380), WTC(0xf0483160),
+ WTC(0xf0f83c00), WTC(0xf1a57db0), WTC(0xf24fe0f0), WTC(0xf2f74ff0),
+ WTC(0xf39bb530), WTC(0xf43cfaf0), WTC(0xf4db0b90), WTC(0xf575d180),
+ WTC(0xf60d3700), WTC(0xf6a12680), WTC(0xf7318a50), WTC(0xf7be4cc0),
+ WTC(0xf8475850), WTC(0xf8cc9738), WTC(0xf94df3e0), WTC(0xf9cb58a8),
+ WTC(0xfa44afe0), WTC(0xfab9e3e8), WTC(0xfb2adf20), WTC(0xfb978be8),
+ WTC(0xfbffd488), WTC(0xfc63a370), WTC(0xfcc2e2f0), WTC(0xfd1d7d64),
+ WTC(0xfd735d2c), WTC(0xfdc46c9c), WTC(0xfe109618), WTC(0xfe57c3f4),
+ WTC(0xfe99e090), WTC(0xfed6d644), WTC(0xff0e8f6e), WTC(0xff40f667),
+ WTC(0xff6df58c), WTC(0xff957738), WTC(0xffb765c5), WTC(0xffd3ab90),
+ WTC(0xffea32f4), WTC(0xfffae64c), WTC(0x0005aff3), WTC(0x000a7a44),
+ WTC(0x00092f9c), WTC(0x0001ba54), WTC(0xfff404ca), WTC(0xffdff957)};
+
+/*
+ * TNS_MAX_BANDS
+ * entry for each sampling rate
+ * 1 long window
+ * 2 SHORT window
+ */
+const UCHAR tns_max_bands_tbl[13][2] = {
+ {31, 9}, /* 96000 */
+ {31, 9}, /* 88200 */
+ {34, 10}, /* 64000 */
+ {40, 14}, /* 48000 */
+ {42, 14}, /* 44100 */
+ {51, 14}, /* 32000 */
+ {46, 14}, /* 24000 */
+ {46, 14}, /* 22050 */
+ {42, 14}, /* 16000 */
+ {42, 14}, /* 12000 */
+ {42, 14}, /* 11025 */
+ {39, 14}, /* 8000 */
+ {39, 14}, /* 7350 */
+};
+
+/* TNS_MAX_BANDS for low delay. The array index is the sampleRateIndex */
+const UCHAR tns_max_bands_tbl_480[13] = {
+ 31, /* 96000 */
+ 31, /* 88200 */
+ 31, /* 64000 */
+ 31, /* 48000 */
+ 32, /* 44100 */
+ 37, /* 32000 */
+ 30, /* 24000 */
+ 30, /* 22050 */
+ 30, /* 16000 */
+ 30, /* 12000 */
+ 30, /* 11025 */
+ 30, /* 8000 */
+ 30 /* 7350 */
+};
+const UCHAR tns_max_bands_tbl_512[13] = {
+ 31, /* 96000 */
+ 31, /* 88200 */
+ 31, /* 64000 */
+ 31, /* 48000 */
+ 32, /* 44100 */
+ 37, /* 32000 */
+ 31, /* 24000 */
+ 31, /* 22050 */
+ 31, /* 16000 */
+ 31, /* 12000 */
+ 31, /* 11025 */
+ 31, /* 8000 */
+ 31 /* 7350 */
+};
+
+#define TCC(x) (FIXP_DBL(x))
+
+const FIXP_TCC FDKaacDec_tnsCoeff3[8] = {
+ TCC(0x81f1d1d4), TCC(0x9126146c), TCC(0xadb922c4), TCC(0xd438af1f),
+ TCC(0x00000000), TCC(0x3789809b), TCC(0x64130dd4), TCC(0x7cca7016)};
+const FIXP_TCC FDKaacDec_tnsCoeff4[16] = {
+ TCC(0x808bc842), TCC(0x84e2e58c), TCC(0x8d6b49d1), TCC(0x99da920a),
+ TCC(0xa9c45713), TCC(0xbc9ddeb9), TCC(0xd1c2d51b), TCC(0xe87ae53d),
+ TCC(0x00000000), TCC(0x1a9cd9b6), TCC(0x340ff254), TCC(0x4b3c8c29),
+ TCC(0x5f1f5ebb), TCC(0x6ed9ebba), TCC(0x79bc385f), TCC(0x7f4c7e5b)};
+
+const UCHAR FDKaacDec_tnsCoeff3_gain_ld[] = {
+ 3, 1, 1, 1, 0, 1, 1, 3,
+};
+const UCHAR FDKaacDec_tnsCoeff4_gain_ld[] = {
+ 4, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 4,
+};
+
+/* Lookup tables for elements in ER bitstream */
+const MP4_ELEMENT_ID
+ elementsTab[AACDEC_MAX_CH_CONF][AACDEC_CH_ELEMENTS_TAB_SIZE] = {
+ /* 1 */ {ID_SCE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* 1 channel */
+ /* 2 */
+ {ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE} /* 2 channels */
+#if (AACDEC_MAX_CH_CONF > 2)
+ /* 3 */,
+ {ID_SCE, ID_CPE, ID_EXT, ID_END, ID_NONE, ID_NONE,
+ ID_NONE}, /* 3 channels */
+ /* 4 */
+ {ID_SCE, ID_CPE, ID_SCE, ID_EXT, ID_END, ID_NONE,
+ ID_NONE}, /* 4 channels */
+ /* 5 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_EXT, ID_END, ID_NONE,
+ ID_NONE}, /* 5 channels */
+ /* 6 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_EXT, ID_END,
+ ID_NONE} /* 6 channels */
+#endif
+#if (AACDEC_MAX_CH_CONF > 6)
+ /* 7 */,
+ {ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT,
+ ID_END}, /* 8 channels */
+ /* 8 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 9 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 10 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* reserved */
+ /* 11 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_SCE, ID_LFE, ID_EXT,
+ ID_END}, /* 7 channels */
+ /* 12 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_CPE, ID_LFE, ID_EXT,
+ ID_END}, /* 8 channels */
+ /* 13 */
+ {ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE, ID_NONE,
+ ID_NONE}, /* see elementsChCfg13 */
+ /* 14 */
+ {ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_EXT,
+ ID_END} /* 8 channels */
+#endif
+};
+
+/*! Random sign bit used for concealment
+ */
+const USHORT AacDec_randomSign[AAC_NF_NO_RANDOM_VAL / 16] = {
+ /*
+ sign bits of FDK_sbrDecoder_sbr_randomPhase[] entries:
+ LSB ........... MSB -> MSB ... LSB
+ */
+ /* 1001 0111 0011 1100 -> */ 0x3ce9,
+ /* 0100 0111 0111 1011 -> */ 0xdee2,
+ /* 0001 1100 1110 1011 -> */ 0xd738,
+ /* 0001 0011 0110 1001 -> */ 0x96c8,
+ /* 0101 0011 1101 0000 -> */ 0x0bca,
+ /* 0001 0001 1111 0100 -> */ 0x2f88,
+ /* 1110 1100 1110 1101 -> */ 0xb737,
+ /* 0010 1010 1011 1001 -> */ 0x9d54,
+ /* 0111 1100 0110 1010 -> */ 0x563e,
+ /* 1101 0111 0010 0101 -> */ 0xa4eb,
+ /* 0001 0101 1011 1100 -> */ 0x3da8,
+ /* 0101 0111 1001 1011 -> */ 0xd9ea,
+ /* 1101 0100 0101 0101 -> */ 0xaa2b,
+ /* 1000 1001 0100 0011 -> */ 0xc291,
+ /* 1100 1111 1010 1100 -> */ 0x35f3,
+ /* 1100 1010 1110 0010 -> */ 0x4753,
+ /* 0110 0001 1010 1000 -> */ 0x1586,
+ /* 0011 0101 1111 1100 -> */ 0x3fac,
+ /* 0001 0110 1010 0001 -> */ 0x8568,
+ /* 0010 1101 0111 0010 -> */ 0x4eb4,
+ /* 1101 1010 0100 1001 -> */ 0x925b,
+ /* 1100 1001 0000 1110 -> */ 0x7093,
+ /* 1000 1100 0110 1010 -> */ 0x5631,
+ /* 0000 1000 0110 1101 -> */ 0xb610,
+ /* 1000 0001 1111 1011 -> */ 0xdf81,
+ /* 1111 0011 0100 0111 -> */ 0xe2cf,
+ /* 1000 0001 0010 1010 -> */ 0x5481,
+ /* 1101 0101 1100 1111 -> */ 0xf3ab,
+ /* 0110 0001 0110 1000 -> */ 0x1686,
+ /* 0011 0011 1100 0110 -> */ 0x63cc,
+ /* 0011 0111 0101 0110 -> */ 0x6aec,
+ /* 1011 0001 1010 0010 -> */ 0x458d};
+
+/* MDST filter coefficients for current window
+ * max: 0.635722 => 20 bits (unsigned) necessary for representation
+ * min: = -max */
+const FIXP_FILT mdst_filt_coef_curr[20][3] = {
+ {FILT(0.000000f), FILT(0.000000f), FILT(0.500000f)},
+ /*, FILT( 0.000000f), FILT(-0.500000f), FILT( 0.000000f), FILT( 0.000000f) }, */ /* only long / eight short l:sine r:sine */
+ {FILT(0.091497f), FILT(0.000000f), FILT(0.581427f)},
+ /*, FILT( 0.000000f), FILT(-0.581427f), FILT( 0.000000f), FILT(-0.091497f) }, */ /* l:kbd r:kbd */
+ {FILT(0.045748f), FILT(0.057238f), FILT(0.540714f)},
+ /*, FILT( 0.000000f), FILT(-0.540714f), FILT(-0.057238f), FILT(-0.045748f) }, */ /* l:sine r:kbd */
+ {FILT(0.045748f), FILT(-0.057238f), FILT(0.540714f)},
+ /*, FILT( 0.000000f), FILT(-0.540714f), FILT( 0.057238f), FILT(-0.045748f) }, */ /* l:kbd r:sine */
+
+ {FILT(0.102658f), FILT(0.103791f), FILT(0.567149f)},
+ /*, FILT( 0.000000f), FILT(-0.567149f), FILT(-0.103791f), FILT(-0.102658f) }, */ /* long start */
+ {FILT(0.150512f), FILT(0.047969f),
+ FILT(0.608574f)}, /*, FILT( 0.000000f), FILT(-0.608574f),
+ FILT(-0.047969f), FILT(-0.150512f) }, */
+ {FILT(0.104763f), FILT(0.105207f),
+ FILT(0.567861f)}, /*, FILT( 0.000000f), FILT(-0.567861f),
+ FILT(-0.105207f), FILT(-0.104763f) }, */
+ {FILT(0.148406f), FILT(0.046553f),
+ FILT(0.607863f)}, /*, FILT( 0.000000f), FILT(-0.607863f),
+ FILT(-0.046553f), FILT(-0.148406f) }, */
+
+ {FILT(0.102658f), FILT(-0.103791f), FILT(0.567149f)},
+ /*, FILT( 0.000000f), FILT(-0.567149f), FILT( 0.103791f), FILT(-0.102658f) }, */ /* long stop */
+ {FILT(0.150512f), FILT(-0.047969f),
+ FILT(0.608574f)}, /*, FILT( 0.000000f), FILT(-0.608574f), FILT(
+ 0.047969f), FILT(-0.150512f) }, */
+ {FILT(0.148406f), FILT(-0.046553f),
+ FILT(0.607863f)}, /*, FILT( 0.000000f), FILT(-0.607863f), FILT(
+ 0.046553f), FILT(-0.148406f) }, */
+ {FILT(0.104763f), FILT(-0.105207f),
+ FILT(0.567861f)}, /*, FILT( 0.000000f), FILT(-0.567861f), FILT(
+ 0.105207f), FILT(-0.104763f) }, */
+
+ {FILT(0.205316f), FILT(0.000000f), FILT(0.634298f)},
+ /*, FILT( 0.000000f), FILT(-0.634298f), FILT( 0.000000f), FILT(-0.205316f) }, */ /* stop start */
+ {FILT(0.209526f), FILT(0.000000f),
+ FILT(0.635722f)}, /*, FILT( 0.000000f), FILT(-0.635722f), FILT(
+ 0.000000f), FILT(-0.209526f) }, */
+ {FILT(0.207421f), FILT(0.001416f),
+ FILT(0.635010f)}, /*, FILT( 0.000000f), FILT(-0.635010f),
+ FILT(-0.001416f), FILT(-0.207421f) }, */
+ {FILT(0.207421f), FILT(-0.001416f),
+ FILT(0.635010f)}, /*, FILT( 0.000000f), FILT(-0.635010f), FILT(
+ 0.001416f), FILT(-0.207421f) } */
+
+ {FILT(0.185618f), FILT(0.000000f), FILT(0.627371f)},
+ /*, FILT( 0.000000f), FILT(-0.634298f), FILT( 0.000000f), FILT(-0.205316f) }, */ /* stop start Transform Splitting */
+ {FILT(0.204932f), FILT(0.000000f),
+ FILT(0.634159f)}, /*, FILT( 0.000000f), FILT(-0.635722f), FILT(
+ 0.000000f), FILT(-0.209526f) }, */
+ {FILT(0.194609f), FILT(0.006202f),
+ FILT(0.630536f)}, /*, FILT( 0.000000f), FILT(-0.635010f),
+ FILT(-0.001416f), FILT(-0.207421f) }, */
+ {FILT(0.194609f), FILT(-0.006202f),
+ FILT(0.630536f)}, /*, FILT( 0.000000f), FILT(-0.635010f), FILT(
+ 0.001416f), FILT(-0.207421f) } */
+};
+
+/* MDST filter coefficients for previous window
+ * max: 0.31831 => 15 bits (unsigned) necessary for representation
+ * min: 0.0 */
+const FIXP_FILT mdst_filt_coef_prev[6][4] = {
+ {FILT(0.000000f), FILT(0.106103f), FILT(0.250000f), FILT(0.318310f)},
+ /*, FILT( 0.250000f), FILT( 0.106103f), FILT( 0.000000f) }, */ /* only long
+ / long
+ start /
+ eight
+ short
+ l:sine */
+ {FILT(0.059509f), FILT(0.123714f), FILT(0.186579f), FILT(0.213077f)},
+ /*, FILT( 0.186579f), FILT( 0.123714f), FILT( 0.059509f) }, */ /* l:kbd
+ */
+
+ {FILT(0.038498f), FILT(0.039212f), FILT(0.039645f), FILT(0.039790f)},
+ /*, FILT( 0.039645f), FILT( 0.039212f), FILT( 0.038498f) }, */ /* long stop
+ / stop
+ start
+ l:sine */
+ {FILT(0.026142f), FILT(0.026413f), FILT(0.026577f), FILT(0.026631f)},
+ /*, FILT( 0.026577f), FILT( 0.026413f), FILT( 0.026142f) } */ /* l:kbd
+ */
+
+ {FILT(0.069608f), FILT(0.075028f), FILT(0.078423f), FILT(0.079580f)},
+ /*, FILT( 0.039645f), FILT( 0.039212f), FILT( 0.038498f) }, */ /* Transform
+ splitting
+ l:sine */
+ {FILT(0.042172f), FILT(0.043458f), FILT(0.044248f), FILT(0.044514f)},
+ /*, FILT( 0.026577f), FILT( 0.026413f), FILT( 0.026142f) } */ /* l:kbd
+ */
+};
diff --git a/fdk-aac/libAACdec/src/aac_rom.h b/fdk-aac/libAACdec/src/aac_rom.h
new file mode 100644
index 0000000..ffaf951
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aac_rom.h
@@ -0,0 +1,237 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: Definition of constant tables
+
+*******************************************************************************/
+
+#ifndef AAC_ROM_H
+#define AAC_ROM_H
+
+#include "common_fix.h"
+#include "FDK_audio.h"
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcrs.h"
+
+#define PCM_DEC FIXP_DBL
+#define MAXVAL_PCM_DEC MAXVAL_DBL
+#define MINVAL_PCM_DEC MINVAL_DBL
+#define FIXP_DBL2PCM_DEC(x) (x)
+#define PCM_DEC2FIXP_DBL(x) (x)
+#define PCM_DEC_BITS DFRACT_BITS
+#define PCM_DEC2FX_PCM(x) FX_DBL2FX_PCM(x)
+#define FX_PCM2PCM_DEC(x) FX_PCM2FX_DBL(x)
+
+#define AACDEC_MAX_CH_CONF 14
+#define AACDEC_CH_ELEMENTS_TAB_SIZE 7 /*!< Size of element tables */
+
+#define AAC_NF_NO_RANDOM_VAL \
+ 512 /*!< Size of random number array for noise floor */
+
+#define INV_QUANT_TABLESIZE 256
+
+extern const FIXP_DBL InverseQuantTable[INV_QUANT_TABLESIZE + 1];
+extern const FIXP_DBL MantissaTable[4][14];
+extern const SCHAR ExponentTable[4][14];
+
+#define NUM_LD_COEF_512 1536
+#define NUM_LD_COEF_480 1440
+/* Window table partition exponents. */
+#define WTS0 (1)
+#define WTS1 (0)
+#define WTS2 (-2)
+extern const FIXP_WTB LowDelaySynthesis512[1536];
+extern const FIXP_WTB LowDelaySynthesis480[1440];
+extern const FIXP_WTB LowDelaySynthesis256[768];
+extern const FIXP_WTB LowDelaySynthesis240[720];
+extern const FIXP_WTB LowDelaySynthesis160[480];
+extern const FIXP_WTB LowDelaySynthesis128[384];
+extern const FIXP_WTB LowDelaySynthesis120[360];
+
+typedef struct {
+ const SHORT *sfbOffsetLong;
+ const SHORT *sfbOffsetShort;
+ UCHAR numberOfSfbLong;
+ UCHAR numberOfSfbShort;
+} SFB_INFO;
+
+extern const SFB_INFO sfbOffsetTables[5][16];
+
+/* Huffman tables */
+enum { HuffmanBits = 2, HuffmanEntries = (1 << HuffmanBits) };
+
+typedef struct {
+ const USHORT (*CodeBook)[HuffmanEntries];
+ UCHAR Dimension;
+ UCHAR numBits;
+ UCHAR Offset;
+} CodeBookDescription;
+
+extern const CodeBookDescription AACcodeBookDescriptionTable[13];
+extern const CodeBookDescription AACcodeBookDescriptionSCL;
+
+extern const STATEFUNC aStateConstant2State[];
+
+extern const SCHAR aCodebook2StartInt[];
+
+extern const UCHAR aMinOfCbPair[];
+extern const UCHAR aMaxOfCbPair[];
+
+extern const UCHAR aMaxCwLen[];
+extern const UCHAR aDimCb[];
+extern const UCHAR aDimCbShift[];
+extern const UCHAR aSignCb[];
+extern const UCHAR aCbPriority[];
+
+extern const UINT *aHuffTable[];
+extern const SCHAR *aQuantTable[];
+
+extern const USHORT aLargestAbsoluteValue[];
+
+extern const UINT aHuffTreeRvlcEscape[];
+extern const UINT aHuffTreeRvlCodewds[];
+
+extern const UCHAR tns_max_bands_tbl[13][2];
+
+extern const UCHAR tns_max_bands_tbl_480[13];
+extern const UCHAR tns_max_bands_tbl_512[13];
+
+#define FIXP_TCC FIXP_DBL
+
+extern const FIXP_TCC FDKaacDec_tnsCoeff3[8];
+extern const FIXP_TCC FDKaacDec_tnsCoeff4[16];
+
+extern const UCHAR FDKaacDec_tnsCoeff3_gain_ld[];
+extern const UCHAR FDKaacDec_tnsCoeff4_gain_ld[];
+
+extern const USHORT AacDec_randomSign[AAC_NF_NO_RANDOM_VAL / 16];
+
+extern const FIXP_DBL pow2_div24minus1[47];
+extern const int offsetTab[2][16];
+
+/* Channel mapping indices for time domain I/O.
+ The first dimension is the channel configuration index. */
+extern const UCHAR channelMappingTablePassthrough[15][8];
+extern const UCHAR channelMappingTableWAV[15][8];
+
+/* Lookup tables for elements in ER bitstream */
+extern const MP4_ELEMENT_ID elementsTab[AACDEC_MAX_CH_CONF]
+ [AACDEC_CH_ELEMENTS_TAB_SIZE];
+
+#define SF_FNA_COEFFS \
+ 1 /* Compile-time prescaler for MDST-filter coefficients. */
+/* SF_FNA_COEFFS > 0 should only be considered for FIXP_DBL-coefficients */
+/* (i.e. if CPLX_PRED_FILTER_16BIT is not defined). */
+/* With FIXP_DBL loss of precision is possible for SF_FNA_COEFFS > 11. */
+
+#ifdef CPLX_PRED_FILTER_16BIT
+#define FIXP_FILT FIXP_SGL
+#define FILT(a) ((FL2FXCONST_SGL(a)) >> SF_FNA_COEFFS)
+#else
+#define FIXP_FILT FIXP_DBL
+#define FILT(a) ((FL2FXCONST_DBL(a)) >> SF_FNA_COEFFS)
+#endif
+
+extern const FIXP_FILT mdst_filt_coef_curr[20][3]; /* MDST-filter coefficient
+ tables used for current
+ window */
+extern const FIXP_FILT mdst_filt_coef_prev[6][4]; /* MDST-filter coefficient
+ tables used for previous
+ window */
+
+#endif /* #ifndef AAC_ROM_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_drc.cpp b/fdk-aac/libAACdec/src/aacdec_drc.cpp
new file mode 100644
index 0000000..922a09e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc.cpp
@@ -0,0 +1,1355 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for AAC
+
+*******************************************************************************/
+
+#include "aacdec_drc.h"
+
+#include "channelinfo.h"
+#include "aac_rom.h"
+
+#include "sbrdecoder.h"
+
+/*
+ * Dynamic Range Control
+ */
+
+/* For parameter conversion */
+#define DRC_PARAMETER_BITS (7)
+#define DRC_MAX_QUANT_STEPS (1 << DRC_PARAMETER_BITS)
+#define DRC_MAX_QUANT_FACTOR (DRC_MAX_QUANT_STEPS - 1)
+#define DRC_PARAM_QUANT_STEP \
+ (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR))
+#define DRC_PARAM_SCALE (1)
+#define DRC_SCALING_MAX \
+ ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127))
+
+#define DRC_BLOCK_LEN (1024)
+#define DRC_BAND_MULT (4)
+#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT)
+
+#define MAX_REFERENCE_LEVEL (127)
+
+#define DRC_HEAVY_THRESHOLD_DB (10)
+
+#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */
+
+#define OFF 0
+#define ON 1
+
+static INT convert_drcParam(FIXP_DBL param_dbl) {
+ /* converts an internal DRC boost/cut scaling factor in FIXP_DBL
+ (which is downscaled by DRC_PARAM_SCALE)
+ back to an integer value between 0 and 127. */
+ LONG param_long;
+
+ param_long = (LONG)param_dbl >> 7;
+ param_long = param_long * (INT)DRC_MAX_QUANT_FACTOR;
+ param_long >>= 31 - 7 - DRC_PARAM_SCALE - 1;
+ param_long += 1; /* for rounding */
+ param_long >>= 1;
+
+ return (INT)param_long;
+}
+
+/*!
+ \brief Initialize DRC information
+
+ \self Handle of DRC info
+
+ \return none
+*/
+void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
+ CDrcParams *pParams;
+
+ if (self == NULL) {
+ return;
+ }
+
+ /* init control fields */
+ self->enable = OFF;
+ self->numThreads = 0;
+
+ /* init params */
+ pParams = &self->params;
+ pParams->bsDelayEnable = 0;
+ pParams->cut = FL2FXCONST_DBL(0.0f);
+ pParams->usrCut = FL2FXCONST_DBL(0.0f);
+ pParams->boost = FL2FXCONST_DBL(0.0f);
+ pParams->usrBoost = FL2FXCONST_DBL(0.0f);
+ pParams->targetRefLevel = -1;
+ pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
+ pParams->applyDigitalNorm = OFF;
+ pParams->applyHeavyCompression = OFF;
+ pParams->usrApplyHeavyCompression = OFF;
+
+ pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING;
+ pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */
+
+ self->update = 1;
+ self->numOutChannels = 0;
+ self->prevAacNumChannels = 0;
+
+ /* initial program ref level = target ref level */
+ self->progRefLevel = pParams->targetRefLevel;
+ self->progRefLevelPresent = 0;
+ self->presMode = -1;
+ self->uniDrcPrecedence = 0;
+}
+
+/*!
+ \brief Initialize DRC control data for one channel
+
+ \self Handle of DRC info
+
+ \return none
+*/
+void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
+ if (pDrcChData != NULL) {
+ pDrcChData->expiryCount = 0;
+ pDrcChData->numBands = 1;
+ pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+ pDrcChData->drcValue[0] = 0;
+ pDrcChData->drcInterpolationScheme = 0;
+ pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
+ }
+}
+
+/*!
+ \brief Set one single DRC parameter
+
+ \self Handle of DRC info.
+ \param Parameter to be set.
+ \value Value to be set.
+
+ \return an error code.
+*/
+AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
+ AACDEC_DRC_PARAM param, INT value) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ switch (param) {
+ case DRC_CUT_SCALE:
+ /* set attenuation scale factor */
+ if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.usrCut = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
+ self->update = 1;
+ break;
+ case DRC_BOOST_SCALE:
+ /* set boost factor */
+ if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.usrBoost = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
+ self->update = 1;
+ break;
+ case TARGET_REF_LEVEL:
+ if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ if (value < 0) {
+ self->params.applyDigitalNorm = OFF;
+ self->params.targetRefLevel = -1;
+ } else {
+ /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */
+ self->params.applyDigitalNorm = ON;
+ if (self->params.targetRefLevel != (SCHAR)value) {
+ self->params.targetRefLevel = (SCHAR)value;
+ self->progRefLevel = (SCHAR)value; /* Always set the program reference
+ level equal to the target level
+ according to 4.5.2.7.3 of
+ ISO/IEC 14496-3. */
+ }
+ self->update = 1;
+ }
+ break;
+ case APPLY_NORMALIZATION:
+ if ((value != OFF) && (value != ON)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ /* Store new parameter value */
+ self->params.applyDigitalNorm = (UCHAR)value;
+ break;
+ case APPLY_HEAVY_COMPRESSION:
+ if ((value != OFF) && (value != ON)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ /* Store new parameter value */
+ self->params.usrApplyHeavyCompression = (UCHAR)value;
+ self->update = 1;
+ break;
+ case DEFAULT_PRESENTATION_MODE:
+ if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED ||
+ value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.defaultPresentationMode =
+ (AACDEC_DRC_PARAMETER_HANDLING)value;
+ self->update = 1;
+ break;
+ case ENCODER_TARGET_LEVEL:
+ if (value > MAX_REFERENCE_LEVEL || value < 0) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.encoderTargetLevel = (UCHAR)value;
+ self->update = 1;
+ break;
+ case DRC_BS_DELAY:
+ if (value < 0 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.bsDelayEnable = value;
+ break;
+ case DRC_DATA_EXPIRY_FRAME:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
+ break;
+ case MAX_OUTPUT_CHANNELS:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->numOutChannels = (INT)value;
+ self->update = 1;
+ break;
+ case UNIDRC_PRECEDENCE:
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+ self->uniDrcPrecedence = (UCHAR)value;
+ break;
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ } /* switch(param) */
+
+ return ErrorStatus;
+}
+
+static int parseExcludedChannels(UINT *excludedChnsMask,
+ HANDLE_FDK_BITSTREAM bs) {
+ UINT excludeMask = 0;
+ UINT i, j;
+ int bitCnt = 9;
+
+ for (i = 0, j = 1; i < 7; i++, j <<= 1) {
+ if (FDKreadBits(bs, 1)) {
+ excludeMask |= j;
+ }
+ }
+
+ /* additional_excluded_chns */
+ while (FDKreadBits(bs, 1)) {
+ for (i = 0; i < 7; i++, j <<= 1) {
+ if (FDKreadBits(bs, 1)) {
+ excludeMask |= j;
+ }
+ }
+ bitCnt += 9;
+ FDK_ASSERT(j < (UINT)-1);
+ }
+
+ *excludedChnsMask = excludeMask;
+
+ return (bitCnt);
+}
+
+/*!
+ \brief Save DRC payload bitstream position
+
+ \self Handle of DRC info
+ \bs Handle of FDK bitstream
+
+ \return The number of DRC payload bits
+*/
+int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs,
+ AACDEC_DRC_PAYLOAD_TYPE type) {
+ UINT bsStartPos;
+ int i, numBands = 1, bitCnt = 0;
+
+ if (self == NULL) {
+ return 0;
+ }
+
+ bsStartPos = FDKgetValidBits(bs);
+
+ switch (type) {
+ case MPEG_DRC_EXT_DATA: {
+ bitCnt = 4;
+
+ if (FDKreadBits(bs, 1)) { /* pce_tag_present */
+ FDKreadBits(bs, 8); /* pce_instance_tag + drc_tag_reserved_bits */
+ bitCnt += 8;
+ }
+
+ if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
+ FDKreadBits(bs, 7); /* exclude mask [0..7] */
+ bitCnt += 8;
+ while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
+ FDKreadBits(bs, 7); /* exclude mask [x..y] */
+ bitCnt += 8;
+ }
+ }
+
+ if (FDKreadBits(bs, 1)) { /* drc_bands_present */
+ numBands += FDKreadBits(bs, 4); /* drc_band_incr */
+ FDKreadBits(bs, 4); /* reserved */
+ bitCnt += 8;
+ for (i = 0; i < numBands; i++) {
+ FDKreadBits(bs, 8); /* drc_band_top[i] */
+ bitCnt += 8;
+ }
+ }
+
+ if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
+ FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
+ bitCnt += 8;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
+ bitCnt += 8;
+ }
+
+ if ((self->numPayloads < MAX_DRC_THREADS) &&
+ ((INT)FDKgetValidBits(bs) >= 0)) {
+ self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
+ }
+ } break;
+
+ case DVB_DRC_ANC_DATA:
+ bitCnt += 8;
+ /* check sync word */
+ if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
+ int dmxLevelsPresent, compressionPresent;
+ int coarseGrainTcPresent, fineGrainTcPresent;
+
+ /* bs_info field */
+ FDKreadBits(
+ bs,
+ 8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
+ bitCnt += 8;
+
+ /* Evaluate ancillary_data_status */
+ FDKreadBits(bs, 3); /* reserved, set to 0 */
+ dmxLevelsPresent =
+ FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
+ FDKreadBits(bs, 1); /* reserved, set to 0 */
+ compressionPresent =
+ FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
+ coarseGrainTcPresent =
+ FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
+ fineGrainTcPresent =
+ FDKreadBits(bs, 1); /* fine_grain_timecode_status */
+ bitCnt += 8;
+
+ /* MPEG4 downmixing levels */
+ if (dmxLevelsPresent) {
+ FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
+ bitCnt += 8;
+ }
+ /* audio coding mode and compression status */
+ if (compressionPresent) {
+ FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
+ bitCnt += 16;
+ }
+ /* coarse grain timecode */
+ if (coarseGrainTcPresent) {
+ FDKreadBits(bs, 16); /* coarse_grain_timecode */
+ bitCnt += 16;
+ }
+ /* fine grain timecode */
+ if (fineGrainTcPresent) {
+ FDKreadBits(bs, 16); /* fine_grain_timecode */
+ bitCnt += 16;
+ }
+ if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
+ self->dvbAncDataPosition = bsStartPos;
+ self->dvbAncDataAvailable = 1;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return (bitCnt);
+}
+
+/*!
+ \brief Parse DRC parameters from bitstream
+
+ \bs Handle of FDK bitstream (in)
+ \pDrcBs Pointer to DRC payload data container (out)
+ \payloadPosition Bitstream position of MPEG DRC data chunk (in)
+
+ \return Flag telling whether new DRC data has been found or not.
+*/
+static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs,
+ UINT payloadPosition) {
+ int i, numBands;
+
+ /* Move to the beginning of the DRC payload field */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
+
+ /* pce_tag_present */
+ if (FDKreadBits(bs, 1)) {
+ pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
+ /* only one program supported */
+ FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
+ } else {
+ pDrcBs->pceInstanceTag = -1; /* not present */
+ }
+
+ if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
+ /* get excluded_chn_mask */
+ parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
+ } else {
+ pDrcBs->excludedChnsMask = 0;
+ }
+
+ numBands = 1;
+ if (FDKreadBits(bs, 1)) /* drc_bands_present */
+ {
+ /* get band_incr */
+ numBands += FDKreadBits(bs, 4); /* drc_band_incr */
+ pDrcBs->channelData.drcInterpolationScheme =
+ FDKreadBits(bs, 4); /* drc_interpolation_scheme */
+ /* band_top */
+ for (i = 0; i < numBands; i++) {
+ pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
+ }
+ } else {
+ pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
+ 1; /* ... comprising the whole spectrum. */
+ ;
+ }
+
+ pDrcBs->channelData.numBands = numBands;
+
+ if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
+ {
+ pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
+ FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
+ } else {
+ pDrcBs->progRefLevel = -1;
+ }
+
+ for (i = 0; i < numBands; i++) {
+ pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
+ << 7; /* dyn_rng_sgn[i] */
+ pDrcBs->channelData.drcValue[i] |=
+ FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
+ }
+
+ /* Set DRC payload type */
+ pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
+
+ return (1);
+}
+
+/*!
+ \brief Parse heavy compression value transported in DSEs of DVB streams with
+ MPEG-4 content.
+
+ \bs Handle of FDK bitstream (in)
+ \pDrcBs Pointer to DRC payload data container (out)
+ \payloadPosition Bitstream position of DVB ancillary data chunk
+
+ \return Flag telling whether new DRC data has been found or not.
+*/
+#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */
+
+static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
+ CDrcPayload *pDrcBs,
+ UINT payloadPosition) {
+ int foundDrcData = 0;
+ int dmxLevelsPresent, compressionPresent;
+
+ /* Move to the beginning of the DRC payload field */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
+
+ /* Sanity checks */
+ if (FDKgetValidBits(bs) < 24) {
+ return 0;
+ }
+
+ /* Check sync word */
+ if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
+ return 0;
+ }
+
+ /* Evaluate bs_info field */
+ if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
+ /* No MPEG-4 audio data */
+ return 0;
+ }
+ FDKreadBits(bs, 2); /* dolby_surround_mode */
+ pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
+ FDKreadBits(bs, 1); /* stereo_downmix_mode */
+ if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */
+ return 0;
+ }
+
+ /* Evaluate ancillary_data_status */
+ if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
+ return 0;
+ }
+ dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
+ /*extensionPresent =*/FDKreadBits(bs,
+ 1); /* ancillary_data_extension_status; */
+ compressionPresent =
+ FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
+ /*coarseGrainTcPresent =*/FDKreadBits(bs,
+ 1); /* coarse_grain_timecode_status */
+ /*fineGrainTcPresent =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */
+
+ if (dmxLevelsPresent) {
+ FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
+ }
+
+ /* audio_coding_mode_and_compression_status */
+ if (compressionPresent) {
+ UCHAR compressionOn, compressionValue;
+
+ /* audio_coding_mode */
+ if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
+ return 0;
+ }
+ compressionOn = (UCHAR)FDKreadBits(bs, 1); /* compression_on */
+ compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */
+
+ if (compressionOn) {
+ /* A compression value is available so store the data just like MPEG DRC
+ * data */
+ pDrcBs->channelData.numBands = 1; /* One band ... */
+ pDrcBs->channelData.drcValue[0] =
+ compressionValue; /* ... with one value ... */
+ pDrcBs->channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT -
+ 1; /* ... comprising the whole spectrum. */
+ ;
+ pDrcBs->pceInstanceTag = -1; /* Not present */
+ pDrcBs->progRefLevel = -1; /* Not present */
+ pDrcBs->channelData.drcDataType =
+ DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
+ foundDrcData = 1;
+ }
+ }
+
+ return (foundDrcData);
+}
+
+/*
+ * Extract DRC payload from bitstream and map it to channels.
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+static int aacDecoder_drcExtractAndMap(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ CDrcPayload threadBs[MAX_DRC_THREADS];
+ CDrcPayload *validThreadBs[MAX_DRC_THREADS];
+ CDrcParams *pParams;
+ UINT backupBsPosition;
+ int result = 0;
+ int i, thread, validThreads = 0;
+
+ FDK_ASSERT(self != NULL);
+ FDK_ASSERT(hBs != NULL);
+ FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
+
+ pParams = &self->params;
+
+ self->numThreads = 0;
+ backupBsPosition = FDKgetValidBits(hBs);
+
+ for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
+ i++) {
+ /* Init payload data chunk. The memclear is very important because it
+ initializes the most values. Without it the module wouldn't work properly
+ or crash. */
+ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
+ threadBs[self->numThreads].channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+
+ /* Extract payload */
+ self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
+ self->drcPayloadPosition[i]);
+ }
+ self->numPayloads = 0;
+
+ if (self->dvbAncDataAvailable &&
+ self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression
+ payload thread if available. */
+
+ /* Init payload data chunk. The memclear is very important because it
+ initializes the most values. Without it the module wouldn't work properly
+ or crash. */
+ FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
+ threadBs[self->numThreads].channelData.bandTop[0] =
+ DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
+
+ /* Extract payload */
+ self->numThreads += aacDecoder_drcReadCompression(
+ hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
+ }
+ self->dvbAncDataAvailable = 0;
+
+ /* Reset the bitbufffer */
+ FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition);
+
+ /* calculate number of valid bits in excl_chn_mask */
+
+ /* coupling channels not supported */
+
+ /* check for valid threads */
+ for (thread = 0; thread < self->numThreads; thread++) {
+ CDrcPayload *pThreadBs = &threadBs[thread];
+ int numExclChns = 0;
+
+ switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
+ default:
+ continue;
+ case MPEG_DRC_EXT_DATA:
+ case DVB_DRC_ANC_DATA:
+ break;
+ }
+
+ if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
+ if (pThreadBs->pceInstanceTag != pceInstanceTag) {
+ continue; /* don't accept */
+ }
+ }
+
+ /* calculate number of excluded channels */
+ if (pThreadBs->excludedChnsMask > 0) {
+ INT exclMask = pThreadBs->excludedChnsMask;
+ int ch;
+ for (ch = 0; ch < validChannels; ch++) {
+ numExclChns += exclMask & 0x1;
+ exclMask >>= 1;
+ }
+ }
+ if (numExclChns < validChannels) {
+ validThreadBs[validThreads] = pThreadBs;
+ validThreads++;
+ }
+ }
+
+ /* map DRC bitstream information onto DRC channel information */
+ for (thread = 0; thread < validThreads; thread++) {
+ CDrcPayload *pThreadBs = validThreadBs[thread];
+ INT exclMask = pThreadBs->excludedChnsMask;
+ AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
+ (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
+ int ch;
+
+ /* last progRefLevel transmitted is the one that is used
+ * (but it should really only be transmitted once per block!)
+ */
+ if (pThreadBs->progRefLevel >= 0) {
+ self->progRefLevel = pThreadBs->progRefLevel;
+ self->progRefLevelPresent = 1;
+ self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
+ }
+
+ if (drcPayloadType == DVB_DRC_ANC_DATA) {
+ /* Announce the presentation mode of this valid thread. */
+ self->presMode = pThreadBs->presMode;
+ }
+
+ /* SCE, CPE and LFE */
+ for (ch = 0; ch < validChannels; ch++) {
+ AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
+ int mapedChannel = channelMapping[ch];
+
+ if ((mapedChannel >= validChannels) ||
+ ((exclMask & (1 << mapedChannel)) != 0))
+ continue;
+
+ if ((pParams->expiryFrame <= 0) ||
+ (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
+ pParams->expiryFrame)) {
+ prvPayloadType =
+ (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
+ ->drcData.drcDataType;
+ }
+ if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
+ (prvPayloadType != DVB_DRC_ANC_DATA)) ||
+ ((drcPayloadType == DVB_DRC_ANC_DATA) &&
+ (pParams->applyHeavyCompression ==
+ ON))) { /* copy thread to channel */
+ pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
+ result = 1;
+ }
+ }
+ /* CCEs not supported by now */
+ }
+
+ /* Increment and check expiry counter for the program reference level: */
+ if ((pParams->expiryFrame > 0) &&
+ (self->prlExpiryCount++ >
+ pParams->expiryFrame)) { /* The program reference level is too old, so
+ set it back to the target level. */
+ self->progRefLevelPresent = 0;
+ self->progRefLevel = pParams->targetRefLevel;
+ self->prlExpiryCount = 0;
+ }
+
+ return result;
+}
+
+void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CDrcChannelData *pDrcChData, FIXP_DBL *extGain,
+ int ch, /* needed only for SBR */
+ int aacFrameSize, int bSbrPresent) {
+ int band, bin, numBands;
+ int bottom = 0;
+ int modifyBins = 0;
+
+ FIXP_DBL max_mantissa;
+ INT max_exponent;
+
+ FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
+ INT norm_exponent = 1;
+
+ FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
+ INT fact_exponent[MAX_DRC_BANDS];
+
+ CDrcParams *pParams = &self->params;
+
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ int winSeq = pIcsInfo->WindowSequence;
+
+ /* Increment and check expiry counter */
+ if ((pParams->expiryFrame > 0) &&
+ (++pDrcChData->expiryCount >
+ pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */
+ aacDecoder_drcInitChannelData(pDrcChData);
+ }
+
+ if (self->enable != ON) {
+ sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
+ if (extGain != NULL) {
+ INT gainScale = (INT)*extGain;
+ /* The gain scaling must be passed to the function in the buffer pointed
+ * on by extGain. */
+ if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
+ *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
+ } else {
+ FDK_ASSERT(0);
+ }
+ }
+ return;
+ }
+
+ numBands = pDrcChData->numBands;
+
+ /* If program reference normalization is done in the digital domain,
+ modify factor to perform normalization. prog_ref_level can
+ alternatively be passed to the system for modification of the level in
+ the analog domain. Analog level modification avoids problems with
+ reduced DAC SNR (if signal is attenuated) or clipping (if signal is
+ boosted) */
+
+ if (pParams->targetRefLevel >= 0) {
+ /* 0.5^((targetRefLevel - progRefLevel)/24) */
+ norm_mantissa =
+ fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
+ 0,
+ (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
+ (INT)(pParams->targetRefLevel - self->progRefLevel)),
+ 3, &norm_exponent);
+ }
+ /* Always export the normalization gain (if possible). */
+ if (extGain != NULL) {
+ INT gainScale = (INT)*extGain;
+ /* The gain scaling must be passed to the function in the buffer pointed on
+ * by extGain. */
+ if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
+ *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
+ } else {
+ FDK_ASSERT(0);
+ }
+ }
+ if (self->params.applyDigitalNorm == OFF) {
+ /* Reset normalization gain since this module must not apply it */
+ norm_mantissa = FL2FXCONST_DBL(0.5f);
+ norm_exponent = 1;
+ }
+
+ /* calc scale factors */
+ for (band = 0; band < numBands; band++) {
+ UCHAR drcVal = pDrcChData->drcValue[band];
+
+ fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
+ fact_exponent[band] = 1;
+
+ if ((pParams->applyHeavyCompression == ON) &&
+ ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
+ DVB_DRC_ANC_DATA)) {
+ INT compressionFactorVal_e;
+ int valX, valY;
+
+ valX = drcVal >> 4;
+ valY = drcVal & 0x0F;
+
+ /* calculate the unscaled heavy compression factor.
+ compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
+ range: -48.166 dB to 48.164 dB */
+ if (drcVal != 0x7F) {
+ fact_mantissa[band] = fPowInt(
+ FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
+ 0, valY, &compressionFactorVal_e);
+
+ /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
+ fact_mantissa[band] =
+ fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);
+
+ fact_exponent[band] =
+ DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
+ }
+ } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
+ MPEG_DRC_EXT_DATA) {
+ /* apply the scaled dynamic range control words to factor.
+ * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
+ * then there is no dynamic range compression
+ *
+ * if pDrcChData->drcSgn[band] is
+ * 1 then gain is < 1 : factor = 2^(-self->cut *
+ * pDrcChData->drcMag[band] / 24) 0 then gain is > 1 : factor = 2^(
+ * self->boost * pDrcChData->drcMag[band] / 24)
+ */
+
+ if ((drcVal & 0x7F) > 0) {
+ FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;
+
+ fact_mantissa[band] = f2Pow(
+ (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
+ (drcVal & 0x7F)),
+ 3 + DRC_PARAM_SCALE, &fact_exponent[band]);
+ }
+ }
+
+ fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
+ fact_exponent[band] += norm_exponent;
+
+ } /* end loop over bands */
+
+ /* normalizations */
+ {
+ int res;
+
+ max_mantissa = FL2FXCONST_DBL(0.0f);
+ max_exponent = 0;
+ for (band = 0; band < numBands; band++) {
+ max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
+ max_exponent = fixMax(max_exponent, fact_exponent[band]);
+ }
+
+ /* left shift factors to gain accurancy */
+ res = CntLeadingZeros(max_mantissa) - 1;
+
+ /* above topmost DRC band gain factor is 1 */
+ if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
+ res = 0;
+
+ if (res > 0) {
+ res = fixMin(res, max_exponent);
+ max_exponent -= res;
+
+ for (band = 0; band < numBands; band++) {
+ fact_mantissa[band] <<= res;
+ fact_exponent[band] -= res;
+ }
+ }
+
+ /* normalize magnitudes to one scale factor */
+ for (band = 0; band < numBands; band++) {
+ if (fact_exponent[band] < max_exponent) {
+ fact_mantissa[band] >>= max_exponent - fact_exponent[band];
+ }
+ if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
+ modifyBins = 1;
+ }
+ }
+ if (max_exponent != 1) {
+ modifyBins = 1;
+ }
+ }
+
+ /* apply factor to spectral lines
+ * short blocks must take care that bands fall on
+ * block boundaries!
+ */
+ if (!bSbrPresent) {
+ bottom = 0;
+
+ if (!modifyBins) {
+ /* We don't have to modify the spectral bins because the fractional part
+ of all factors is 0.5. In order to keep accurancy we don't apply the
+ factor but decrease the exponent instead. */
+ max_exponent -= 1;
+ } else {
+ for (band = 0; band < numBands; band++) {
+ int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
+ aacFrameSize); /* ... * DRC_BAND_MULT; */
+
+ for (bin = bottom; bin < top; bin++) {
+ pSpectralCoefficient[bin] =
+ fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
+ }
+
+ bottom = top;
+ }
+ }
+
+ /* above topmost DRC band gain factor is 1 */
+ if (max_exponent > 0) {
+ for (bin = bottom; bin < aacFrameSize; bin += 1) {
+ pSpectralCoefficient[bin] >>= max_exponent;
+ }
+ }
+
+ /* adjust scaling */
+ pSpecScale[0] += max_exponent;
+
+ if (winSeq == BLOCK_SHORT) {
+ int win;
+ for (win = 1; win < 8; win++) {
+ pSpecScale[win] += max_exponent;
+ }
+ }
+ } else {
+ HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
+ numBands = pDrcChData->numBands;
+
+ /* feed factors into SBR decoder for application in QMF domain. */
+ sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
+ max_exponent, pDrcChData->drcInterpolationScheme,
+ winSeq, pDrcChData->bandTop);
+ }
+
+ return;
+}
+
+/*
+ * DRC parameter and presentation mode handling
+ */
+static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,
+ INT aacNumChannels,
+ SCHAR prevDrcProgRefLevel,
+ SCHAR prevDrcPresMode) {
+ int isDownmix, isMonoDownmix, isStereoDownmix;
+ int dDmx, dHr;
+ AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
+ CDrcParams *p;
+
+ FDK_ASSERT(self != NULL);
+
+ p = &self->params;
+
+ if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;
+
+ if (self->presMode != prevDrcPresMode) self->update = 1;
+
+ if (self->prevAacNumChannels != aacNumChannels) self->update = 1;
+
+ /* return if no relevant parameter has changed */
+ if (!self->update) {
+ return;
+ }
+
+ /* derive downmix property. aacNumChannels: number of channels in aac stream,
+ * numOutChannels: number of output channels */
+ isDownmix = (aacNumChannels > self->numOutChannels);
+ isDownmix = (isDownmix && (self->numOutChannels > 0));
+ isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
+ isStereoDownmix = (isDownmix && (self->numOutChannels == 2));
+
+ if ((self->presMode == 1) || (self->presMode == 2)) {
+ drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
+ } else { /* no presentation mode -> use parameter handling specified by
+ AAC_DRC_DEFAULT_PRESENTATION_MODE */
+ drcParameterHandling = p->defaultPresentationMode;
+ }
+
+ /* by default, do as desired */
+ p->cut = p->usrCut;
+ p->boost = p->usrBoost;
+ p->applyHeavyCompression = p->usrApplyHeavyCompression;
+
+ switch (drcParameterHandling) {
+ case DISABLED_PARAMETER_HANDLING:
+ default:
+ /* use drc parameters as requested */
+ break;
+
+ case ENABLED_PARAMETER_HANDLING:
+ /* dDmx: estimated headroom reduction due to downmix, format: -1/4*dB
+ dDmx = floor(-4*20*log10(aacNumChannels/numOutChannels)) */
+ if (isDownmix) {
+ FIXP_DBL dmxTmp;
+ int e_log, e_mult;
+ dmxTmp = fDivNorm(self->numOutChannels,
+ aacNumChannels); /* inverse division ->
+ negative sign after
+ logarithm */
+ dmxTmp = fLog2(dmxTmp, 0, &e_log);
+ dmxTmp = fMultNorm(
+ dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)),
+ &e_mult); /* e = e_log + e_mult + 5 */
+ dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1));
+ } else {
+ dDmx = 0;
+ }
+
+ /* dHr: Full estimated (decoder) headroom reduction due to loudness
+ * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */
+ if (p->targetRefLevel >= 0) { /* if target level is provided */
+ dHr = p->targetRefLevel + dDmx - self->progRefLevel;
+ } else {
+ dHr = dDmx;
+ }
+
+ if (dHr < 0) { /* if headroom is reduced */
+ /* Use compression, but as little as possible. */
+ /* eHr: Headroom provided by encoder, format: -1/4 dB */
+ int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0);
+ if (eHr <
+ dHr) { /* if encoder provides more headroom than decoder needs */
+ /* derive scaling of light DRC */
+ FIXP_DBL calcFactor_norm;
+ INT calcFactor; /* fraction of DRC gains that is minimally needed for
+ clipping prevention */
+ calcFactor_norm =
+ fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */
+ calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE;
+ /* quantize to 128 steps */
+ calcFactor = convert_drcParam(
+ calcFactor_norm); /* convert to integer value between 0 and 127 */
+ calcFactor_norm = (FIXP_DBL)(
+ (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor);
+ p->cut = (calcFactor_norm > p->cut)
+ ? calcFactor_norm
+ : p->cut; /* use calcFactor_norm as lower limit */
+ } else {
+ /* encoder provides equal or less headroom than decoder needs */
+ /* the time domain limiter must always be active in this case. It is
+ * assumed that the framework activates it by default */
+ p->cut = DRC_SCALING_MAX;
+ if ((dHr - eHr) <=
+ -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if
+ headroom deficit is equal or
+ higher than
+ DRC_HEAVY_THRESHOLD_DB */
+ p->applyHeavyCompression = ON;
+ }
+ }
+ } else { /* dHr >= 0 */
+ /* no restrictions required, as headroom is not reduced. */
+ /* p->cut = p->usrCut; */
+ }
+ break;
+
+ /* presentation mode 1 and 2 according to ETSI TS 101 154:
+ Digital Video Broadcasting (DVB); Specification for the use of Video
+ and Audio Coding in Broadcasting Applications based on the MPEG-2
+ Transport Stream, section C.5.4., "Decoding", and Table C.33. Also
+ according to amendment 4 to ISO/IEC 14496-3, section 4.5.2.14.2.4, and
+ Table AMD4.11. ISO DRC -> applyHeavyCompression = OFF (Use
+ light compression, MPEG-style) Compression_value ->
+ applyHeavyCompression = ON (Use heavy compression, DVB-style) scaling
+ restricted -> p->cut = DRC_SCALING_MAX */
+
+ case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
+ if ((p->targetRefLevel >= 0) &&
+ (p->targetRefLevel <
+ 124)) { /* if target level is provided and > -31 dB */
+ /* playback up to -23 dB */
+ p->applyHeavyCompression = ON;
+ } else { /* target level <= -31 dB or not provided */
+ /* playback -31 dB */
+ if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
+ p->cut = DRC_SCALING_MAX;
+ }
+ }
+ break;
+
+ case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
+ if ((p->targetRefLevel >= 0) &&
+ (p->targetRefLevel <
+ 124)) { /* if target level is provided and > -31 dB */
+ /* playback up to -23 dB */
+ if (isMonoDownmix) { /* if mono downmix */
+ p->applyHeavyCompression = ON;
+ } else {
+ p->applyHeavyCompression = OFF;
+ p->cut = DRC_SCALING_MAX;
+ }
+ } else { /* target level <= -31 dB or not provided */
+ /* playback -31 dB */
+ p->applyHeavyCompression = OFF;
+ if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
+ p->cut = DRC_SCALING_MAX;
+ }
+ }
+ break;
+ } /* switch (drcParameterHandling) */
+
+ /* With heavy compression, there is no scaling.
+ Scaling factors are set for notification only. */
+ if (p->applyHeavyCompression == ON) {
+ p->boost = DRC_SCALING_MAX;
+ p->cut = DRC_SCALING_MAX;
+ }
+
+ /* switch on/off processing */
+ self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
+ (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
+ self->enable = (self->enable && !self->uniDrcPrecedence);
+
+ self->prevAacNumChannels = aacNumChannels;
+ self->update = 0;
+}
+
+/*
+ * Prepare DRC processing
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+int aacDecoder_drcProlog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ int result = 0;
+
+ if (self == NULL) {
+ return -1;
+ }
+
+ if (!self->params.bsDelayEnable) {
+ /* keep previous progRefLevel and presMode for update flag in
+ * drcParameterHandling */
+ INT prevPRL, prevPM = 0;
+ prevPRL = self->progRefLevel;
+ prevPM = self->presMode;
+
+ result = aacDecoder_drcExtractAndMap(
+ self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
+ validChannels);
+
+ if (result < 0) {
+ return result;
+ }
+
+ /* Drc parameter handling */
+ aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
+ }
+
+ return result;
+}
+
+/*
+ * Finalize DRC processing
+ * Valid return values are:
+ * -1 : An unexpected error occured.
+ * 0 : No error and no valid DRC data available.
+ * 1 : No error and valid DRC data has been mapped.
+ */
+int aacDecoder_drcEpilog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag,
+ UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
+ canonical channel index */
+ int validChannels) {
+ int result = 0;
+
+ if (self == NULL) {
+ return -1;
+ }
+
+ if (self->params.bsDelayEnable) {
+ /* keep previous progRefLevel and presMode for update flag in
+ * drcParameterHandling */
+ INT prevPRL, prevPM = 0;
+ prevPRL = self->progRefLevel;
+ prevPM = self->presMode;
+
+ result = aacDecoder_drcExtractAndMap(
+ self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
+ validChannels);
+
+ if (result < 0) {
+ return result;
+ }
+
+ /* Drc parameter handling */
+ aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
+ }
+
+ return result;
+}
+
+/*
+ * Export relevant metadata info from bitstream payload.
+ */
+void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
+ SCHAR *pProgRefLevel) {
+ if (self != NULL) {
+ if (pPresMode != NULL) {
+ *pPresMode = self->presMode;
+ }
+ if (pProgRefLevel != NULL) {
+ if (self->progRefLevelPresent) {
+ *pProgRefLevel = self->progRefLevel;
+ } else {
+ *pProgRefLevel = -1;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_drc.h b/fdk-aac/libAACdec/src/aacdec_drc.h
new file mode 100644
index 0000000..924ec6f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc.h
@@ -0,0 +1,192 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) decoder tool for AAC
+
+*******************************************************************************/
+
+#ifndef AACDEC_DRC_H
+#define AACDEC_DRC_H
+
+#include "tp_data.h" /* for program config element support */
+
+#include "aacdec_drc_types.h"
+#include "channel.h"
+#include "FDK_bitstream.h"
+
+#define AACDEC_DRC_DFLT_EXPIRY_FRAMES \
+ (0) /* Default DRC data expiry time in AAC frames */
+
+/* #define AACDEC_DRC_IGNORE_FRAMES_WITH_MULTIPLE_CH_THREADS */ /* The name says
+ it all. */
+/* #define AACDEC_DRC_DEBUG */
+
+/**
+ * \brief DRC module setting parameters
+ */
+typedef enum {
+ DRC_CUT_SCALE = 0,
+ DRC_BOOST_SCALE,
+ TARGET_REF_LEVEL,
+ DRC_BS_DELAY,
+ DRC_DATA_EXPIRY_FRAME,
+ APPLY_NORMALIZATION,
+ APPLY_HEAVY_COMPRESSION,
+ DEFAULT_PRESENTATION_MODE,
+ ENCODER_TARGET_LEVEL,
+ MAX_OUTPUT_CHANNELS,
+ UNIDRC_PRECEDENCE
+} AACDEC_DRC_PARAM;
+
+/**
+ * \brief DRC module interface functions
+ */
+void aacDecoder_drcInit(HANDLE_AAC_DRC self);
+
+void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChannel);
+
+AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
+ AACDEC_DRC_PARAM param, INT value);
+
+int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ AACDEC_DRC_PAYLOAD_TYPE type);
+
+int aacDecoder_drcProlog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag, UCHAR channelMapping[], int validChannels);
+
+/**
+ * \brief Apply DRC. If SBR is present, DRC data is handed over to the SBR
+ * decoder.
+ * \param self AAC decoder instance
+ * \param pSbrDec pointer to SBR decoder instance
+ * \param pAacDecoderChannelInfo AAC decoder channel instance to be processed
+ * \param pDrcDat DRC channel data
+ * \param extGain Pointer to a FIXP_DBL where a externally applyable gain will
+ * be stored into (independently on whether it will be apply internally or not).
+ * At function call the buffer must hold the scale (0 >= scale <
+ * DFRACT_BITS) to be applied on the gain value.
+ * \param ch channel index
+ * \param aacFrameSize AAC frame size
+ * \param bSbrPresent flag indicating that SBR is present, in which case DRC is
+ * handed over to the SBR instance pSbrDec
+ */
+void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CDrcChannelData *pDrcDat, FIXP_DBL *extGain, int ch,
+ int aacFrameSize, int bSbrPresent);
+
+int aacDecoder_drcEpilog(
+ HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ UCHAR pceInstanceTag, UCHAR channelMapping[], int validChannels);
+
+/**
+ * \brief Get metadata information found in bitstream.
+ * \param self DRC module instance handle.
+ * \param pPresMode Pointer to field where the presentation mode will be written
+ * to.
+ * \param pProgRefLevel Pointer to field where the program reference level will
+ * be written to.
+ * \return Nothing.
+ */
+void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
+ SCHAR *pProgRefLevel);
+
+#endif /* AACDEC_DRC_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_drc_types.h b/fdk-aac/libAACdec/src/aacdec_drc_types.h
new file mode 100644
index 0000000..76c35d0
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_drc_types.h
@@ -0,0 +1,220 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Dynamic range control (DRC) global data types
+
+*******************************************************************************/
+
+#ifndef AACDEC_DRC_TYPES_H
+#define AACDEC_DRC_TYPES_H
+
+#include "common_fix.h"
+
+#define MAX_DRC_THREADS \
+ ((8) + 1) /* Heavy compression value is handled just like MPEG DRC data */
+#define MAX_DRC_BANDS (16) /* 2^LEN_DRC_BAND_INCR (LEN_DRC_BAND_INCR = 4) */
+
+/**
+ * \brief DRC module global data types
+ */
+typedef enum {
+ UNKNOWN_PAYLOAD = 0,
+ MPEG_DRC_EXT_DATA = 1,
+ DVB_DRC_ANC_DATA = 2
+
+} AACDEC_DRC_PAYLOAD_TYPE;
+
+/**
+ * \brief Options for parameter handling / presentation mode
+ */
+typedef enum {
+ DISABLED_PARAMETER_HANDLING = -1, /*!< DRC parameter handling disabled, all
+ parameters are applied as requested. */
+ ENABLED_PARAMETER_HANDLING =
+ 0, /*!< Apply changes to requested DRC parameters to prevent clipping */
+ DRC_PRESENTATION_MODE_1 = 1, /*!< DRC Presentation mode 1*/
+ DRC_PRESENTATION_MODE_2 = 2 /*!< DRC Presentation mode 2*/
+
+} AACDEC_DRC_PARAMETER_HANDLING;
+
+typedef struct {
+ UINT expiryCount;
+ UINT numBands;
+ USHORT bandTop[MAX_DRC_BANDS];
+ SHORT drcInterpolationScheme;
+ UCHAR drcValue[MAX_DRC_BANDS];
+ SCHAR drcDataType;
+
+} CDrcChannelData;
+
+typedef struct {
+ UINT excludedChnsMask;
+ SCHAR progRefLevel;
+ SCHAR presMode; /* Presentation mode: 0 (not indicated), 1, 2, and 3
+ (reserved). */
+ SCHAR pceInstanceTag;
+
+ CDrcChannelData channelData;
+
+} CDrcPayload;
+
+typedef struct {
+ /* DRC parameters: Latest user requests */
+ FIXP_DBL usrCut;
+ FIXP_DBL usrBoost;
+ UCHAR usrApplyHeavyCompression;
+
+ /* DRC parameters: Currently used, possibly changed by
+ * aacDecoder_drcParameterHandling */
+ FIXP_DBL cut; /* attenuation scale factor */
+ FIXP_DBL boost; /* boost scale factor */
+ SCHAR targetRefLevel; /* target reference level for loudness normalization */
+ UCHAR applyHeavyCompression; /* heavy compression (DVB) flag */
+
+ UINT expiryFrame;
+ UCHAR bsDelayEnable;
+ UCHAR applyDigitalNorm;
+
+ AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode;
+ UCHAR encoderTargetLevel;
+
+} CDrcParams;
+
+typedef struct {
+ CDrcParams
+ params; /* Module parameters that can be set by user (via SetParam API
+ function) */
+
+ UCHAR enable; /* Switch that controls dynamic range processing */
+ UCHAR digitalNorm; /* Switch to en-/disable reference level normalization in
+ digital domain */
+
+ UCHAR update; /* Flag indicating the change of a user or bitstream parameter
+ which affects aacDecoder_drcParameterHandling */
+ INT numOutChannels; /* Number of output channels */
+ INT prevAacNumChannels; /* Previous number of channels of aac bitstream, used
+ for update flag */
+
+ USHORT numPayloads; /* The number of DRC data payload elements found within
+ frame */
+ USHORT
+ numThreads; /* The number of DRC data threads extracted from the found
+ payload elements */
+ SCHAR progRefLevel; /* Program reference level for all channels */
+ UCHAR progRefLevelPresent; /* Program reference level found in bitstream */
+
+ UINT prlExpiryCount; /* Counter that can be used to monitor the life time of
+ the program reference level. */
+
+ SCHAR presMode; /* Presentation mode as defined in ETSI TS 101 154 */
+ UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data
+ is present or not */
+ UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload
+ position in the bitstream (only one per frame) */
+ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload
+ positions in the bitstream */
+
+ UCHAR
+ uniDrcPrecedence; /* Flag for signalling that uniDrc is active and takes
+ precedence over legacy DRC */
+
+} CDrcInfo;
+
+typedef CDrcInfo *HANDLE_AAC_DRC;
+
+#endif /* AACDEC_DRC_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr.cpp b/fdk-aac/libAACdec/src/aacdec_hcr.cpp
new file mode 100644
index 0000000..6114756
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr.cpp
@@ -0,0 +1,1498 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo,
+ decode priority codewords (PCWs)
+
+*******************************************************************************/
+
+#include "aacdec_hcr.h"
+
+#include "aacdec_hcr_types.h"
+#include "aacdec_hcr_bit.h"
+#include "aacdec_hcrs.h"
+#include "aac_ram.h"
+#include "aac_rom.h"
+#include "channel.h"
+#include "block.h"
+
+#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */
+#include "FDK_bitstream.h"
+
+extern int mlFileChCurr;
+
+static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
+ UINT *errorWord);
+
+static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
+ SHORT lengthOfReorderedSpectralData,
+ UINT *errorWord);
+
+static void HcrCalcNumCodeword(H_HCR_INFO pHcr);
+static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr);
+static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr);
+static void HcrExtendedSectionInfo(H_HCR_INFO pHcr);
+
+static void DeriveNumberOfExtendedSortedSectionsInSets(
+ UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
+ int numExtendedSortedCodewordInSectionIdx,
+ USHORT *pNumExtendedSortedSectionsInSets,
+ int numExtendedSortedSectionsInSetsIdx);
+
+static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT quantSpecCoef, INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits);
+
+static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ UINT codebookDim, const SCHAR *pQuantVal,
+ FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits);
+
+static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ const UINT *pCurrentTree,
+ const SCHAR *pQuantValBase,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits);
+
+static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr);
+
+static void HcrReorderQuantizedSpectralCoefficients(
+ H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo);
+
+static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
+ H_HCR_INFO pHcr, PCW_TYPE kind,
+ FIXP_DBL *qsc_base_of_cw,
+ UCHAR dimension);
+
+static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr);
+
+/*---------------------------------------------------------------------------------------------
+ description: Check if codebook and numSect are within allowed range
+(short only)
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
+ UINT *errorWord) {
+ if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
+ *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+ if (numLine < 0 || numLine > 1024) {
+ *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Check both HCR lengths
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
+ SHORT lengthOfReorderedSpectralData,
+ UINT *errorWord) {
+ if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) {
+ *errorWord |= HCR_SI_LENGTHS_FAILURE;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode (and adapt if necessary) the two HCR sideinfo
+components: 'reordered_spectral_data_length' and 'longest_codeword_length'
+--------------------------------------------------------------------------------------------
+*/
+
+void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const MP4_ELEMENT_ID globalHcrType) {
+ SHORT lengOfReorderedSpectralData;
+ SCHAR lengOfLongestCodeword;
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData =
+ 0;
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0;
+
+ /* ------- SI-Value No 1 ------- */
+ lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD;
+ if (globalHcrType == ID_CPE) {
+ if ((lengOfReorderedSpectralData >= 0) &&
+ (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ lengOfReorderedSpectralData; /* the decoded value is within range */
+ } else {
+ if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ CPE_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+ } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE ||
+ globalHcrType == ID_CCE) {
+ if ((lengOfReorderedSpectralData >= 0) &&
+ (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ lengOfReorderedSpectralData; /* the decoded value is within range */
+ } else {
+ if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData =
+ SCE_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+ }
+
+ /* ------- SI-Value No 2 ------- */
+ lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC;
+ if ((lengOfLongestCodeword >= 0) &&
+ (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
+ lengOfLongestCodeword; /* the decoded value is within range */
+ } else {
+ if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) {
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
+ LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Set up HCR - must be called before every call to
+HcrDecoder(). For short block a sorting algorithm is applied to get the SI in
+the order that HCR could assemble the qsc's as if it is a long block.
+-----------------------------------------------------------------------------------------------
+ return: error log
+--------------------------------------------------------------------------------------------
+*/
+
+UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pNumLinesInSec;
+ UCHAR *pCodeBk;
+ SHORT numSection;
+ SCHAR cb;
+ int numLine;
+ int i;
+
+ pHcr->decInOut.lengthOfReorderedSpectralData =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData;
+ pHcr->decInOut.lengthOfLongestCodeword =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword;
+ pHcr->decInOut.pQuantizedSpectralCoefficientsBase =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0;
+ pHcr->decInOut.pCodebook =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
+ pHcr->decInOut.pNumLineInSect =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
+ pHcr->decInOut.numSection =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection;
+ pHcr->decInOut.errorLog = 0;
+ pHcr->nonPcwSideinfo.pResultBase =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+
+ FDKsyncCache(bs);
+ pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs);
+
+ if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */
+ {
+ SHORT band;
+ SHORT maxBand;
+ SCHAR group;
+ SCHAR winGroupLen;
+ SCHAR window;
+ SCHAR numUnitInBand;
+ SCHAR cntUnitInBand;
+ SCHAR groupWin;
+ SCHAR cb_prev;
+
+ UCHAR *pCodeBook;
+ const SHORT *BandOffsets;
+ SCHAR numOfGroups;
+
+ pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */
+ pNumLinesInSec = pHcr->decInOut.pNumLineInSect; /* out */
+ pCodeBk = pHcr->decInOut.pCodebook; /* out */
+ BandOffsets =
+ GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */
+ numOfGroups = GetWindowGroups(pIcsInfo);
+
+ numLine = 0;
+ numSection = 0;
+ cb = pCodeBook[0];
+ cb_prev = pCodeBook[0];
+
+ /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new
+ * section starts */
+
+ *pCodeBk++ = cb_prev;
+
+ maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (band = 0; band < maxBand;
+ band++) { /* from low to high sfbs i.e. from low to high frequencies */
+ numUnitInBand =
+ ((BandOffsets[band + 1] - BandOffsets[band]) >>
+ FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */
+ for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0;
+ cntUnitInBand--) { /* for every unit in the band */
+ for (window = 0, group = 0; group < numOfGroups; group++) {
+ winGroupLen = (SCHAR)GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) {
+ cb = pCodeBook[group * 16 + band];
+ if (cb != cb_prev) {
+ errDetectorInHcrSideinfoShrt(cb, numLine,
+ &pHcr->decInOut.errorLog);
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+ *pCodeBk++ = cb;
+ *pNumLinesInSec++ = numLine;
+ numSection++;
+
+ cb_prev = cb;
+ numLine = LINES_PER_UNIT;
+ } else {
+ numLine += LINES_PER_UNIT;
+ }
+ }
+ }
+ }
+ }
+
+ numSection++;
+
+ errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog);
+ if (numSection <= 0 || numSection > 1024 / 2) {
+ pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK;
+ }
+ errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
+ pHcr->decInOut.lengthOfReorderedSpectralData,
+ &pHcr->decInOut.errorLog);
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+
+ *pCodeBk = cb;
+ *pNumLinesInSec = numLine;
+ pHcr->decInOut.numSection = numSection;
+
+ } else /* end short block prepare SI */
+ { /* long block */
+ errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
+ pHcr->decInOut.lengthOfReorderedSpectralData,
+ &pHcr->decInOut.errorLog);
+ numSection = pHcr->decInOut.numSection;
+ pNumLinesInSec = pHcr->decInOut.pNumLineInSect;
+ pCodeBk = pHcr->decInOut.pCodebook;
+ if (numSection <= 0 || numSection > 64) {
+ pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK;
+ numSection = 0;
+ }
+
+ for (i = numSection; i != 0; i--) {
+ cb = *pCodeBk++;
+
+ if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
+ pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK;
+ }
+
+ numLine = *pNumLinesInSec++;
+ /* FDK_ASSERT(numLine > 0); */
+
+ if ((numLine <= 0) || (numLine > 1024)) {
+ pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK;
+ }
+ }
+ if (pHcr->decInOut.errorLog != 0) {
+ return (pHcr->decInOut.errorLog);
+ }
+ }
+
+ pCodeBk = pHcr->decInOut.pCodebook;
+ for (i = 0; i < numSection; i++) {
+ if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) ||
+ (*pCodeBk == INTENSITY_HCB)) {
+ *pCodeBk = 0;
+ }
+ pCodeBk++;
+ }
+
+ /* HCR-sideinfo-input is complete and seems to be valid */
+
+ return (pHcr->decInOut.errorLog);
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes the codewords of the spectral
+coefficients from the bitstream according to the HCR algorithm and stores the
+quantized spectral coefficients in correct order in the output buffer.
+--------------------------------------------------------------------------------------------
+*/
+
+UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ int pTmp1, pTmp2, pTmp3, pTmp4;
+ int pTmp5;
+
+ INT bitCntOffst;
+ INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */
+
+ HcrCalcNumCodeword(pHcr);
+
+ HcrSortCodebookAndNumCodewordInSection(pHcr);
+
+ HcrPrepareSegmentationGrid(pHcr);
+
+ HcrExtendedSectionInfo(pHcr);
+
+ if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) {
+ return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return
+ from HCR without having decoded
+ anything */
+ }
+
+ DeriveNumberOfExtendedSortedSectionsInSets(
+ pHcr->segmentInfo.numSegment,
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection,
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx,
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets,
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx);
+
+ /* store */
+ pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
+
+ /* ------- decode meaningful PCWs ------ */
+ DecodePCWs(bs, pHcr);
+
+ if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) {
+ /* ------ decode the non-PCWs -------- */
+ DecodeNonPCWs(bs, pHcr);
+ }
+
+ errDetectWithinSegmentationFinal(pHcr);
+
+ /* restore */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4;
+ pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5;
+
+ HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo,
+ pSamplingRateInfo);
+
+ /* restore bitstream position */
+ bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
+ if (bitCntOffst) {
+ FDKpushBiDirectional(bs, bitCntOffst);
+ }
+
+ return (pHcr->decInOut.errorLog);
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function reorders the quantized spectral coefficients
+sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute
+Value of the current codebook) -- a counter is incremented if there is an error
+ detected.
+ Additional for short-blocks a unit-based-deinterleaving is
+applied. Moreover (for short blocks) the scaling is derived (compare plain
+huffman decoder).
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrReorderQuantizedSpectralCoefficients(
+ H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo) {
+ INT qsc;
+ UINT abs_qsc;
+ UINT i, j;
+ USHORT numSpectralValuesInSection;
+ FIXP_DBL *pTeVa;
+ USHORT lavErrorCnt = 0;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ SPECTRAL_PTR pQuantizedSpectralCoefficientsBase =
+ pHcr->decInOut.pQuantizedSpectralCoefficientsBase;
+ FIXP_DBL *pQuantizedSpectralCoefficients =
+ SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+ const UCHAR *pCbDimShift = aDimCbShift;
+ const USHORT *pLargestAbsVal = aLargestAbsoluteValue;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
+ FIXP_DBL pTempValues[1024];
+ FIXP_DBL *pBak = pTempValues;
+
+ FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL));
+
+ /* long and short: check if decoded huffman-values (quantized spectral
+ * coefficients) are within range */
+ for (i = numSection; i != 0; i--) {
+ numSpectralValuesInSection = *pNumSortedCodewordInSection++
+ << pCbDimShift[*pSortedCodebook];
+ pTeVa = &pTempValues[*pReorderOffset++];
+ for (j = numSpectralValuesInSection; j != 0; j--) {
+ qsc = *pQuantizedSpectralCoefficients++;
+ abs_qsc = fAbs(qsc);
+ if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) {
+ *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */
+ } else { /* line is too high .. */
+ if (abs_qsc ==
+ Q_VALUE_INVALID) { /* .. because of previous marking --> dont set
+ LAV flag (would be confusing), just copy out
+ the already marked value */
+ *pTeVa++ = (FIXP_DBL)qsc;
+ } else { /* .. because a too high value was decoded for this cb --> set
+ LAV flag */
+ *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID;
+ lavErrorCnt += 1;
+ }
+ }
+ }
+ pSortedCodebook++;
+ }
+
+ if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ FIXP_DBL *pOut;
+ FIXP_DBL locMax;
+ FIXP_DBL tmp;
+ SCHAR groupoffset;
+ SCHAR group;
+ SCHAR band;
+ SCHAR groupwin;
+ SCHAR window;
+ SCHAR numWinGroup;
+ SHORT interm;
+ SCHAR numSfbTransm;
+ SCHAR winGroupLen;
+ SHORT index;
+ INT msb;
+ INT lsb;
+
+ SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ const SHORT *BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ pBak = pTempValues;
+ /* deinterleave unitwise for short blocks */
+ for (window = 0; window < (8); window++) {
+ pOut = SPEC(pQuantizedSpectralCoefficientsBase, window,
+ pAacDecoderChannelInfo->granuleLength);
+ for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
+ pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) +
+ i * 32; /* distance of lines between unit groups has to be
+ constant for every framelength (32)! */
+ for (j = (LINES_PER_UNIT); j != 0; j--) {
+ *pOut++ = *pTeVa++;
+ }
+ }
+ }
+
+ /* short blocks only */
+ /* derive global scaling-value for every sfb and every window (as it is done
+ * in plain-huffman-decoder at short blocks) */
+ groupoffset = 0;
+
+ numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ numSfbTransm =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+
+ for (group = 0; group < numWinGroup; group++) {
+ winGroupLen =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ for (band = 0; band < numSfbTransm; band++) {
+ interm = group * 16 + band;
+ msb = pScaleFacHcr[interm] >> 2;
+ lsb = pScaleFacHcr[interm] & 3;
+ for (groupwin = 0; groupwin < winGroupLen; groupwin++) {
+ window = groupoffset + groupwin;
+ pBak = SPEC(pQuantizedSpectralCoefficientsBase, window,
+ pAacDecoderChannelInfo->granuleLength);
+ locMax = FL2FXCONST_DBL(0.0f);
+ for (index = BandOffsets[band]; index < BandOffsets[band + 1];
+ index += LINES_PER_UNIT) {
+ pTeVa = &pBak[index];
+ for (i = LINES_PER_UNIT; i != 0; i--) {
+ tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++;
+ locMax = fixMax(tmp, locMax);
+ }
+ }
+ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
+ locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE;
+ }
+ pSfbSclHcr[window * 16 + band] =
+ msb - GetScaleFromValue(
+ locMax, lsb); /* save global scale maxima in this sfb */
+ }
+ }
+ groupoffset +=
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ }
+ } else {
+ /* copy straight for long-blocks */
+ pQuantizedSpectralCoefficients =
+ SPEC_LONG(pQuantizedSpectralCoefficientsBase);
+ for (i = 1024; i != 0; i--) {
+ *pQuantizedSpectralCoefficients++ = *pBak++;
+ }
+ }
+
+ if (lavErrorCnt != 0) {
+ pHcr->decInOut.errorLog |= LAV_VIOLATION;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number of codewords
+ for each section (numCodewordInSection) and the number of
+codewords for all sections (numCodeword). For zero and intensity codebooks a
+entry is also done in the variable numCodewordInSection. It is assumed that the
+codebook is a two tuples codebook. This is needed later for the calculation of
+the base addresses for the reordering of the quantize spectral coefficients at
+the end of the hcr tool. The variable numCodeword contain the number of
+codewords which are really in the bitstream. Zero or intensity codebooks does
+not increase the variable numCodewords.
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrCalcNumCodeword(H_HCR_INFO pHcr) {
+ int hcrSection;
+ UINT numCodeword;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ UCHAR *pCodebook = pHcr->decInOut.pCodebook;
+ SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect;
+ const UCHAR *pCbDimShift = aDimCbShift;
+
+ USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
+
+ numCodeword = 0;
+ for (hcrSection = numSection; hcrSection != 0; hcrSection--) {
+ *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook];
+ if (*pCodebook != 0) {
+ numCodeword += *pNumCodewordInSection;
+ }
+ pNumCodewordInSection++;
+ pCodebook++;
+ }
+ pHcr->sectionInfo.numCodeword = numCodeword;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number
+ of sorted codebooks and sorts the codebooks and the
+numCodewordInSection according to the priority.
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) {
+ UINT i, j, k;
+ UCHAR temp;
+ UINT counter;
+ UINT startOffset;
+ UINT numZeroSection;
+ UCHAR *pDest;
+ UINT numSectionDec;
+
+ UINT numSection = pHcr->decInOut.numSection;
+ UCHAR *pCodebook = pHcr->decInOut.pCodebook;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
+ USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
+ const UCHAR *pCbPriority = aCbPriority;
+ const UCHAR *pMinOfCbPair = aMinOfCbPair;
+ const UCHAR *pMaxOfCbPair = aMaxOfCbPair;
+ const UCHAR *pCbDimShift = aDimCbShift;
+
+ UINT searchStart = 0;
+
+ /* calculate *pNumSortedSection and store the priorities in array
+ * pSortedCdebook */
+ pDest = pSortedCodebook;
+ numZeroSection = 0;
+ for (i = numSection; i != 0; i--) {
+ if (pCbPriority[*pCodebook] == 0) {
+ numZeroSection += 1;
+ }
+ *pDest++ = pCbPriority[*pCodebook++];
+ }
+ pHcr->sectionInfo.numSortedSection =
+ numSection - numZeroSection; /* numSortedSection contains no zero or
+ intensity section */
+ pCodebook = pHcr->decInOut.pCodebook;
+
+ /* sort priorities of the codebooks in array pSortedCdebook[] */
+ numSectionDec = numSection - 1;
+ if (numSectionDec > 0) {
+ counter = numSectionDec;
+ for (j = numSectionDec; j != 0; j--) {
+ for (i = 0; i < counter; i++) {
+ /* swap priorities */
+ if (pSortedCodebook[i + 1] > pSortedCodebook[i]) {
+ temp = pSortedCodebook[i];
+ pSortedCodebook[i] = pSortedCodebook[i + 1];
+ pSortedCodebook[i + 1] = temp;
+ }
+ }
+ counter -= 1;
+ }
+ }
+
+ /* clear codebookSwitch array */
+ for (i = numSection; i != 0; i--) {
+ *pCodebookSwitch++ = 0;
+ }
+ pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
+
+ /* sort sectionCodebooks and numCodwordsInSection and calculate
+ * pReorderOffst[j] */
+ for (j = 0; j < numSection; j++) {
+ for (i = searchStart; i < numSection; i++) {
+ if (pCodebookSwitch[i] == 0 &&
+ (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] ||
+ pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) {
+ pCodebookSwitch[i] = 1;
+ pSortedCodebook[j] = pCodebook[i]; /* sort codebook */
+ pNumSortedCodewordInSection[j] =
+ pNumCodewordInSection[i]; /* sort NumCodewordInSection */
+
+ startOffset = 0;
+ for (k = 0; k < i; k++) { /* make entry in pReorderOffst */
+ startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]];
+ }
+ pReorderOffset[j] =
+ startOffset; /* offset for reordering the codewords */
+
+ if (i == searchStart) {
+ k = i;
+ while (pCodebookSwitch[k++] == 1) searchStart++;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the segmentation, which includes
+numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment.
+ The segmentation could be visualized a as kind of
+'overlay-grid' for the bitstream-block holding the HCR-encoded
+quantized-spectral-coefficients.
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) {
+ USHORT i, j;
+ USHORT numSegment = 0;
+ INT segmentStart = 0;
+ UCHAR segmentWidth;
+ UCHAR lastSegmentWidth;
+ UCHAR sortedCodebook;
+ UCHAR endFlag = 0;
+ INT intermediateResult;
+
+ SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
+ SHORT lengthOfReorderedSpectralData =
+ pHcr->decInOut.lengthOfReorderedSpectralData;
+ UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ const UCHAR *pMaxCwLength = aMaxCwLen;
+
+ for (i = numSortedSection; i != 0; i--) {
+ sortedCodebook = *pSortedCodebook++;
+ segmentWidth =
+ fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword);
+
+ for (j = *pNumSortedCodewordInSection; j != 0; j--) {
+ /* width allows a new segment */
+ intermediateResult = segmentStart;
+ if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) {
+ /* store segment start, segment length and increment the number of
+ * segments */
+ *pLeftStartOfSegment++ = intermediateResult;
+ *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1;
+ *pRemainingBitsInSegment++ = segmentWidth;
+ segmentStart += segmentWidth;
+ numSegment += 1;
+ }
+ /* width does not allow a new segment */
+ else {
+ /* correct the last segment length */
+ pLeftStartOfSegment--;
+ pRightStartOfSegment--;
+ pRemainingBitsInSegment--;
+ segmentStart = *pLeftStartOfSegment;
+
+ lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart;
+ *pRemainingBitsInSegment = lastSegmentWidth;
+ *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1;
+ endFlag = 1;
+ break;
+ }
+ }
+ pNumSortedCodewordInSection++;
+ if (endFlag != 0) {
+ break;
+ }
+ }
+ pHcr->segmentInfo.numSegment = numSegment;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function adapts the sorted section boundaries to the
+boundaries of segmentation. If the section lengths does not fit completely into
+the current segment, the section is spitted into two so called 'extended
+ sections'. The extended-section-info
+(pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in
+this case.
+
+--------------------------------------------------------------------------------------------
+*/
+
+static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) {
+ UINT srtSecCnt = 0; /* counter for sorted sections */
+ UINT xSrtScCnt = 0; /* counter for extended sorted sections */
+ UINT remainNumCwInSortSec;
+ UINT inSegmentRemainNumCW;
+
+ UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
+ UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
+ USHORT *pNumSortedCodewordInSection =
+ pHcr->sectionInfo.pNumSortedCodewordInSection;
+ UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook;
+ USHORT *pNumExtSortCwInSect =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ UINT numSegment = pHcr->segmentInfo.numSegment;
+ UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
+ SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
+ const UCHAR *pMaxCwLength = aMaxCwLen;
+
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ inSegmentRemainNumCW = numSegment;
+
+ while (srtSecCnt < numSortedSection) {
+ if (inSegmentRemainNumCW < remainNumCwInSortSec) {
+ pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ remainNumCwInSortSec -= inSegmentRemainNumCW;
+ inSegmentRemainNumCW = numSegment;
+ /* data of a sorted section was not integrated in extended sorted section
+ */
+ } else if (inSegmentRemainNumCW == remainNumCwInSortSec) {
+ pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ srtSecCnt++;
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ inSegmentRemainNumCW = numSegment;
+ /* data of a sorted section was integrated in extended sorted section */
+ } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */
+ pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec;
+ pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
+
+ inSegmentRemainNumCW -= remainNumCwInSortSec;
+ srtSecCnt++;
+ remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
+ /* data of a sorted section was integrated in extended sorted section */
+ }
+ pMaxLenOfCbInExtSrtSec[xSrtScCnt] =
+ fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],
+ (INT)lengthOfLongestCodeword);
+
+ xSrtScCnt += 1;
+
+ if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW;
+ return;
+ }
+ }
+ pNumExtSortCwInSect[xSrtScCnt] = 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function calculates the number of extended sorted
+sections which belong to the sets. Each set from set 0 (one and only set for the
+PCWs) till to the last set gets a entry in the array to which
+ 'pNumExtendedSortedSectinsInSets' points to.
+
+ Calculation: The entrys in
+pNumExtendedSortedCodewordInSectin are added untill the value numSegment is
+reached. Then the sum_variable is cleared and the calculation starts from the
+beginning. As much extended sorted Sections are summed up to reach the value
+numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin.
+--------------------------------------------------------------------------------------------
+*/
+static void DeriveNumberOfExtendedSortedSectionsInSets(
+ UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
+ int numExtendedSortedCodewordInSectionIdx,
+ USHORT *pNumExtendedSortedSectionsInSets,
+ int numExtendedSortedSectionsInSetsIdx) {
+ USHORT counter = 0;
+ UINT cwSum = 0;
+ USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection;
+ USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets;
+
+ while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) {
+ cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx];
+ numExtendedSortedCodewordInSectionIdx++;
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ if (cwSum > numSegment) {
+ return;
+ }
+ counter++;
+ if (counter > 1024 / 4) {
+ return;
+ }
+ if (cwSum == numSegment) {
+ pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter;
+ numExtendedSortedSectionsInSetsIdx++;
+ if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
+ return;
+ }
+ counter = 0;
+ cwSum = 0;
+ }
+ }
+ pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] =
+ counter; /* save last entry for the last - probably shorter - set */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes all priority codewords (PCWs) in a
+spectrum (within set 0). The calculation of the PCWs is managed in two loops.
+The loopcounter of the outer loop is set to the first value pointer
+ pNumExtendedSortedSectionsInSets points to. This value
+represents the number of extended sorted sections within set 0. The loopcounter
+of the inner loop is set to the first value pointer
+ pNumExtendedSortedCodewordInSectin points to. The value
+represents the number of extended sorted codewords in sections (the original
+sections have been splitted to go along with the borders of the sets). Each time
+the number of the extended sorted codewords in sections are de- coded, the
+pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one.
+--------------------------------------------------------------------------------------------
+*/
+static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
+ UINT i;
+ USHORT extSortSec;
+ USHORT curExtSortCwInSec;
+ UCHAR codebook;
+ UCHAR dimension;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ USHORT *pNumExtendedSortedCodewordInSection =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ int numExtendedSortedCodewordInSectionIdx =
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
+ int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ USHORT *pNumExtendedSortedSectionsInSets =
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
+ int numExtendedSortedSectionsInSetsIdx =
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ FIXP_DBL *pQuantizedSpectralCoefficients =
+ SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+ int quantizedSpectralCoefficientsIdx =
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
+ int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
+ UCHAR maxAllowedCwLen;
+ int numDecodedBits;
+ const UCHAR *pCbDimension = aDimCb;
+ const UCHAR *pCbSign = aSignCb;
+
+ /* clear result array */
+ FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx,
+ 1024 * sizeof(FIXP_DBL));
+
+ /* decode all PCWs in the extended sorted section(s) belonging to set 0 */
+ for (extSortSec =
+ pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
+ extSortSec != 0; extSortSec--) {
+ codebook =
+ pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for
+ this extended
+ sorted section
+ and increment ptr
+ to cb of next
+ ext. sort sec */
+ extendedSortedCodebookIdx++;
+ if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ dimension = pCbDimension[codebook]; /* get dimension of codebook of this
+ extended sort. sec. */
+ pCurrentTree =
+ aHuffTable[codebook]; /* convert codebook to pointer to QSCs */
+ pQuantValBase =
+ aQuantTable[codebook]; /* convert codebook to index to table of QSCs */
+ maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx];
+ maxLenOfCbInExtSrtSecIdx++;
+ if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+
+ /* switch for decoding with different codebooks: */
+ if (pCbSign[codebook] ==
+ 0) { /* no sign bits follow after the codeword-body */
+ /* PCW_BodyONLY */
+ /*==============*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ numDecodedBits = 0;
+
+ /* decode PCW_BODY */
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ /* result is written out here because NO sign bits follow the body */
+ for (i = dimension; i != 0; i--) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into
+ spectrum; sign is already valid */
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+ }
+
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx - dimension,
+ dimension)) {
+ return;
+ }
+ pLeftStartOfSegment++; /* update pointer for decoding the next PCW */
+ pRemainingBitsInSegment++; /* update pointer for decoding the next PCW
+ */
+ }
+ } else if ((codebook < 11) && (pCbSign[codebook] ==
+ 1)) { /* possibly there follow 1,2,3 or 4
+ sign bits after the codeword-body */
+ /* PCW_Body and PCW_Sign */
+ /*=======================*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ int err;
+ numDecodedBits = 0;
+
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ err = DecodePCW_Sign(
+ bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
+ pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+ if (err != 0) {
+ return;
+ }
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr,
+ PCW_BODY_SIGN,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx - dimension,
+ dimension)) {
+ return;
+ }
+ pLeftStartOfSegment++;
+ pRemainingBitsInSegment++;
+ }
+ } else if ((pCbSign[codebook] == 1) &&
+ (codebook >= 11)) { /* possibly there follow some sign bits and
+ maybe one or two escape sequences after
+ the cw-body */
+ /* PCW_Body, PCW_Sign and maybe PCW_Escape */
+ /*=========================================*/
+
+ for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ curExtSortCwInSec != 0; curExtSortCwInSec--) {
+ int err;
+ numDecodedBits = 0;
+
+ /* decode PCW_BODY */
+ pQuantVal = DecodePCW_Body(
+ bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+
+ err = DecodePCW_Sign(
+ bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
+ pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
+ pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
+ if (err != 0) {
+ return;
+ }
+
+ /* decode PCW_ESCAPE if present */
+ quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK;
+
+ if (fixp_abs(pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx]) ==
+ (FIXP_DBL)ESCAPE_VALUE) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)DecodeEscapeSequence(
+ bs, pHcr->decInOut.bitstreamAnchor,
+ pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx],
+ pLeftStartOfSegment, pRemainingBitsInSegment,
+ &numDecodedBits);
+ }
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+
+ if (fixp_abs(pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx]) ==
+ (FIXP_DBL)ESCAPE_VALUE) {
+ pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
+ (FIXP_DBL)DecodeEscapeSequence(
+ bs, pHcr->decInOut.bitstreamAnchor,
+ pQuantizedSpectralCoefficients
+ [quantizedSpectralCoefficientsIdx],
+ pLeftStartOfSegment, pRemainingBitsInSegment,
+ &numDecodedBits);
+ }
+ quantizedSpectralCoefficientsIdx++;
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+
+ /* one more PCW should be decoded */
+
+ if (maxAllowedCwLen <
+ (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) {
+ pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
+ }
+
+ if (1 == errDetectPcwSegmentation(
+ *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr,
+ PCW_BODY_SIGN_ESC,
+ pQuantizedSpectralCoefficients +
+ quantizedSpectralCoefficientsIdx -
+ DIMENSION_OF_ESCAPE_CODEBOOK,
+ DIMENSION_OF_ESCAPE_CODEBOOK)) {
+ return;
+ }
+ pLeftStartOfSegment++;
+ pRemainingBitsInSegment++;
+ }
+ }
+
+ /* all PCWs belonging to this extended section should be decoded */
+ numExtendedSortedCodewordInSectionIdx++;
+ if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) {
+ return;
+ }
+ }
+ /* all PCWs should be decoded */
+
+ numExtendedSortedSectionsInSetsIdx++;
+ if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
+ return;
+ }
+
+ /* Write back indexes into structure */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
+ numExtendedSortedSectionsInSetsIdx;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx =
+ quantizedSpectralCoefficientsIdx;
+ pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function checks immediately after every decoded PCW,
+whether out of the current segment too many bits have been read or not. If an
+error occurrs, probably the sideinfo or the HCR-bitstream block holding the
+huffman encoded quantized spectral coefficients is distorted. In this case the
+two or four quantized spectral coefficients belonging to the current codeword
+ are marked (for being detected by concealment later).
+--------------------------------------------------------------------------------------------
+*/
+static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
+ H_HCR_INFO pHcr, PCW_TYPE kind,
+ FIXP_DBL *qsc_base_of_cw,
+ UCHAR dimension) {
+ SCHAR i;
+ if (remainingBitsInSegment < 0) {
+ /* log the error */
+ switch (kind) {
+ case PCW_BODY:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY;
+ break;
+ case PCW_BODY_SIGN:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN;
+ break;
+ case PCW_BODY_SIGN_ESC:
+ pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC;
+ break;
+ }
+ /* mark the erred lines */
+ for (i = dimension; i != 0; i--) {
+ *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function checks if all segments are empty after
+decoding. There are _no lines markded_ as invalid because it could not be traced
+back where from the remaining bits are.
+--------------------------------------------------------------------------------------------
+*/
+static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) {
+ UCHAR segmentationErrorFlag = 0;
+ USHORT i;
+ SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ UINT numSegment = pHcr->segmentInfo.numSegment;
+
+ for (i = numSegment; i != 0; i--) {
+ if (*pRemainingBitsInSegment++ != 0) {
+ segmentationErrorFlag = 1;
+ }
+ }
+ if (segmentationErrorFlag == 1) {
+ pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function walks one step within the decoding tree. Which
+branch is taken depends on the decoded carryBit input parameter.
+--------------------------------------------------------------------------------------------
+*/
+void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
+ UINT *branchNode) {
+ if (carryBit == 0) {
+ *branchNode =
+ (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT: 00FFF000 */
+ } else {
+ *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */
+ }
+
+ *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the body of a priority codeword (PCW)
+-----------------------------------------------------------------------------------------------
+ return: - return value is pointer to first of two or four quantized
+spectral coefficients
+--------------------------------------------------------------------------------------------
+*/
+static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ const UINT *pCurrentTree,
+ const SCHAR *pQuantValBase,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UCHAR carryBit;
+ UINT branchNode;
+ UINT treeNode;
+ UINT branchValue;
+ const SCHAR *pQuantVal;
+
+ /* decode PCW_BODY */
+ treeNode = *pCurrentTree; /* get first node of current tree belonging to
+ current codebook */
+
+ /* decode whole PCW-codeword-body */
+ while (1) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */
+ break; /* end of branch in tree reached i.e. a whole PCW-Body is decoded
+ */
+ } else {
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ pQuantVal =
+ pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4
+ quantized values */
+
+ return pQuantVal;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes one escape sequence. In case of a
+escape codebook and in case of the absolute value of the quantized spectral
+value == 16, a escapeSequence is decoded in two steps:
+ 1. escape prefix
+ 2. escape word
+--------------------------------------------------------------------------------------------
+*/
+
+static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT quantSpecCoef, INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UINT i;
+ INT sign;
+ UINT escapeOnesCounter = 0;
+ UINT carryBit;
+ INT escape_word = 0;
+
+ /* decode escape prefix */
+ while (1) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ if (carryBit != 0) {
+ escapeOnesCounter += 1;
+ } else {
+ escapeOnesCounter += 4;
+ break;
+ }
+ }
+
+ /* decode escape word */
+ for (i = escapeOnesCounter; i != 0; i--) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+
+ escape_word <<= 1;
+ escape_word = escape_word | carryBit;
+ }
+
+ sign = (quantSpecCoef >= 0) ? 1 : -1;
+
+ quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
+
+ return quantSpecCoef;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the Signbits of a priority codeword (PCW) and writes
+out the resulting quantized spectral values into unsorted sections
+-----------------------------------------------------------------------------------------------
+ output: - two or four lines at position in corresponding section
+(which are not located at the desired position, i.e. they must be reordered in
+the last of eight function of HCR)
+-----------------------------------------------------------------------------------------------
+ return: - updated pQuantSpecCoef pointer (to next empty storage for a
+line)
+--------------------------------------------------------------------------------------------
+*/
+static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ UINT codebookDim, const SCHAR *pQuantVal,
+ FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
+ INT *pLeftStartOfSegment,
+ SCHAR *pRemainingBitsInSegment,
+ int *pNumDecodedBits) {
+ UINT i;
+ UINT carryBit;
+ INT quantSpecCoef;
+
+ for (i = codebookDim; i != 0; i--) {
+ quantSpecCoef = *pQuantVal++;
+ if (quantSpecCoef != 0) {
+ carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
+ pLeftStartOfSegment, /* dummy */
+ FROM_LEFT_TO_RIGHT);
+ *pRemainingBitsInSegment -= 1;
+ *pNumDecodedBits += 1;
+ if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) {
+ return -1;
+ }
+
+ /* adapt sign of values according to the decoded sign bit */
+ if (carryBit != 0) {
+ pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef;
+ } else {
+ pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef;
+ }
+ } else {
+ pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f);
+ }
+ *quantSpecCoefIdx += 1;
+ if (*quantSpecCoefIdx >= 1024) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Mutes spectral lines which have been marked as erroneous
+(Q_VALUE_INVALID)
+--------------------------------------------------------------------------------------------
+*/
+void HcrMuteErroneousLines(H_HCR_INFO hHcr) {
+ int c;
+ FIXP_DBL *RESTRICT pLong =
+ SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase);
+
+ /* if there is a line with value Q_VALUE_INVALID mute it */
+ for (c = 0; c < 1024; c++) {
+ if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) {
+ pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr.h b/fdk-aac/libAACdec/src/aacdec_hcr.h
new file mode 100644
index 0000000..be21144
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr.h
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Interface function declaration; common defines
+ and structures; defines for switching error-generator,
+ -detector, and -concealment
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_H
+#define AACDEC_HCR_H
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs);
+UINT HcrDecoder(H_HCR_INFO hHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ HANDLE_FDK_BITSTREAM bs);
+void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
+ UINT *branchNode);
+
+void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const MP4_ELEMENT_ID globalHcrType);
+void HcrMuteErroneousLines(H_HCR_INFO hHcr);
+
+void setHcrType(H_HCR_INFO hHcr, MP4_ELEMENT_ID type);
+INT getHcrType(H_HCR_INFO hHcr);
+
+#endif /* AACDEC_HCR_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp b/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp
new file mode 100644
index 0000000..0198659
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_bit.cpp
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Bitstream reading
+
+*******************************************************************************/
+
+#include "aacdec_hcr_bit.h"
+
+/*---------------------------------------------------------------------------------------------
+ description: This function toggles the read direction.
+-----------------------------------------------------------------------------------------------
+ input: current read direction
+-----------------------------------------------------------------------------------------------
+ return: new read direction
+--------------------------------------------------------------------------------------------
+*/
+UCHAR ToggleReadDirection(UCHAR readDirection) {
+ if (readDirection == FROM_LEFT_TO_RIGHT) {
+ return FROM_RIGHT_TO_LEFT;
+ } else {
+ return FROM_LEFT_TO_RIGHT;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function returns a bit from the bitstream according to
+read direction. It is called very often, therefore it makes sense to inline it
+(runtime).
+-----------------------------------------------------------------------------------------------
+ input: - handle to FDK bitstream
+ - reference value marking start of bitfield
+ - pLeftStartOfSegment
+ - pRightStartOfSegment
+ - readDirection
+-----------------------------------------------------------------------------------------------
+ return: - bit from bitstream
+--------------------------------------------------------------------------------------------
+*/
+UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pLeftStartOfSegment,
+ INT *pRightStartOfSegment, UCHAR readDirection) {
+ UINT bit;
+ INT readBitOffset;
+
+ if (readDirection == FROM_LEFT_TO_RIGHT) {
+ readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pLeftStartOfSegment;
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ bit = FDKreadBits(bs, 1);
+
+ *pLeftStartOfSegment += 1;
+ } else {
+ readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pRightStartOfSegment;
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ /* to be replaced with a brother function of FDKreadBits() */
+ bit = FDKreadBits(bs, 1);
+ FDKpushBack(bs, 2);
+
+ *pRightStartOfSegment -= 1;
+ }
+
+ return (bit);
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_bit.h b/fdk-aac/libAACdec/src/aacdec_hcr_bit.h
new file mode 100644
index 0000000..77242ac
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_bit.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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Bitstream reading prototypes
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_BIT_H
+#define AACDEC_HCR_BIT_H
+
+#include "aacdec_hcr.h"
+
+UCHAR ToggleReadDirection(UCHAR readDirection);
+
+UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pLeftStartOfSegment,
+ INT *pRightStartOfSegment, UCHAR readDirection);
+
+#endif /* AACDEC_HCR_BIT_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcr_types.h b/fdk-aac/libAACdec/src/aacdec_hcr_types.h
new file mode 100644
index 0000000..1cc3cb0
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcr_types.h
@@ -0,0 +1,432 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Common defines and structures; defines for
+ switching error-generator, -detector, and -concealment;
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCR_TYPES_H
+#define AACDEC_HCR_TYPES_H
+
+#include "FDK_bitstream.h"
+#include "overlapadd.h"
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+
+#define LINES_PER_UNIT 4
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+/* ----------- basic HCR configuration ------------ */
+
+#define MAX_SFB_HCR \
+ (((1024 / 8) / LINES_PER_UNIT) * 8) /* (8 * 16) is not enough because sfbs \
+ are split in units for blocktype \
+ short */
+#define NUMBER_OF_UNIT_GROUPS (LINES_PER_UNIT * 8)
+#define LINES_PER_UNIT_GROUP (1024 / NUMBER_OF_UNIT_GROUPS) /* 15 16 30 32 */
+
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+/* ------------------------------------------------ */
+
+#define FROM_LEFT_TO_RIGHT 0
+#define FROM_RIGHT_TO_LEFT 1
+
+#define MAX_CB_PAIRS 23
+#define MAX_HCR_SETS 14
+
+#define ESCAPE_VALUE 16
+#define POSITION_OF_FLAG_A 21
+#define POSITION_OF_FLAG_B 20
+
+#define MAX_CB 32 /* last used CB is cb #31 when VCB11 is used */
+
+#define MAX_CB_CHECK \
+ 32 /* support for VCB11 available -- is more general, could therefore used \
+ in both cases */
+
+#define NUMBER_OF_BIT_IN_WORD 32
+
+/* log */
+#define THIRTYTWO_LOG_DIV_TWO_LOG 5
+#define EIGHT_LOG_DIV_TWO_LOG 3
+#define FOUR_LOG_DIV_TWO_LOG 2
+
+/* borders */
+#define CPE_TOP_LENGTH 12288
+#define SCE_TOP_LENGTH 6144
+#define LEN_OF_LONGEST_CW_TOP_LENGTH 49
+
+/* qsc's of high level */
+#define Q_VALUE_INVALID \
+ 8192 /* mark a invalid line with this value (to be concealed later on) */
+#define HCR_DIRAC 500 /* a line of high level */
+
+/* masks */
+#define MASK_LEFT 0xFFF000
+#define MASK_RIGHT 0xFFF
+#define CLR_BIT_10 0x3FF
+#define TEST_BIT_10 0x400
+
+#define LEFT_OFFSET 12
+
+/* when set HCR is replaced by a dummy-module which just fills the outputbuffer
+ * with a dirac sequence */
+/* use this if HCR is suspected to write in other modules -- if error is stell
+ * there, HCR is innocent */
+
+/* ------------------------------ */
+/* - insert HCR errors - */
+/* ------------------------------ */
+
+/* modify input lengths -- high protected */
+#define ERROR_LORSD 0 /* offset: error if different from zero */
+#define ERROR_LOLC 0 /* offset: error if different from zero */
+
+/* segments are earlier empty as expected when decoding PCWs */
+#define ERROR_PCW_BODY \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+#define ERROR_PCW_BODY_SIGN \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+#define ERROR_PCW_BODY_SIGN_ESC \
+ 0 /* set a positive values to trigger the error (make segments earlyer \
+ appear to be empty) */
+
+/* pretend there are too many bits decoded (enlarge length of codeword) at PCWs
+ * -- use a positive value */
+#define ERROR_PCW_BODY_ONLY_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+#define ERROR_PCW_BODY_SIGN_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+#define ERROR_PCW_BODY_SIGN_ESC_TOO_LONG \
+ 0 /* set a positive values to trigger the error */
+
+/* modify HCR bitstream block */
+
+#define MODULO_DIVISOR_HCR 30
+
+/* ------------------------------ */
+/* - detect HCR errors - */
+/* ------------------------------ */
+/* check input data */
+
+/* during decoding */
+
+/* all the segments are checked -- therefore -- if this check passes, its a kind
+ of evidence that the decoded PCWs and non-PCWs are fine */
+
+/* if a codeword is decoded there exists a border for the number of bits, which
+ are allowed to read for this codeword. This border is the minimum of the
+ length of the longest codeword (for the currently used codebook) and the
+ separately transmitted 'lengthOfLongestCodeword' in this frame and channel.
+ The number of decoded bits is counted (for PCWs only -- there it makes really
+ sense in my opinion). If this number exceeds the border (derived as minimum
+ -- see above), a error is detected. */
+
+/* -----------------------------------------------------------------------------------------------------
+ This error check could be set to zero because due to a test within
+ RVLC-Escape-huffman-Decoder a too long codeword could not be detected -- it
+ seems that for RVLC-Escape-Codeword the coderoom is used to 100%. Therefore I
+ assume that the coderoom is used to 100% also for the codebooks 1..11 used at
+ HCR Therefore this test is deactivated pending further notice
+ -----------------------------------------------------------------------------------------------------
+ */
+
+/* test if the number of remaining bits in a segment is _below_ zero. If there
+ are no errors the lowest allowed value for remainingBitsInSegment is zero.
+ This check also could be set to zero (save runtime) */
+
+/* other */
+/* when set to '1', avoid setting the LAV-Flag in errorLog due to a
+ previous-line-marking (at PCW decoder). A little more runtime is needed then
+ when writing values out into output-buffer. */
+
+/* ------------------------------ */
+/* - conceal HCR errors - */
+/* ------------------------------ */
+
+#define HCR_ERROR_CONCEALMENT \
+ 1 /* if set to '1', HCR _mutes_ the erred quantized spectral coefficients */
+
+// ------------------------------------------------------------------------------------------------------------------
+// errorLog: A word of 32 bits used for
+// logging possible errors within HCR
+// in case of distorted
+// bitstreams. Table of all
+// known errors:
+// ------------------------------------------------------------------------------------------------------------------------
+// bit fatal location meaning
+// ----+-----+-----------+--------------------------------------
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY \
+ 0x80000000 // 31 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN \
+ 0x40000000 // 30 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC \
+ 0x20000000 // 29 no PCW-Dec During PCW decoding it is checked after
+ // every PCW if there are too many bits decoded (immediate
+ // check).
+#define EXTENDED_SORTED_COUNTER_OVERFLOW \
+ 0x10000000 // 28 yes Init-Dec Error during extending sideinfo
+ // (neither a PCW nor a nonPCW was decoded so far)
+ // 0x08000000 // 27 reserved
+ // 0x04000000 // 26 reserved
+ // 0x02000000 // 25 reserved
+ // 0x01000000 // 24 reserved
+ // 0x00800000 // 23 reserved
+ // 0x00400000 // 22 reserved
+ // 0x00200000 // 21 reserved
+ // 0x00100000 // 20 reserved
+
+/* special errors */
+#define TOO_MANY_PCW_BODY_BITS_DECODED \
+ 0x00080000 // 19 yes PCW-Dec During PCW-body-decoding too many bits
+ // have been read from bitstream -- advice: skip non-PCW decoding
+#define TOO_MANY_PCW_BODY_SIGN_BITS_DECODED \
+ 0x00040000 // 18 yes PCW-Dec During PCW-body-sign-decoding too many
+ // bits have been read from bitstream -- advice: skip non-PCW
+ // decoding
+#define TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED \
+ 0x00020000 // 17 yes PCW-Dec During PCW-body-sign-esc-decoding too
+ // many bits have been read from bitstream -- advice: skip
+ // non-PCW decoding
+
+// 0x00010000 // 16 reserved
+#define STATE_ERROR_BODY_ONLY \
+ 0x00008000 // 15 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN__BODY \
+ 0x00004000 // 14 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN__SIGN \
+ 0x00002000 // 13 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__BODY \
+ 0x00001000 // 12 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__SIGN \
+ 0x00000800 // 11 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX \
+ 0x00000400 // 10 no NonPCW-Dec State machine returned with error
+#define STATE_ERROR_BODY_SIGN_ESC__ESC_WORD \
+ 0x00000200 // 9 no NonPCW-Dec State machine returned with error
+#define HCR_SI_LENGTHS_FAILURE \
+ 0x00000100 // 8 yes Init-Dec LengthOfLongestCodeword must not be
+ // less than lenghtOfReorderedSpectralData
+#define NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000080 // 7 yes Init-Dec The number of sections is not within
+ // the allowed range (short block)
+#define NUM_SECT_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000040 // 6 yes Init-Dec The number of sections is not within
+ // the allowed range (long block)
+#define LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000020 // 5 yes Init-Dec The number of lines per section is not
+ // within the allowed range (short block)
+#define CB_OUT_OF_RANGE_SHORT_BLOCK \
+ 0x00000010 // 4 yes Init-Dec The codebook is not within the allowed
+ // range (short block)
+#define LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000008 // 3 yes Init-Dec The number of lines per section is not
+ // within the allowed range (long block)
+#define CB_OUT_OF_RANGE_LONG_BLOCK \
+ 0x00000004 // 2 yes Init-Dec The codebook is not within the allowed
+ // range (long block)
+#define LAV_VIOLATION \
+ 0x00000002 // 1 no Final The absolute value of at least one
+ // decoded line was too high for the according codebook.
+#define BIT_IN_SEGMENTATION_ERROR \
+ 0x00000001 // 0 no Final After PCW and non-PWC-decoding at least
+ // one segment is not zero (global check).
+
+/*----------*/
+#define HCR_FATAL_PCW_ERROR_MASK 0x100E01FC
+
+typedef enum { PCW_BODY, PCW_BODY_SIGN, PCW_BODY_SIGN_ESC } PCW_TYPE;
+
+/* interface Decoder <---> HCR */
+typedef struct {
+ UINT errorLog;
+ SPECTRAL_PTR pQuantizedSpectralCoefficientsBase;
+ int quantizedSpectralCoefficientsIdx;
+ SHORT lengthOfReorderedSpectralData;
+ SHORT numSection;
+ SHORT *pNumLineInSect;
+ INT bitstreamAnchor;
+ SCHAR lengthOfLongestCodeword;
+ UCHAR *pCodebook;
+} HCR_INPUT_OUTPUT;
+
+typedef struct {
+ const UCHAR *pMinOfCbPair;
+ const UCHAR *pMaxOfCbPair;
+} HCR_CB_PAIRS;
+
+typedef struct {
+ const USHORT *pLargestAbsVal;
+ const UCHAR *pMaxCwLength;
+ const UCHAR *pCbDimension;
+ const UCHAR *pCbDimShift;
+ const UCHAR *pCbSign;
+ const UCHAR *pCbPriority;
+} HCR_TABLE_INFO;
+
+typedef struct {
+ UINT numSegment;
+ UINT pSegmentBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
+ UINT pCodewordBitfield[((1024 >> 1) / NUMBER_OF_BIT_IN_WORD + 1)];
+ UINT segmentOffset;
+ INT pLeftStartOfSegment[1024 >> 1];
+ INT pRightStartOfSegment[1024 >> 1];
+ SCHAR pRemainingBitsInSegment[1024 >> 1];
+ UCHAR readDirection;
+ UCHAR numWordForBitfield;
+ USHORT pNumBitValidInLastWord;
+} HCR_SEGMENT_INFO;
+
+typedef struct {
+ UINT numCodeword;
+ UINT numSortedSection;
+ USHORT pNumCodewordInSection[MAX_SFB_HCR];
+ USHORT pNumSortedCodewordInSection[MAX_SFB_HCR];
+ USHORT pNumExtendedSortedCodewordInSection[MAX_SFB_HCR + MAX_HCR_SETS];
+ int numExtendedSortedCodewordInSectionIdx;
+ USHORT pNumExtendedSortedSectionsInSets[MAX_HCR_SETS];
+ int numExtendedSortedSectionsInSetsIdx;
+ USHORT pReorderOffset[MAX_SFB_HCR];
+ UCHAR pSortedCodebook[MAX_SFB_HCR];
+
+ UCHAR pExtendedSortedCodebook[MAX_SFB_HCR + MAX_HCR_SETS];
+ int extendedSortedCodebookIdx;
+ UCHAR pMaxLenOfCbInExtSrtSec[MAX_SFB_HCR + MAX_HCR_SETS];
+ int maxLenOfCbInExtSrtSecIdx;
+ UCHAR pCodebookSwitch[MAX_SFB_HCR];
+} HCR_SECTION_INFO;
+
+typedef UINT (*STATEFUNC)(HANDLE_FDK_BITSTREAM, void *);
+
+typedef struct {
+ /* worst-case and 1024/4 non-PCWs exist in worst-case */
+ FIXP_DBL
+ *pResultBase; /* Base address for spectral data output target buffer */
+ UINT iNode[1024 >> 2]; /* Helper indices for code books */
+ USHORT
+ iResultPointer[1024 >> 2]; /* Helper indices for accessing pResultBase */
+ UINT pEscapeSequenceInfo[1024 >> 2];
+ UINT codewordOffset;
+ STATEFUNC pState;
+ UCHAR pCodebook[1024 >> 2];
+ UCHAR pCntSign[1024 >> 2];
+ /* this array holds the states coded as integer values within the range
+ * [0,1,..,7] */
+ SCHAR pSta[1024 >> 2];
+} HCR_NON_PCW_SIDEINFO;
+
+typedef struct {
+ HCR_INPUT_OUTPUT decInOut;
+ HCR_SEGMENT_INFO segmentInfo;
+ HCR_SECTION_INFO sectionInfo;
+ HCR_NON_PCW_SIDEINFO nonPcwSideinfo;
+} CErHcrInfo;
+
+typedef CErHcrInfo *H_HCR_INFO;
+
+#endif /* AACDEC_HCR_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_hcrs.cpp b/fdk-aac/libAACdec/src/aacdec_hcrs.cpp
new file mode 100644
index 0000000..d2bc867
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcrs.cpp
@@ -0,0 +1,1551 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Prepare decoding of non-PCWs, segmentation- and
+ bitfield-handling, HCR-Statemachine
+
+*******************************************************************************/
+
+#include "aacdec_hcrs.h"
+
+#include "aacdec_hcr.h"
+
+#include "aacdec_hcr_bit.h"
+#include "aac_rom.h"
+#include "aac_ram.h"
+
+static UINT InitSegmentBitfield(UINT *pNumSegment,
+ SCHAR *pRemainingBitsInSegment,
+ UINT *pSegmentBitfield,
+ UCHAR *pNumWordForBitfield,
+ USHORT *pNumBitValidInLastWord);
+
+static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr);
+
+static INT ModuloValue(INT input, INT bufferlength);
+
+static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
+ UINT *pBitfield);
+
+/*---------------------------------------------------------------------------------------------
+ description: This function decodes all non-priority codewords (non-PCWs) by
+using a state-machine.
+--------------------------------------------------------------------------------------------
+*/
+void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
+ UINT numValidSegment;
+ INT segmentOffset;
+ INT codewordOffsetBase;
+ INT codewordOffset;
+ UINT trial;
+
+ UINT *pNumSegment;
+ SCHAR *pRemainingBitsInSegment;
+ UINT *pSegmentBitfield;
+ UCHAR *pNumWordForBitfield;
+ USHORT *pNumBitValidInLastWord;
+ UINT *pCodewordBitfield;
+ INT bitfieldWord;
+ INT bitInWord;
+ UINT tempWord;
+ UINT interMediateWord;
+ INT tempBit;
+ INT carry;
+
+ UINT numCodeword;
+ UCHAR numSet;
+ UCHAR currentSet;
+ UINT codewordInSet;
+ UINT remainingCodewordsInSet;
+ SCHAR *pSta;
+ UINT ret;
+
+ pNumSegment = &(pHcr->segmentInfo.numSegment);
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pNumWordForBitfield = &(pHcr->segmentInfo.numWordForBitfield);
+ pNumBitValidInLastWord = &(pHcr->segmentInfo.pNumBitValidInLastWord);
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ numValidSegment = InitSegmentBitfield(pNumSegment, pRemainingBitsInSegment,
+ pSegmentBitfield, pNumWordForBitfield,
+ pNumBitValidInLastWord);
+
+ if (numValidSegment != 0) {
+ numCodeword = pHcr->sectionInfo.numCodeword;
+ numSet = ((numCodeword - 1) / *pNumSegment) + 1;
+
+ pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT;
+
+ /* Process sets subsequently */
+ for (currentSet = 1; currentSet < numSet; currentSet++) {
+ /* step 1 */
+ numCodeword -=
+ *pNumSegment; /* number of remaining non PCWs [for all sets] */
+ if (numCodeword < *pNumSegment) {
+ codewordInSet = numCodeword; /* for last set */
+ } else {
+ codewordInSet = *pNumSegment; /* for all sets except last set */
+ }
+
+ /* step 2 */
+ /* prepare array 'CodewordBitfield'; as much ones are written from left in
+ * all words, as much decodedCodewordInSetCounter nonPCWs exist in this
+ * set */
+ tempWord = 0xFFFFFFFF;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+
+ for (bitfieldWord = *pNumWordForBitfield; bitfieldWord != 0;
+ bitfieldWord--) { /* loop over all used words */
+ if (codewordInSet > NUMBER_OF_BIT_IN_WORD) { /* more codewords than
+ number of bits => fill
+ ones */
+ /* fill a whole word with ones */
+ *pCodewordBitfield++ = tempWord;
+ codewordInSet -= NUMBER_OF_BIT_IN_WORD; /* subtract number of bits */
+ } else {
+ /* prepare last tempWord */
+ for (remainingCodewordsInSet = codewordInSet;
+ remainingCodewordsInSet < NUMBER_OF_BIT_IN_WORD;
+ remainingCodewordsInSet++) {
+ tempWord =
+ tempWord &
+ ~(1
+ << (NUMBER_OF_BIT_IN_WORD - 1 -
+ remainingCodewordsInSet)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i)
+ in tempWord */
+ }
+ *pCodewordBitfield++ = tempWord;
+ tempWord = 0x00000000;
+ }
+ }
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+
+ /* step 3 */
+ /* build non-PCW sideinfo for each non-PCW of the current set */
+ InitNonPCWSideInformationForCurrentSet(pHcr);
+
+ /* step 4 */
+ /* decode all non-PCWs belonging to this set */
+
+ /* loop over trials */
+ codewordOffsetBase = 0;
+ for (trial = *pNumSegment; trial > 0; trial--) {
+ /* loop over number of words in bitfields */
+ segmentOffset = 0; /* start at zero in every segment */
+ pHcr->segmentInfo.segmentOffset =
+ segmentOffset; /* store in structure for states */
+ codewordOffset = codewordOffsetBase;
+ pHcr->nonPcwSideinfo.codewordOffset =
+ codewordOffset; /* store in structure for states */
+
+ for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield;
+ bitfieldWord++) {
+ /* derive tempWord with bitwise and */
+ tempWord =
+ pSegmentBitfield[bitfieldWord] & pCodewordBitfield[bitfieldWord];
+
+ /* if tempWord is not zero, decode something */
+ if (tempWord != 0) {
+ /* loop over all bits in tempWord; start state machine if & is true
+ */
+ for (bitInWord = NUMBER_OF_BIT_IN_WORD; bitInWord > 0;
+ bitInWord--) {
+ interMediateWord = ((UINT)1 << (bitInWord - 1));
+ if ((tempWord & interMediateWord) == interMediateWord) {
+ /* get state and start state machine */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]];
+
+ while (pHcr->nonPcwSideinfo.pState) {
+ ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr);
+ if (ret != 0) {
+ return;
+ }
+ }
+ }
+
+ /* update both offsets */
+ segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
+ pHcr->segmentInfo.segmentOffset = segmentOffset;
+ codewordOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
+ codewordOffset =
+ ModuloValue(codewordOffset,
+ *pNumSegment); /* index of the current codeword
+ lies within modulo range */
+ pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
+ }
+ } else {
+ segmentOffset +=
+ NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
+ pHcr->segmentInfo.segmentOffset = segmentOffset;
+ codewordOffset +=
+ NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
+ codewordOffset = ModuloValue(
+ codewordOffset,
+ *pNumSegment); /* index of the current codeword lies within
+ modulo range */
+ pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
+ }
+ } /* end of bitfield word loop */
+
+ /* decrement codeword - pointer */
+ codewordOffsetBase -= 1;
+ codewordOffsetBase =
+ ModuloValue(codewordOffsetBase, *pNumSegment); /* index of the
+ current codeword
+ base lies within
+ modulo range */
+
+ /* rotate numSegment bits in codewordBitfield */
+ /* rotation of *numSegment bits in bitfield of codewords
+ * (circle-rotation) */
+ /* get last valid bit */
+ tempBit = pCodewordBitfield[*pNumWordForBitfield - 1] &
+ (1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
+ tempBit = tempBit >> (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord);
+
+ /* write zero into place where tempBit was fetched from */
+ pCodewordBitfield[*pNumWordForBitfield - 1] =
+ pCodewordBitfield[*pNumWordForBitfield - 1] &
+ ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
+
+ /* rotate last valid word */
+ pCodewordBitfield[*pNumWordForBitfield - 1] =
+ pCodewordBitfield[*pNumWordForBitfield - 1] >> 1;
+
+ /* transfare carry bit 0 from current word into bitposition 31 from next
+ * word and rotate current word */
+ for (bitfieldWord = *pNumWordForBitfield - 2; bitfieldWord > -1;
+ bitfieldWord--) {
+ /* get carry (=bit at position 0) from current word */
+ carry = pCodewordBitfield[bitfieldWord] & 1;
+
+ /* put the carry bit at position 31 into word right from current word
+ */
+ pCodewordBitfield[bitfieldWord + 1] =
+ pCodewordBitfield[bitfieldWord + 1] |
+ (carry << (NUMBER_OF_BIT_IN_WORD - 1));
+
+ /* shift current word */
+ pCodewordBitfield[bitfieldWord] =
+ pCodewordBitfield[bitfieldWord] >> 1;
+ }
+
+ /* put tempBit into free bit-position 31 from first word */
+ pCodewordBitfield[0] =
+ pCodewordBitfield[0] | (tempBit << (NUMBER_OF_BIT_IN_WORD - 1));
+
+ } /* end of trial loop */
+
+ /* toggle read direction */
+ pHcr->segmentInfo.readDirection =
+ ToggleReadDirection(pHcr->segmentInfo.readDirection);
+ }
+ /* end of set loop */
+
+ /* all non-PCWs of this spectrum are decoded */
+ }
+
+ /* all PCWs and all non PCWs are decoded. They are unbacksorted in output
+ * buffer. Here is the Interface with comparing QSCs to asm decoding */
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function prepares the bitfield used for the
+ segments. The list is set up once to be used in all
+following sets. If a segment is decoded empty, the according bit from the
+Bitfield is removed.
+-----------------------------------------------------------------------------------------------
+ return: numValidSegment = the number of valid segments
+--------------------------------------------------------------------------------------------
+*/
+static UINT InitSegmentBitfield(UINT *pNumSegment,
+ SCHAR *pRemainingBitsInSegment,
+ UINT *pSegmentBitfield,
+ UCHAR *pNumWordForBitfield,
+ USHORT *pNumBitValidInLastWord) {
+ SHORT i;
+ USHORT r;
+ UCHAR bitfieldWord;
+ UINT tempWord;
+ USHORT numValidSegment;
+
+ *pNumWordForBitfield =
+ (*pNumSegment == 0)
+ ? 0
+ : ((*pNumSegment - 1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1;
+
+ /* loop over all words, which are completely used or only partial */
+ /* bit in pSegmentBitfield is zero if segment is empty; bit in
+ * pSegmentBitfield is one if segment is not empty */
+ numValidSegment = 0;
+ *pNumBitValidInLastWord = *pNumSegment;
+
+ /* loop over words */
+ for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield - 1;
+ bitfieldWord++) {
+ tempWord = 0xFFFFFFFF; /* set ones */
+ r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
+ for (i = 0; i < NUMBER_OF_BIT_IN_WORD; i++) {
+ if (pRemainingBitsInSegment[r + i] == 0) {
+ tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
+ i)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i) in
+ tempWord */
+ } else {
+ numValidSegment += 1; /* count segments which are not empty */
+ }
+ }
+ pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
+ *pNumBitValidInLastWord -= NUMBER_OF_BIT_IN_WORD; /* calculate number of
+ zeros on LSB side in
+ the last word */
+ }
+
+ /* calculate last word: prepare special tempWord */
+ tempWord = 0xFFFFFFFF;
+ for (i = 0; i < (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); i++) {
+ tempWord = tempWord & ~(1 << i); /* clear bit i in tempWord */
+ }
+
+ /* calculate last word */
+ r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
+ for (i = 0; i < *pNumBitValidInLastWord; i++) {
+ if (pRemainingBitsInSegment[r + i] == 0) {
+ tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
+ i)); /* set a zero at bit number
+ (NUMBER_OF_BIT_IN_WORD-1-i) in
+ tempWord */
+ } else {
+ numValidSegment += 1; /* count segments which are not empty */
+ }
+ }
+ pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
+
+ return numValidSegment;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function sets up sideinfo for the non-PCW decoder (for the
+current set).
+---------------------------------------------------------------------------------------------*/
+static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr) {
+ USHORT i, k;
+ UCHAR codebookDim;
+ UINT startNode;
+
+ UCHAR *pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ UINT *iNode = pHcr->nonPcwSideinfo.iNode;
+ UCHAR *pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ USHORT *iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ UINT *pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ SCHAR *pSta = pHcr->nonPcwSideinfo.pSta;
+ USHORT *pNumExtendedSortedCodewordInSection =
+ pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
+ int numExtendedSortedCodewordInSectionIdx =
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
+ UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
+ int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
+ USHORT *pNumExtendedSortedSectionsInSets =
+ pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
+ int numExtendedSortedSectionsInSetsIdx =
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
+ int quantizedSpectralCoefficientsIdx =
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx;
+ const UCHAR *pCbDimension = aDimCb;
+ int iterationCounter = 0;
+
+ /* loop over number of extended sorted sections in the current set so all
+ * codewords sideinfo variables within this set can be prepared for decoding
+ */
+ for (i = pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
+ i != 0; i--) {
+ codebookDim =
+ pCbDimension[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+ startNode = *aHuffTable[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+
+ for (k = pNumExtendedSortedCodewordInSection
+ [numExtendedSortedCodewordInSectionIdx];
+ k != 0; k--) {
+ iterationCounter++;
+ if (iterationCounter > (1024 >> 2)) {
+ return;
+ }
+ *pSta++ = aCodebook2StartInt
+ [pExtendedSortedCodebook[extendedSortedCodebookIdx]];
+ *pCodebook++ = pExtendedSortedCodebook[extendedSortedCodebookIdx];
+ *iNode++ = startNode;
+ *pCntSign++ = 0;
+ *iResultPointer++ = quantizedSpectralCoefficientsIdx;
+ *pEscapeSequenceInfo++ = 0;
+ quantizedSpectralCoefficientsIdx +=
+ codebookDim; /* update pointer by codebookDim --> point to next
+ starting value for writing out */
+ if (quantizedSpectralCoefficientsIdx >= 1024) {
+ return;
+ }
+ }
+ numExtendedSortedCodewordInSectionIdx++; /* inc ptr for next ext sort sec in
+ current set */
+ extendedSortedCodebookIdx++; /* inc ptr for next ext sort sec in current set
+ */
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS) ||
+ extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+ }
+ numExtendedSortedSectionsInSetsIdx++; /* inc ptr for next set of non-PCWs */
+ if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
+ return;
+ }
+
+ /* Write back indexes */
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
+ pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
+ numExtendedSortedSectionsInSetsIdx;
+ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
+ numExtendedSortedCodewordInSectionIdx;
+ pHcr->decInOut.quantizedSpectralCoefficientsIdx =
+ quantizedSpectralCoefficientsIdx;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function returns the input value if the value is in the
+ range of bufferlength. If <input> is smaller, one bufferlength
+is added, if <input> is bigger one bufferlength is subtracted.
+-----------------------------------------------------------------------------------------------
+ return: modulo result
+--------------------------------------------------------------------------------------------
+*/
+static INT ModuloValue(INT input, INT bufferlength) {
+ if (input > (bufferlength - 1)) {
+ return (input - bufferlength);
+ }
+ if (input < 0) {
+ return (input + bufferlength);
+ }
+ return input;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This function clears a bit from current bitfield and
+ switches off the statemachine.
+
+ A bit is cleared in two cases:
+ a) a codeword is decoded, then a bit is cleared in codeword
+bitfield b) a segment is decoded empty, then a bit is cleared in segment
+bitfield
+--------------------------------------------------------------------------------------------
+*/
+static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
+ UINT *pBitfield) {
+ UINT numBitfieldWord;
+ UINT numBitfieldBit;
+
+ /* get both values needed for clearing the bit */
+ numBitfieldWord = offset >> THIRTYTWO_LOG_DIV_TWO_LOG; /* int = wordNr */
+ numBitfieldBit = offset - (numBitfieldWord
+ << THIRTYTWO_LOG_DIV_TWO_LOG); /* fract = bitNr */
+
+ /* clear a bit in bitfield */
+ pBitfield[numBitfieldWord] =
+ pBitfield[numBitfieldWord] &
+ ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - numBitfieldBit));
+
+ /* switch off state machine because codeword is decoded and/or because segment
+ * is empty */
+ *ptrState = NULL;
+}
+
+/* =========================================================================================
+ the states of the statemachine
+ =========================================================================================
+ */
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the body of a codeword. This State is used for
+codebooks 1,2,5 and 6. No sign bits are decoded, because the table of the
+quantized spectral values has got a valid sign at the quantized spectral lines.
+-----------------------------------------------------------------------------------------------
+ output: Two or four quantizes spectral values written at position
+where pResultPointr points to
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+ FIXP_DBL *pResultBase;
+ UINT *iNode;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+ UINT branchNode;
+ UINT branchValue;
+ UINT iQSC;
+ UINT treeNode;
+ UCHAR carryBit;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ SCHAR *pRemainingBitsInSegment;
+ UCHAR readDirection;
+ UCHAR *pCodebook;
+ UCHAR dimCntr;
+ const UINT *pCurrentTree;
+ const UCHAR *pCbDimension;
+ const SCHAR *pQuantVal;
+ const SCHAR *pQuantValBase;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+
+ pCbDimension = aDimCb;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; ==> body is complete */
+ pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
+ address of
+ quantized
+ values
+ belonging to
+ current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ iQSC = iResultPointer[codewordOffset]; /* get position of first line for
+ writing out result */
+
+ for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
+ dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal++; /* write out 2 or 4 lines into
+ spectrum; no Sign bits
+ available in this state */
+ }
+
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+ iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
+ decoding of codeword body not finished
+ yet */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY;
+ return BODY_ONLY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the codeword body, writes out result and counts the
+number of quantized spectral values, which are different form zero. For those
+values sign bits are needed.
+
+ If sign bit counter cntSign is different from zero, switch to
+next state to decode sign Bits there. If sign bit counter cntSign is zero, no
+sign bits are needed and codeword is decoded.
+-----------------------------------------------------------------------------------------------
+ output: Two or four written quantizes spectral values written at
+position where pResultPointr points to. The signs of those lines may be wrong.
+If the signs [on just one signle sign] is wrong, the next state will correct it.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UCHAR *pCodebook;
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UINT iQSC;
+ UINT cntSign;
+ UCHAR dimCntr;
+ UCHAR carryBit;
+ SCHAR *pSta;
+ UINT treeNode;
+ UINT branchValue;
+ UINT branchNode;
+ const UCHAR *pCbDimension;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pCodebook = pHcr->nonPcwSideinfo.pCodebook;
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ pCbDimension = aDimCb;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set body complete */
+ /* body completely decoded; branchValue is valid, set pQuantVal to first
+ * (of two or four) quantized spectral coefficients */
+ pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
+ address of
+ quantized
+ values
+ belonging to
+ current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ iQSC = iResultPointer[codewordOffset]; /* get position of first line for
+ writing result */
+
+ /* codeword decoding result is written out here: Write out 2 or 4
+ * quantized spectral values with probably */
+ /* wrong sign and count number of values which are different from zero for
+ * sign bit decoding [which happens in next state] */
+ cntSign = 0;
+ for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
+ dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
+ if (*pQuantVal++ != 0) {
+ cntSign += 1;
+ }
+ }
+
+ if (cntSign == 0) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ } else {
+ pCntSign[codewordOffset] = cntSign; /* write sign count result into
+ codewordsideinfo of current
+ codeword */
+ pSta[codewordOffset] = BODY_SIGN__SIGN; /* change state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ treeNode = *(
+ pCurrentTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+ iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
+ decoding of codeword body not finished
+ yet */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY;
+ return BODY_SIGN__BODY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This state decodes the sign bits belonging to a codeword. The
+state is called as often in different "trials" until pCntSgn[codewordOffset] is
+zero.
+-----------------------------------------------------------------------------------------------
+ output: The two or four quantizes spectral values (written in previous
+state) have now the correct sign.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UCHAR carryBit;
+ UINT iQSC;
+ UCHAR cntSign;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ /*pCodebook = */
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+
+ iQSC = iResultPointer[codewordOffset];
+ cntSign = pCntSign[codewordOffset];
+
+ /* loop for sign bit decoding */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+ cntSign -=
+ 1; /* decrement sign counter because one sign bit has been read */
+
+ /* search for a line (which was decoded in previous state) which is not
+ * zero. [This value will get a sign] */
+ while (pResultBase[iQSC] == (FIXP_DBL)0) {
+ if (++iQSC >= 1024) { /* points to current value different from zero */
+ return BODY_SIGN__SIGN;
+ }
+ }
+
+ /* put sign together with line; if carryBit is zero, the sign is ok already;
+ * no write operation necessary in this case */
+ if (carryBit != 0) {
+ pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
+ }
+
+ iQSC++; /* update pointer to next (maybe valid) value */
+
+ if (cntSign == 0) { /* if (cntSign==0) ==> set state CODEWORD_DECODED */
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ break; /* whole nonPCW-Body and according sign bits are decoded */
+ }
+ }
+ pCntSign[codewordOffset] = cntSign;
+ iResultPointer[codewordOffset] = iQSC; /* store updated pResultPointer */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN;
+ return BODY_SIGN__SIGN;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decodes the codeword body in case of codebook is 11. Writes
+out resulting two or four lines [with probably wrong sign] and counts the number
+of lines, which are different form zero. This information is needed in next
+ state where sign bits will be decoded, if necessary.
+ If sign bit counter cntSign is zero, no sign bits are needed
+and codeword is decoded completely.
+-----------------------------------------------------------------------------------------------
+ output: Two lines (quantizes spectral coefficients) which are probably
+wrong. The sign may be wrong and if one or two values is/are 16, the following
+states will decode the escape sequence to correct the values which are wirtten
+here.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT codewordOffset;
+
+ UCHAR carryBit;
+ UINT iQSC;
+ UINT cntSign;
+ UINT dimCntr;
+ UINT treeNode;
+ SCHAR *pSta;
+ UINT branchNode;
+ UINT branchValue;
+ const UINT *pCurrentTree;
+ const SCHAR *pQuantValBase;
+ const SCHAR *pQuantVal;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ treeNode = iNode[codewordOffset];
+ pCurrentTree = aHuffTable[ESCAPE_CODEBOOK];
+
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* make a step in tree */
+ CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
+
+ /* if end of branch reached write out lines and count bits needed for sign,
+ * otherwise store node in codeword sideinfo */
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set body complete */
+
+ /* body completely decoded; branchValue is valid */
+ /* set pQuantVol to first (of two or four) quantized spectral coefficients
+ */
+ pQuantValBase = aQuantTable[ESCAPE_CODEBOOK]; /* get base address of
+ quantized values
+ belonging to current
+ codebook */
+ pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
+ line [of 2 or 4 quantized
+ values] */
+
+ /* make backup from original resultPointer in node storage for state
+ * BODY_SIGN_ESC__SIGN */
+ iNode[codewordOffset] = iResultPointer[codewordOffset];
+
+ /* get position of first line for writing result */
+ iQSC = iResultPointer[codewordOffset];
+
+ /* codeword decoding result is written out here: Write out 2 or 4
+ * quantized spectral values with probably */
+ /* wrong sign and count number of values which are different from zero for
+ * sign bit decoding [which happens in next state] */
+ cntSign = 0;
+
+ for (dimCntr = DIMENSION_OF_ESCAPE_CODEBOOK; dimCntr != 0; dimCntr--) {
+ pResultBase[iQSC++] =
+ (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
+ if (*pQuantVal++ != 0) {
+ cntSign += 1;
+ }
+ }
+
+ if (cntSign == 0) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ /* codeword decoded */
+ } else {
+ /* write sign count result into codewordsideinfo of current codeword */
+ pCntSign[codewordOffset] = cntSign;
+ pSta[codewordOffset] = BODY_SIGN_ESC__SIGN; /* change state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* the last reinitialzation
+ of for loop counter (see
+ above) is done here */
+ break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
+ decoded */
+ } else { /* body is not decoded completely: */
+ /* update treeNode for further step in decoding tree and store updated
+ * treeNode because maybe no more bits left in segment */
+ treeNode = *(pCurrentTree + branchValue);
+ iNode[codewordOffset] = treeNode;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY;
+ return BODY_SIGN_ESC__BODY;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: This state decodes the sign bits, if a codeword of codebook 11
+needs some. A flag named 'flagB' in codeword sideinfo is set, if the second line
+of quantized spectral values is 16. The 'flagB' is used in case of decoding of a
+escape sequence is necessary as far as the second line is concerned.
+
+ If only the first line needs an escape sequence, the flagB is
+cleared. If only the second line needs an escape sequence, the flagB is not
+used.
+
+ For storing sideinfo in case of escape sequence decoding one
+single word can be used for both escape sequences because they are decoded not
+at the same time:
+
+
+ bit 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
+4 3 2 1 0
+ ===== == == =========== ===========
+=================================== ^ ^ ^ ^ ^
+^ | | | | | | res. flagA flagB
+escapePrefixUp escapePrefixDown escapeWord
+
+-----------------------------------------------------------------------------------------------
+ output: Two lines with correct sign. If one or two values is/are 16,
+the lines are not valid, otherwise they are.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ UINT *iNode;
+ UCHAR *pCntSign;
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+
+ UINT iQSC;
+ UCHAR cntSign;
+ UINT flagA;
+ UINT flagB;
+ UINT flags;
+ UCHAR carryBit;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ iNode = pHcr->nonPcwSideinfo.iNode;
+ pCntSign = pHcr->nonPcwSideinfo.pCntSign;
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ iQSC = iResultPointer[codewordOffset];
+ cntSign = pCntSign[codewordOffset];
+
+ /* loop for sign bit decoding */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* decrement sign counter because one sign bit has been read */
+ cntSign -= 1;
+ pCntSign[codewordOffset] = cntSign;
+
+ /* get a quantized spectral value (which was decoded in previous state)
+ * which is not zero. [This value will get a sign] */
+ while (pResultBase[iQSC] == (FIXP_DBL)0) {
+ if (++iQSC >= 1024) {
+ return BODY_SIGN_ESC__SIGN;
+ }
+ }
+ iResultPointer[codewordOffset] = iQSC;
+
+ /* put negative sign together with quantized spectral value; if carryBit is
+ * zero, the sign is ok already; no write operation necessary in this case
+ */
+ if (carryBit != 0) {
+ pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
+ }
+ iQSC++; /* update index to next (maybe valid) value */
+ iResultPointer[codewordOffset] = iQSC;
+
+ if (cntSign == 0) {
+ /* all sign bits are decoded now */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+
+ /* check decoded values if codeword is decoded: Check if one or two escape
+ * sequences 16 follow */
+
+ /* step 0 */
+ /* restore pointer to first decoded quantized value [ = original
+ * pResultPointr] from index iNode prepared in State_BODY_SIGN_ESC__BODY
+ */
+ iQSC = iNode[codewordOffset];
+
+ /* step 1 */
+ /* test first value if escape sequence follows */
+ flagA = 0; /* for first possible escape sequence */
+ if (fixp_abs(pResultBase[iQSC++]) == (FIXP_DBL)ESCAPE_VALUE) {
+ flagA = 1;
+ }
+
+ /* step 2 */
+ /* test second value if escape sequence follows */
+ flagB = 0; /* for second possible escape sequence */
+ if (fixp_abs(pResultBase[iQSC]) == (FIXP_DBL)ESCAPE_VALUE) {
+ flagB = 1;
+ }
+
+ /* step 3 */
+ /* evaluate flag result and go on if necessary */
+ if (!flagA && !flagB) {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ } else {
+ /* at least one of two lines is 16 */
+ /* store both flags at correct positions in non PCW codeword sideinfo
+ * pEscapeSequenceInfo[codewordOffset] */
+ flags = flagA << POSITION_OF_FLAG_A;
+ flags |= (flagB << POSITION_OF_FLAG_B);
+ pEscapeSequenceInfo[codewordOffset] = flags;
+
+ /* set next state */
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+
+ /* set result pointer to the first line of the two decoded lines */
+ iResultPointer[codewordOffset] = iNode[codewordOffset];
+
+ if (!flagA && flagB) {
+ /* update pResultPointr ==> state Stat_BODY_SIGN_ESC__ESC_WORD writes
+ * to correct position. Second value is the one and only escape value
+ */
+ iQSC = iResultPointer[codewordOffset];
+ iQSC++;
+ iResultPointer[codewordOffset] = iQSC;
+ }
+
+ } /* at least one of two lines is 16 */
+ break; /* nonPCW-Body at cb 11 and according sign bits are decoded */
+
+ } /* if ( cntSign == 0 ) */
+ } /* loop over remaining Bits in segment */
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN;
+ return BODY_SIGN_ESC__SIGN;
+ }
+ }
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode escape prefix of first or second escape sequence. The
+escape prefix consists of ones. The following zero is also decoded here.
+-----------------------------------------------------------------------------------------------
+ output: If the single separator-zero which follows the
+escape-prefix-ones is not yet decoded: The value 'escapePrefixUp' in word
+pEscapeSequenceInfo[codewordOffset] is updated.
+
+ If the single separator-zero which follows the
+escape-prefix-ones is decoded: Two updated values 'escapePrefixUp' and
+'escapePrefixDown' in word pEscapeSequenceInfo[codewordOffset]. This State is
+finished. Switch to next state.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT segmentOffset;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+ UCHAR carryBit;
+ UINT escapePrefixUp;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ escapePrefixUp =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
+ LSB_ESCAPE_PREFIX_UP;
+
+ /* decode escape prefix */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* count ones and store sum in escapePrefixUp */
+ if (carryBit == 1) {
+ escapePrefixUp += 1; /* update conter for ones */
+
+ /* store updated counter in sideinfo of current codeword */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixUp */
+ escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
+ } else { /* separator [zero] reached */
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+ escapePrefixUp +=
+ 4; /* if escape_separator '0' appears, add 4 and ==> break */
+
+ /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
+ * position escapePrefixUp */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixUp */
+ escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
+
+ /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
+ * position escapePrefixDown */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
+ escapePrefixUp <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixUp; /* insert new escapePrefixDown */
+
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from separate
+ array of cw-sideinfo */
+ break;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
+ return BODY_SIGN_ESC__ESC_PREFIX;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Decode escapeWord of escape sequence. If the escape sequence
+is decoded completely, assemble quantized-spectral-escape-coefficient and
+replace the previous decoded 16 by the new value. Test flagB. If flagB is set,
+the second escape sequence must be decoded. If flagB is not set, the codeword is
+decoded and the state machine is switched off.
+-----------------------------------------------------------------------------------------------
+ output: Two lines with valid sign. At least one of both lines has got
+the correct value.
+-----------------------------------------------------------------------------------------------
+ return: 0
+--------------------------------------------------------------------------------------------
+*/
+UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) {
+ H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
+ SCHAR *pRemainingBitsInSegment;
+ INT *pLeftStartOfSegment;
+ INT *pRightStartOfSegment;
+ UCHAR readDirection;
+ UINT *pSegmentBitfield;
+ UINT *pCodewordBitfield;
+ UINT segmentOffset;
+
+ FIXP_DBL *pResultBase;
+ USHORT *iResultPointer;
+ UINT *pEscapeSequenceInfo;
+ UINT codewordOffset;
+
+ UINT escapeWord;
+ UINT escapePrefixDown;
+ UINT escapePrefixUp;
+ UCHAR carryBit;
+ UINT iQSC;
+ INT sign;
+ UINT flagA;
+ UINT flagB;
+ SCHAR *pSta;
+
+ pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
+ pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
+ pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
+ readDirection = pHcr->segmentInfo.readDirection;
+ pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
+ pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
+ segmentOffset = pHcr->segmentInfo.segmentOffset;
+
+ pResultBase = pHcr->nonPcwSideinfo.pResultBase;
+ iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
+ pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
+ codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
+ pSta = pHcr->nonPcwSideinfo.pSta;
+
+ escapeWord = pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_WORD;
+ escapePrefixDown =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_DOWN) >>
+ LSB_ESCAPE_PREFIX_DOWN;
+
+ /* decode escape word */
+ for (; pRemainingBitsInSegment[segmentOffset] > 0;
+ pRemainingBitsInSegment[segmentOffset] -= 1) {
+ carryBit = HcrGetABitFromBitstream(
+ bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
+ &pRightStartOfSegment[segmentOffset], readDirection);
+
+ /* build escape word */
+ escapeWord <<=
+ 1; /* left shift previous decoded part of escapeWord by on bit */
+ escapeWord = escapeWord | carryBit; /* assemble escape word by bitwise or */
+
+ /* decrement counter for length of escape word because one more bit was
+ * decoded */
+ escapePrefixDown -= 1;
+
+ /* store updated escapePrefixDown */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
+ escapePrefixDown <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapePrefixDown; /* insert new escapePrefixDown */
+ escapePrefixDown >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back */
+
+ /* store updated escapeWord */
+ pEscapeSequenceInfo[codewordOffset] &=
+ ~MASK_ESCAPE_WORD; /* delete old escapeWord */
+ pEscapeSequenceInfo[codewordOffset] |=
+ escapeWord; /* insert new escapeWord */
+
+ if (escapePrefixDown == 0) {
+ pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
+ for loop counter (see
+ above) is done here */
+
+ /* escape sequence decoded. Assemble escape-line and replace original line
+ */
+
+ /* step 0 */
+ /* derive sign */
+ iQSC = iResultPointer[codewordOffset];
+ sign = (pResultBase[iQSC] >= (FIXP_DBL)0)
+ ? 1
+ : -1; /* get sign of escape value 16 */
+
+ /* step 1 */
+ /* get escapePrefixUp */
+ escapePrefixUp =
+ (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
+ LSB_ESCAPE_PREFIX_UP;
+
+ /* step 2 */
+ /* calculate escape value */
+ pResultBase[iQSC] =
+ (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord));
+
+ /* get both flags from sideinfo (flags are not shifted to the
+ * lsb-position) */
+ flagA = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_A;
+ flagB = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_B;
+
+ /* step 3 */
+ /* clear the whole escape sideinfo word */
+ pEscapeSequenceInfo[codewordOffset] = 0;
+
+ /* change state in dependence of flag flagB */
+ if (flagA != 0) {
+ /* first escape sequence decoded; previous decoded 16 has been replaced
+ * by valid line */
+
+ /* clear flagA in sideinfo word because this escape sequence has already
+ * beed decoded */
+ pEscapeSequenceInfo[codewordOffset] &= ~MASK_FLAG_A;
+
+ if (flagB == 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield
+ and switch off
+ statemachine */
+ } else {
+ /* updated pointer to next and last 16 */
+ iQSC++;
+ iResultPointer[codewordOffset] = iQSC;
+
+ /* change state */
+ pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
+ pHcr->nonPcwSideinfo.pState =
+ aStateConstant2State[pSta[codewordOffset]]; /* get state from
+ separate array of
+ cw-sideinfo */
+ }
+ } else {
+ ClearBitFromBitfield(
+ &(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pCodewordBitfield); /* clear a bit in bitfield and switch off
+ statemachine */
+ }
+ break;
+ }
+ }
+
+ if (pRemainingBitsInSegment[segmentOffset] <= 0) {
+ ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
+ pSegmentBitfield); /* clear a bit in bitfield and
+ switch off statemachine */
+
+ if (pRemainingBitsInSegment[segmentOffset] < 0) {
+ pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD;
+ return BODY_SIGN_ESC__ESC_WORD;
+ }
+ }
+
+ return STOP_THIS_STATE;
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_hcrs.h b/fdk-aac/libAACdec/src/aacdec_hcrs.h
new file mode 100644
index 0000000..acb2f40
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_hcrs.h
@@ -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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: HCR Decoder: Defines of state-constants, masks and
+ state-prototypes
+
+*******************************************************************************/
+
+#ifndef AACDEC_HCRS_H
+#define AACDEC_HCRS_H
+
+#include "FDK_bitstream.h"
+#include "aacdec_hcr_types.h"
+/* The four different kinds of types of states are: */
+/* different states are defined as constants */ /* start middle=self next
+ stop */
+#define STOP_THIS_STATE \
+ 0 /* */
+#define BODY_ONLY \
+ 1 /* X X X */
+#define BODY_SIGN__BODY \
+ 2 /* X X X X [stop if no sign] */
+#define BODY_SIGN__SIGN \
+ 3 /* X X [stop if sign bits decoded] */
+#define BODY_SIGN_ESC__BODY \
+ 4 /* X X X X [stop if no sign] */
+#define BODY_SIGN_ESC__SIGN \
+ 5 /* X X X [stop if no escape sequence] */
+#define BODY_SIGN_ESC__ESC_PREFIX \
+ 6 /* X X */
+#define BODY_SIGN_ESC__ESC_WORD \
+ 7 /* X X X [stop if abs(second qsc) != 16] */
+
+/* examples: */
+
+/* BODY_ONLY means only the codeword body will be decoded; no
+ * sign bits will follow and no escapesequence will follow */
+
+/* BODY_SIGN__BODY means that the codeword consists of two parts;
+ * body and sign part. The part '__BODY' after the two underscores shows */
+/* that the bits which are currently decoded belong
+ * to the '__BODY' of the codeword and not to the sign part. */
+
+/* BODY_SIGN_ESC__ESC_PB means that the codeword consists of three parts;
+ * body, sign and (here: two) escape sequences; */
+/* P = Prefix = ones */
+/* W = Escape Word */
+/* A = first possible (of two) Escape sequeces */
+/* B = second possible (of two) Escape sequeces */
+/* The part after the two underscores shows that
+ * the current bits which are decoded belong to the '__ESC_PB' - part of the */
+/* codeword. That means the body and the sign bits
+ * are decoded completely and the bits which are decoded now belong to */
+/* the escape sequence [P = prefix; B=second
+ * possible escape sequence] */
+
+#define MSB_31_MASK 0x80000000 /* masks MSB (= Bit 31) in a 32 bit word */
+#define DIMENSION_OF_ESCAPE_CODEBOOK 2 /* for cb >= 11 is dimension 2 */
+#define ESCAPE_CODEBOOK 11
+
+#define MASK_ESCAPE_PREFIX_UP 0x000F0000
+#define LSB_ESCAPE_PREFIX_UP 16
+
+#define MASK_ESCAPE_PREFIX_DOWN 0x0000F000
+#define LSB_ESCAPE_PREFIX_DOWN 12
+
+#define MASK_ESCAPE_WORD 0x00000FFF
+#define MASK_FLAG_A 0x00200000
+#define MASK_FLAG_B 0x00100000
+
+extern void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO hHcr);
+
+UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM, void*);
+UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM, void*);
+
+#endif /* AACDEC_HCRS_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_pns.cpp b/fdk-aac/libAACdec/src/aacdec_pns.cpp
new file mode 100644
index 0000000..432cd4e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_pns.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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: perceptual noise substitution tool
+
+*******************************************************************************/
+
+#include "aacdec_pns.h"
+
+#include "aac_ram.h"
+#include "aac_rom.h"
+#include "channelinfo.h"
+#include "block.h"
+#include "FDK_bitstream.h"
+
+#include "genericStds.h"
+
+#define NOISE_OFFSET 90 /* cf. ISO 14496-3 p. 175 */
+
+/*!
+ \brief Reset InterChannel and PNS data
+
+ The function resets the InterChannel and PNS data
+*/
+void CPns_ResetData(CPnsData *pPnsData,
+ CPnsInterChannelData *pPnsInterChannelData) {
+ FDK_ASSERT(pPnsData != NULL);
+ FDK_ASSERT(pPnsInterChannelData != NULL);
+ /* Assign pointer always, since pPnsData is not persistent data */
+ pPnsData->pPnsInterChannelData = pPnsInterChannelData;
+ pPnsData->PnsActive = 0;
+ pPnsData->CurrentEnergy = 0;
+
+ FDKmemclear(pPnsData->pnsUsed, (8 * 16) * sizeof(UCHAR));
+ FDKmemclear(pPnsInterChannelData->correlated, (8 * 16) * sizeof(UCHAR));
+}
+
+/*!
+ \brief Update PNS noise generator state.
+
+ The function sets the seed for PNS noise generation.
+ It can be used to link two or more channels in terms of PNS.
+*/
+void CPns_UpdateNoiseState(CPnsData *pPnsData, INT *currentSeed,
+ INT *randomSeed) {
+ /* use pointer because seed has to be
+ same, left and right channel ! */
+ pPnsData->currentSeed = currentSeed;
+ pPnsData->randomSeed = randomSeed;
+}
+
+/*!
+ \brief Indicates if PNS is used
+
+ The function returns a value indicating whether PNS is used or not
+ acordding to the noise energy
+
+ \return PNS used
+*/
+int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band) {
+ unsigned pns_band = group * 16 + band;
+
+ return pPnsData->pnsUsed[pns_band] & (UCHAR)1;
+}
+
+/*!
+ \brief Set correlation
+
+ The function activates the noise correlation between the channel pair
+*/
+void CPns_SetCorrelation(CPnsData *pPnsData, const int group, const int band,
+ const int outofphase) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ pInterChannelData->correlated[pns_band] = (outofphase) ? 3 : 1;
+}
+
+/*!
+ \brief Indicates if correlation is used
+
+ The function indicates if the noise correlation between the channel pair
+ is activated
+
+ \return PNS is correlated
+*/
+static int CPns_IsCorrelated(const CPnsData *pPnsData, const int group,
+ const int band) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ return (pInterChannelData->correlated[pns_band] & 0x01) ? 1 : 0;
+}
+
+/*!
+ \brief Indicates if correlated out of phase mode is used.
+
+ The function indicates if the noise correlation between the channel pair
+ is activated in out-of-phase mode.
+
+ \return PNS is out-of-phase
+*/
+static int CPns_IsOutOfPhase(const CPnsData *pPnsData, const int group,
+ const int band) {
+ CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData;
+ unsigned pns_band = group * 16 + band;
+
+ return (pInterChannelData->correlated[pns_band] & 0x02) ? 1 : 0;
+}
+
+/*!
+ \brief Read PNS information
+
+ The function reads the PNS information from the bitstream
+*/
+void CPns_Read(CPnsData *pPnsData, HANDLE_FDK_BITSTREAM bs,
+ const CodeBookDescription *hcb, SHORT *pScaleFactor,
+ UCHAR global_gain, int band, int group /* = 0 */) {
+ int delta;
+ UINT pns_band = group * 16 + band;
+
+ if (pPnsData->PnsActive) {
+ /* Next PNS band case */
+ delta = CBlock_DecodeHuffmanWord(bs, hcb) - 60;
+ } else {
+ /* First PNS band case */
+ int noiseStartValue = FDKreadBits(bs, 9);
+
+ delta = noiseStartValue - 256;
+ pPnsData->PnsActive = 1;
+ pPnsData->CurrentEnergy = global_gain - NOISE_OFFSET;
+ }
+
+ pPnsData->CurrentEnergy += delta;
+ pScaleFactor[pns_band] = pPnsData->CurrentEnergy;
+
+ pPnsData->pnsUsed[pns_band] = 1;
+}
+
+/**
+ * \brief Generate a vector of noise of given length. The noise values are
+ * scaled in order to yield a noise energy of 1.0
+ * \param spec pointer to were the noise values will be written to.
+ * \param size amount of noise values to be generated.
+ * \param pRandomState pointer to the state of the random generator being used.
+ * \return exponent of generated noise vector.
+ */
+static int GenerateRandomVector(FIXP_DBL *RESTRICT spec, int size,
+ int *pRandomState) {
+ int i, invNrg_e = 0, nrg_e = 0;
+ FIXP_DBL invNrg_m, nrg_m = FL2FXCONST_DBL(0.0f);
+ FIXP_DBL *RESTRICT ptr = spec;
+ int randomState = *pRandomState;
+
+#define GEN_NOISE_NRG_SCALE 7
+
+ /* Generate noise and calculate energy. */
+ for (i = 0; i < size; i++) {
+ randomState =
+ (((INT64)1664525 * randomState) + (INT64)1013904223) & 0xFFFFFFFF;
+ nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState >> GEN_NOISE_NRG_SCALE);
+ *ptr++ = (FIXP_DBL)randomState;
+ }
+ nrg_e = GEN_NOISE_NRG_SCALE * 2 + 1;
+
+ /* weight noise with = 1 / sqrt_nrg; */
+ invNrg_m = invSqrtNorm2(nrg_m << 1, &invNrg_e);
+ invNrg_e += -((nrg_e - 1) >> 1);
+
+ for (i = size; i--;) {
+ spec[i] = fMult(spec[i], invNrg_m);
+ }
+
+ /* Store random state */
+ *pRandomState = randomState;
+
+ return invNrg_e;
+}
+
+static void ScaleBand(FIXP_DBL *RESTRICT spec, int size, int scaleFactor,
+ int specScale, int noise_e, int out_of_phase) {
+ int i, shift, sfExponent;
+ FIXP_DBL sfMatissa;
+
+ /* Get gain from scale factor value = 2^(scaleFactor * 0.25) */
+ sfMatissa = MantissaTable[scaleFactor & 0x03][0];
+ /* sfExponent = (scaleFactor >> 2) + ExponentTable[scaleFactor & 0x03][0]; */
+ /* Note: ExponentTable[scaleFactor & 0x03][0] is always 1. */
+ sfExponent = (scaleFactor >> 2) + 1;
+
+ if (out_of_phase != 0) {
+ sfMatissa = -sfMatissa;
+ }
+
+ /* +1 because of fMultDiv2 below. */
+ shift = sfExponent - specScale + 1 + noise_e;
+
+ /* Apply gain to noise values */
+ if (shift >= 0) {
+ shift = fixMin(shift, DFRACT_BITS - 1);
+ for (i = size; i-- != 0;) {
+ spec[i] = fMultDiv2(spec[i], sfMatissa) << shift;
+ }
+ } else {
+ shift = fixMin(-shift, DFRACT_BITS - 1);
+ for (i = size; i-- != 0;) {
+ spec[i] = fMultDiv2(spec[i], sfMatissa) >> shift;
+ }
+ }
+}
+
+/*!
+ \brief Apply PNS
+
+ The function applies PNS (i.e. it generates noise) on the bands
+ flagged as noisy bands
+
+*/
+void CPns_Apply(const CPnsData *pPnsData, const CIcsInfo *pIcsInfo,
+ SPECTRAL_PTR pSpectrum, const SHORT *pSpecScale,
+ const SHORT *pScaleFactor,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const int channel) {
+ if (pPnsData->PnsActive) {
+ const short *BandOffsets =
+ GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo);
+
+ int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(pIcsInfo);
+
+ for (int window = 0, group = 0; group < GetWindowGroups(pIcsInfo);
+ group++) {
+ for (int groupwin = 0; groupwin < GetWindowGroupLength(pIcsInfo, group);
+ groupwin++, window++) {
+ FIXP_DBL *spectrum = SPEC(pSpectrum, window, granuleLength);
+
+ for (int band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ if (CPns_IsPnsUsed(pPnsData, group, band)) {
+ UINT pns_band = window * 16 + band;
+
+ int bandWidth = BandOffsets[band + 1] - BandOffsets[band];
+ int noise_e;
+
+ FDK_ASSERT(bandWidth >= 0);
+
+ if (channel > 0 && CPns_IsCorrelated(pPnsData, group, band)) {
+ noise_e =
+ GenerateRandomVector(spectrum + BandOffsets[band], bandWidth,
+ &pPnsData->randomSeed[pns_band]);
+ } else {
+ pPnsData->randomSeed[pns_band] = *pPnsData->currentSeed;
+
+ noise_e = GenerateRandomVector(spectrum + BandOffsets[band],
+ bandWidth, pPnsData->currentSeed);
+ }
+
+ int outOfPhase = CPns_IsOutOfPhase(pPnsData, group, band);
+
+ ScaleBand(spectrum + BandOffsets[band], bandWidth,
+ pScaleFactor[group * 16 + band], pSpecScale[window],
+ noise_e, outOfPhase);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_pns.h b/fdk-aac/libAACdec/src/aacdec_pns.h
new file mode 100644
index 0000000..45cd989
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_pns.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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: perceptual noise substitution tool
+
+*******************************************************************************/
+
+#ifndef AACDEC_PNS_H
+#define AACDEC_PNS_H
+
+#include "common_fix.h"
+
+#define NO_OFBANDS ((8 * 16))
+
+typedef struct {
+ UCHAR correlated[NO_OFBANDS];
+} CPnsInterChannelData;
+
+typedef struct {
+ CPnsInterChannelData *pPnsInterChannelData;
+ UCHAR pnsUsed[NO_OFBANDS];
+ int CurrentEnergy;
+ UCHAR PnsActive;
+ INT *currentSeed;
+ INT *randomSeed;
+} CPnsData;
+
+void CPns_UpdateNoiseState(CPnsData *pPnsData, INT *currentSeed,
+ INT *randomSeed);
+
+void CPns_ResetData(CPnsData *pPnsData,
+ CPnsInterChannelData *pPnsInterChannelData);
+
+#endif /* #ifndef AACDEC_PNS_H */
diff --git a/fdk-aac/libAACdec/src/aacdec_tns.cpp b/fdk-aac/libAACdec/src/aacdec_tns.cpp
new file mode 100644
index 0000000..fb3fe33
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_tns.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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: temporal noise shaping tool
+
+*******************************************************************************/
+
+#include "aacdec_tns.h"
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "channelinfo.h"
+
+#include "FDK_lpc.h"
+
+#define TNS_MAXIMUM_ORDER_AAC 12
+
+/*!
+ \brief Reset tns data
+
+ The function resets the tns data
+
+ \return none
+*/
+void CTns_Reset(CTnsData *pTnsData) {
+ /* Note: the following FDKmemclear should not be required. */
+ FDKmemclear(pTnsData->Filter,
+ TNS_MAX_WINDOWS * TNS_MAXIMUM_FILTERS * sizeof(CFilter));
+ FDKmemclear(pTnsData->NumberOfFilters, TNS_MAX_WINDOWS * sizeof(UCHAR));
+ pTnsData->DataPresent = 0;
+ pTnsData->Active = 0;
+}
+
+void CTns_ReadDataPresentFlag(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ CTnsData *pTnsData) /*!< pointer to aac decoder channel info */
+{
+ pTnsData->DataPresent = (UCHAR)FDKreadBits(bs, 1);
+}
+
+/*!
+ \brief Read tns data from bitstream
+
+ The function reads the elements for tns from
+ the bitstream.
+
+ \return none
+*/
+AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData,
+ const CIcsInfo *pIcsInfo, const UINT flags) {
+ UCHAR n_filt, order;
+ UCHAR length, coef_res, coef_compress;
+ UCHAR window;
+ UCHAR wins_per_frame;
+ UCHAR isLongFlag;
+ UCHAR start_window;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ if (!pTnsData->DataPresent) {
+ return ErrorStatus;
+ }
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ isLongFlag = IsLongBlock(pIcsInfo);
+ }
+
+ pTnsData->GainLd = 0;
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ pTnsData->NumberOfFilters[window] = n_filt =
+ (UCHAR)FDKreadBits(bs, isLongFlag ? 2 : 1);
+
+ if (n_filt) {
+ int index;
+ UCHAR nextstopband;
+
+ coef_res = (UCHAR)FDKreadBits(bs, 1);
+
+ nextstopband = GetScaleFactorBandsTotal(pIcsInfo);
+
+ for (index = 0; index < n_filt; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ length = (UCHAR)FDKreadBits(bs, isLongFlag ? 6 : 4);
+
+ if (length > nextstopband) {
+ length = nextstopband;
+ }
+
+ filter->StartBand = nextstopband - length;
+ filter->StopBand = nextstopband;
+ nextstopband = filter->StartBand;
+
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ /* max(Order) = 15 (long), 7 (short) */
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 4 : 3);
+ } else {
+ filter->Order = order = (UCHAR)FDKreadBits(bs, isLongFlag ? 5 : 3);
+
+ if (filter->Order > TNS_MAXIMUM_ORDER) {
+ ErrorStatus = AAC_DEC_TNS_READ_ERROR;
+ return ErrorStatus;
+ }
+ }
+
+ FDK_ASSERT(order <=
+ TNS_MAXIMUM_ORDER); /* avoid illegal memory access */
+ if (order) {
+ UCHAR coef, s_mask;
+ UCHAR i;
+ SCHAR n_mask;
+
+ static const UCHAR sgn_mask[] = {0x2, 0x4, 0x8};
+ static const SCHAR neg_mask[] = {~0x3, ~0x7, ~0xF};
+
+ filter->Direction = FDKreadBits(bs, 1) ? -1 : 1;
+
+ coef_compress = (UCHAR)FDKreadBits(bs, 1);
+
+ filter->Resolution = coef_res + 3;
+
+ s_mask = sgn_mask[coef_res + 1 - coef_compress];
+ n_mask = neg_mask[coef_res + 1 - coef_compress];
+
+ for (i = 0; i < order; i++) {
+ coef = (UCHAR)FDKreadBits(bs, filter->Resolution - coef_compress);
+ filter->Coeff[i] = (coef & s_mask) ? (coef | n_mask) : coef;
+ }
+ pTnsData->GainLd = 4;
+ }
+ }
+ }
+ }
+
+ pTnsData->Active = 1;
+
+ return ErrorStatus;
+}
+
+void CTns_ReadDataPresentUsac(HANDLE_FDK_BITSTREAM hBs, CTnsData *pTnsData0,
+ CTnsData *pTnsData1, UCHAR *ptns_on_lr,
+ const CIcsInfo *pIcsInfo, const UINT flags,
+ const UINT elFlags, const int fCommonWindow) {
+ int common_tns = 0;
+
+ if (fCommonWindow) {
+ common_tns = FDKreadBit(hBs);
+ }
+ { *ptns_on_lr = FDKreadBit(hBs); }
+ if (common_tns) {
+ pTnsData0->DataPresent = 1;
+ CTns_Read(hBs, pTnsData0, pIcsInfo, flags);
+
+ pTnsData0->DataPresent = 0;
+ pTnsData0->Active = 1;
+ *pTnsData1 = *pTnsData0;
+ } else {
+ int tns_present_both;
+
+ tns_present_both = FDKreadBit(hBs);
+ if (tns_present_both) {
+ pTnsData0->DataPresent = 1;
+ pTnsData1->DataPresent = 1;
+ } else {
+ pTnsData1->DataPresent = FDKreadBit(hBs);
+ pTnsData0->DataPresent = !pTnsData1->DataPresent;
+ }
+ }
+}
+
+/*!
+ \brief Apply tns to spectral lines
+
+ The function applies the tns to the spectrum,
+
+ \return none
+*/
+void CTns_Apply(CTnsData *RESTRICT pTnsData, /*!< pointer to aac decoder info */
+ const CIcsInfo *pIcsInfo, SPECTRAL_PTR pSpectralCoefficient,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const UCHAR nbands,
+ const UCHAR igf_active, const UINT flags) {
+ int window, index, start, stop, size, start_window, wins_per_frame;
+
+ if (pTnsData->Active) {
+ C_AALLOC_SCRATCH_START(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+
+ {
+ start_window = 0;
+ wins_per_frame = GetWindowsPerFrame(pIcsInfo);
+ }
+
+ for (window = start_window; window < wins_per_frame; window++) {
+ FIXP_DBL *pSpectrum;
+
+ { pSpectrum = SPEC(pSpectralCoefficient, window, granuleLength); }
+
+ for (index = 0; index < pTnsData->NumberOfFilters[window]; index++) {
+ CFilter *filter = &pTnsData->Filter[window][index];
+
+ if (filter->Order > 0) {
+ FIXP_TCC *pCoeff;
+ UCHAR tns_max_bands;
+
+ pCoeff = coeff;
+ if (filter->Resolution == 3) {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff3[filter->Coeff[i] + 4];
+ } else {
+ int i;
+ for (i = 0; i < filter->Order; i++)
+ *pCoeff++ = FDKaacDec_tnsCoeff4[filter->Coeff[i] + 8];
+ }
+
+ switch (granuleLength) {
+ case 480:
+ tns_max_bands =
+ tns_max_bands_tbl_480[pSamplingRateInfo->samplingRateIndex];
+ break;
+ case 512:
+ tns_max_bands =
+ tns_max_bands_tbl_512[pSamplingRateInfo->samplingRateIndex];
+ break;
+ default:
+ tns_max_bands = GetMaximumTnsBands(
+ pIcsInfo, pSamplingRateInfo->samplingRateIndex);
+ /* See redefinition of TNS_MAX_BANDS table */
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pSamplingRateInfo->samplingRateIndex > 5)) {
+ tns_max_bands += 1;
+ }
+ break;
+ }
+
+ start = fixMin(fixMin(filter->StartBand, tns_max_bands), nbands);
+
+ start = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[start];
+
+ if (igf_active) {
+ stop = fixMin(filter->StopBand, nbands);
+ } else {
+ stop = fixMin(fixMin(filter->StopBand, tns_max_bands), nbands);
+ }
+
+ stop = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[stop];
+
+ size = stop - start;
+
+ if (size) {
+ C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+
+ FDKmemclear(state, TNS_MAXIMUM_ORDER * sizeof(FIXP_DBL));
+ CLpc_SynthesisLattice(pSpectrum + start, size, 0, 0,
+ filter->Direction, coeff, filter->Order,
+ state);
+
+ C_ALLOC_SCRATCH_END(state, FIXP_DBL, TNS_MAXIMUM_ORDER)
+ }
+ }
+ }
+ }
+ C_AALLOC_SCRATCH_END(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER)
+ }
+}
diff --git a/fdk-aac/libAACdec/src/aacdec_tns.h b/fdk-aac/libAACdec/src/aacdec_tns.h
new file mode 100644
index 0000000..1a63bed
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdec_tns.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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: temporal noise shaping tool
+
+*******************************************************************************/
+
+#ifndef AACDEC_TNS_H
+#define AACDEC_TNS_H
+
+#include "common_fix.h"
+
+enum {
+ TNS_MAX_WINDOWS = 8, /* 8 */
+ TNS_MAXIMUM_FILTERS = 3
+};
+
+/* TNS_MAXIMUM_ORDER (for memory allocation)
+ 12 for AAC-LC and AAC-SSR. Set to 20 for AAC-Main (AOT 1). Some broken
+ encoders also do order 20 for AAC-LC :( 15 for USAC (AOT 42)
+*/
+#define TNS_MAXIMUM_ORDER (20)
+
+#if (TNS_MAXIMUM_ORDER < 15)
+#error USAC: TNS filter order up 15 can be signaled!
+#endif
+
+typedef struct {
+ SCHAR Coeff[TNS_MAXIMUM_ORDER];
+
+ UCHAR StartBand;
+ UCHAR StopBand;
+
+ SCHAR Direction;
+ SCHAR Resolution;
+
+ UCHAR Order;
+} CFilter;
+
+typedef struct {
+ CFilter Filter[TNS_MAX_WINDOWS][TNS_MAXIMUM_FILTERS];
+ UCHAR NumberOfFilters[TNS_MAX_WINDOWS];
+ UCHAR DataPresent;
+ UCHAR Active;
+
+ /* log2 of the maximum total filter gains. The value is required to
+ keep necessary mantissa headroom so that while applying the TNS predictor
+ the mantissas do not overflow. */
+ UCHAR GainLd;
+} CTnsData;
+
+void CTns_Reset(CTnsData *pTnsData);
+
+#endif /* #ifndef AACDEC_TNS_H */
diff --git a/fdk-aac/libAACdec/src/aacdecoder.cpp b/fdk-aac/libAACdec/src/aacdecoder.cpp
new file mode 100644
index 0000000..8f03328
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder.cpp
@@ -0,0 +1,3464 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \page default General Overview of the AAC Decoder Implementation
+
+ The main entry point to decode a AAC frame is CAacDecoder_DecodeFrame(). It
+ handles the different transport multiplexes and bitstream formats supported by
+ this implementation. It extracts the AAC_raw_data_blocks from these bitstreams
+ to further process then in the actual decoding stages.
+
+ Note: Click on a function of file in the above image to see details about the
+ function. Also note, that this is just an overview of the most important
+ functions and not a complete call graph.
+
+ <h2>1 Bitstream deformatter</h2>
+ The basic bit stream parser function CChannelElement_Read() is called. It uses
+ other subcalls in order to parse and unpack the bitstreams. Note, that this
+ includes huffmann decoding of the coded spectral data. This operation can be
+ computational significant specifically at higher bitrates. Optimization is
+ likely in CBlock_ReadSpectralData().
+
+ The bitstream deformatter also includes many bitfield operations. Profiling on
+ the target will determine required optimizations.
+
+ <h2>2 Actual decoding to retain the time domain output</h2>
+ The basic bitstream deformatter function CChannelElement_Decode() for CPE
+ elements and SCE elements are called. Except for the stereo processing (2.1)
+ which is only used for CPE elements, the function calls for CPE or SCE are
+ similar, except that CPE always processes to independent channels while SCE
+ only processes one channel.
+
+ Often there is the distinction between long blocks and short blocks. However,
+ computational expensive functions that ususally require optimization are being
+ shared by these two groups,
+
+ <h3>2.1 Stereo processing for CPE elements</h3>
+ CChannelPairElement_Decode() first calles the joint stereo tools in
+ stereo.cpp when required.
+
+ <h3>2.2 Scaling of spectral data</h3>
+ CBlock_ScaleSpectralData().
+
+ <h3>2.3 Apply additional coding tools</h3>
+ ApplyTools() calles the PNS tools in case of MPEG-4 bitstreams, and TNS
+ filtering CTns_Apply() for MPEG-2 and MPEG-4 bitstreams. The function
+ TnsFilterIIR() which is called by CTns_Apply() (2.3.1) might require some
+ optimization.
+
+ <h2>3 Frequency-To-Time conversion</h3>
+ The filterbank is called using CBlock_FrequencyToTime() using the MDCT module
+ from the FDK Tools
+
+*/
+
+#include "aacdecoder.h"
+
+#include "aac_rom.h"
+#include "aac_ram.h"
+#include "channel.h"
+#include "FDK_audio.h"
+
+#include "aacdec_pns.h"
+
+#include "sbrdecoder.h"
+
+#include "sac_dec_lib.h"
+
+#include "aacdec_hcr.h"
+#include "rvlc.h"
+
+#include "usacdec_lpd.h"
+
+#include "ac_arith_coder.h"
+
+#include "tpdec_lib.h"
+
+#include "conceal.h"
+
+#include "FDK_crc.h"
+#define PS_IS_EXPLICITLY_DISABLED(aot, flags) \
+ (((aot) == AOT_DRM_AAC) && !(flags & AC_PS_PRESENT))
+
+#define IS_STEREO_SBR(el_id, stereoConfigIndex) \
+ (((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 0) || \
+ ((el_id) == ID_USAC_CPE && (stereoConfigIndex) == 3))
+
+void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self) {
+ FDK_ASSERT(
+ !((self->flags[0] & AC_MPS_PRESENT) && (self->flags[0] & AC_PS_PRESENT)));
+
+ /* Assign user requested mode */
+ self->qmfModeCurr = self->qmfModeUser;
+
+ if (IS_USAC(self->streamInfo.aot)) {
+ self->qmfModeCurr = MODE_HQ;
+ }
+
+ if (self->qmfModeCurr == NOT_DEFINED) {
+ if ((IS_LOWDELAY(self->streamInfo.aot) &&
+ (self->flags[0] & AC_MPS_PRESENT)) ||
+ ((self->streamInfo.aacNumChannels == 1) &&
+ ((CAN_DO_PS(self->streamInfo.aot) &&
+ !(self->flags[0] & AC_MPS_PRESENT)) ||
+ (IS_USAC(self->streamInfo.aot))))) {
+ self->qmfModeCurr = MODE_HQ;
+ } else {
+ self->qmfModeCurr = MODE_LP;
+ }
+ }
+
+ if (self->mpsEnableCurr) {
+ if (IS_LOWDELAY(self->streamInfo.aot) &&
+ (self->qmfModeCurr == MODE_LP)) { /* Overrule user requested QMF mode */
+ self->qmfModeCurr = MODE_HQ;
+ }
+ /* Set and check if MPS decoder allows the current mode */
+ switch (mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_PARTIALLY_COMPLEX, self->qmfModeCurr == MODE_LP)) {
+ case MPS_OK:
+ break;
+ case MPS_INVALID_PARAMETER: { /* Only one mode supported. Find out which
+ one: */
+ LIB_INFO libInfo[FDK_MODULE_LAST];
+ UINT mpsCaps;
+
+ FDKinitLibInfo(libInfo);
+ mpegSurroundDecoder_GetLibInfo(libInfo);
+ mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
+
+ if (((mpsCaps & CAPF_MPS_LP) && (self->qmfModeCurr == MODE_LP)) ||
+ ((mpsCaps & CAPF_MPS_HQ) &&
+ (self->qmfModeCurr ==
+ MODE_HQ))) { /* MPS decoder does support the requested mode. */
+ break;
+ }
+ }
+ FDK_FALLTHROUGH;
+ default:
+ if (self->qmfModeUser == NOT_DEFINED) {
+ /* Revert in case mpegSurroundDecoder_SetParam() fails. */
+ self->qmfModeCurr =
+ (self->qmfModeCurr == MODE_LP) ? MODE_HQ : MODE_LP;
+ } else {
+ /* in case specific mode was requested we disable MPS and playout the
+ * downmix */
+ self->mpsEnableCurr = 0;
+ }
+ }
+ }
+
+ /* Set SBR to current QMF mode. Error does not matter. */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_QMF_MODE,
+ (self->qmfModeCurr == MODE_LP));
+ self->psPossible =
+ ((CAN_DO_PS(self->streamInfo.aot) &&
+ !PS_IS_EXPLICITLY_DISABLED(self->streamInfo.aot, self->flags[0]) &&
+ self->streamInfo.aacNumChannels == 1 &&
+ !(self->flags[0] & AC_MPS_PRESENT))) &&
+ self->qmfModeCurr == MODE_HQ;
+ FDK_ASSERT(!((self->flags[0] & AC_MPS_PRESENT) && self->psPossible));
+}
+
+void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ int i;
+
+ for (i = 0; i < fMin(self->aacChannels, (8)); i++) {
+ if (self->pAacDecoderStaticChannelInfo
+ [i]) { /* number of active channels can be smaller */
+ self->pAacDecoderStaticChannelInfo[i]->hArCo->m_numberLinesPrev = 0;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Calculates the number of element channels
+
+ \type channel type
+ \usacStereoConfigIndex usac stereo config index
+
+ \return element channels
+*/
+static int CAacDecoder_GetELChannels(MP4_ELEMENT_ID type,
+ UCHAR usacStereoConfigIndex) {
+ int el_channels = 0;
+
+ switch (type) {
+ case ID_USAC_CPE:
+ if (usacStereoConfigIndex == 1) {
+ el_channels = 1;
+ } else {
+ el_channels = 2;
+ }
+ break;
+ case ID_CPE:
+ el_channels = 2;
+ break;
+ case ID_USAC_SCE:
+ case ID_USAC_LFE:
+ case ID_SCE:
+ case ID_LFE:
+ el_channels = 1;
+ break;
+ default:
+ el_channels = 0;
+ break;
+ }
+
+ return el_channels;
+}
+
+/*!
+ \brief Reset ancillary data struct. Call before parsing a new frame.
+
+ \ancData Pointer to ancillary data structure
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) {
+ int i;
+ for (i = 0; i < 8; i++) {
+ ancData->offset[i] = 0;
+ }
+ ancData->nrElements = 0;
+
+ return AAC_DEC_OK;
+}
+
+/*!
+ \brief Initialize ancillary buffer
+
+ \ancData Pointer to ancillary data structure
+ \buffer Pointer to (external) anc data buffer
+ \size Size of the buffer pointed on by buffer in bytes
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData,
+ unsigned char *buffer, int size) {
+ if (size >= 0) {
+ ancData->buffer = buffer;
+ ancData->bufferSize = size;
+
+ CAacDecoder_AncDataReset(ancData);
+
+ return AAC_DEC_OK;
+ }
+
+ return AAC_DEC_ANC_DATA_ERROR;
+}
+
+/*!
+ \brief Get one ancillary data element
+
+ \ancData Pointer to ancillary data structure
+ \index Index of the anc data element to get
+ \ptr Pointer to a buffer receiving a pointer to the requested anc data element
+ \size Pointer to a buffer receiving the length of the requested anc data
+ element in bytes
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index,
+ unsigned char **ptr, int *size) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+
+ *ptr = NULL;
+ *size = 0;
+
+ if (index >= 0 && index < 8 - 1 && index < ancData->nrElements) {
+ *ptr = &ancData->buffer[ancData->offset[index]];
+ *size = ancData->offset[index + 1] - ancData->offset[index];
+ }
+
+ return error;
+}
+
+/*!
+ \brief Parse ancillary data
+
+ \ancData Pointer to ancillary data structure
+ \hBs Handle to FDK bitstream
+ \ancBytes Length of ancillary data to read from the bitstream
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_AncDataParse(CAncData *ancData,
+ HANDLE_FDK_BITSTREAM hBs,
+ const int ancBytes) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int readBytes = 0;
+
+ if (ancData->buffer != NULL) {
+ if (ancBytes > 0) {
+ /* write ancillary data to external buffer */
+ int offset = ancData->offset[ancData->nrElements];
+
+ if ((offset + ancBytes) > ancData->bufferSize) {
+ error = AAC_DEC_TOO_SMALL_ANC_BUFFER;
+ } else if (ancData->nrElements >= 8 - 1) {
+ error = AAC_DEC_TOO_MANY_ANC_ELEMENTS;
+ } else {
+ int i;
+
+ for (i = 0; i < ancBytes; i++) {
+ ancData->buffer[i + offset] = FDKreadBits(hBs, 8);
+ readBytes++;
+ }
+
+ ancData->nrElements++;
+ ancData->offset[ancData->nrElements] =
+ ancBytes + ancData->offset[ancData->nrElements - 1];
+ }
+ }
+ }
+
+ readBytes = ancBytes - readBytes;
+
+ if (readBytes > 0) {
+ /* skip data */
+ FDKpushFor(hBs, readBytes << 3);
+ }
+
+ return error;
+}
+
+/*!
+ \brief Read Stream Data Element
+
+ \bs Bitstream Handle
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CDataStreamElement_Read(HANDLE_AACDECODER self,
+ HANDLE_FDK_BITSTREAM bs,
+ UCHAR *elementInstanceTag,
+ UINT alignmentAnchor) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ UINT dseBits;
+ INT dataStart;
+ int dataByteAlignFlag, count;
+
+ FDK_ASSERT(self != NULL);
+
+ int crcReg = transportDec_CrcStartReg(self->hInput, 0);
+
+ /* Element Instance Tag */
+ *elementInstanceTag = FDKreadBits(bs, 4);
+ /* Data Byte Align Flag */
+ dataByteAlignFlag = FDKreadBits(bs, 1);
+
+ count = FDKreadBits(bs, 8);
+
+ if (count == 255) {
+ count += FDKreadBits(bs, 8); /* EscCount */
+ }
+ dseBits = count * 8;
+
+ if (dataByteAlignFlag) {
+ FDKbyteAlign(bs, alignmentAnchor);
+ }
+
+ dataStart = (INT)FDKgetValidBits(bs);
+
+ error = CAacDecoder_AncDataParse(&self->ancData, bs, count);
+ transportDec_CrcEndReg(self->hInput, crcReg);
+
+ {
+ /* Move to the beginning of the data chunk */
+ FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
+
+ /* Read Anc data if available */
+ aacDecoder_drcMarkPayload(self->hDrcInfo, bs, DVB_DRC_ANC_DATA);
+ }
+
+ {
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+
+ /* Move to the beginning of the data chunk */
+ FDKpushBack(bs, dataStart - (INT)FDKgetValidBits(bs));
+
+ /* Read DMX meta-data */
+ dmxErr = pcmDmx_Parse(self->hPcmUtils, bs, dseBits, 0 /* not mpeg2 */);
+ if (error == AAC_DEC_OK && dmxErr != PCMDMX_OK) {
+ error = AAC_DEC_UNKNOWN;
+ }
+ }
+
+ /* Move to the very end of the element. */
+ FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - dataStart + (INT)dseBits);
+
+ return error;
+}
+
+/*!
+ \brief Read Program Config Element
+
+ \bs Bitstream Handle
+ \pTp Transport decoder handle for CRC handling
+ \pce Pointer to PCE buffer
+ \channelConfig Current channel configuration
+ \alignAnchor Anchor for byte alignment
+
+ \return PCE status (-1: fail, 0: no new PCE, 1: PCE updated, 2: PCE updated
+ need re-config).
+*/
+static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs,
+ HANDLE_TRANSPORTDEC pTp,
+ CProgramConfig *pce,
+ const UINT channelConfig,
+ const UINT alignAnchor) {
+ int pceStatus = 0;
+ int crcReg;
+
+ /* read PCE to temporal buffer first */
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+
+ CProgramConfig_Init(tmpPce);
+
+ crcReg = transportDec_CrcStartReg(pTp, 0);
+
+ CProgramConfig_Read(tmpPce, bs, alignAnchor);
+
+ transportDec_CrcEndReg(pTp, crcReg);
+
+ if (CProgramConfig_IsValid(tmpPce) && (tmpPce->Profile == 1)) {
+ if (!CProgramConfig_IsValid(pce) && (channelConfig > 0)) {
+ /* Create a standard channel config PCE to compare with */
+ CProgramConfig_GetDefault(pce, channelConfig);
+ }
+
+ if (CProgramConfig_IsValid(pce)) {
+ /* Compare the new and the old PCE (tags ignored) */
+ switch (CProgramConfig_Compare(pce, tmpPce)) {
+ case 1: /* Channel configuration not changed. Just new metadata. */
+ FDKmemcpy(pce, tmpPce,
+ sizeof(CProgramConfig)); /* Store the complete PCE */
+ pceStatus = 1; /* New PCE but no change of config */
+ break;
+ case 2: /* The number of channels are identical but not the config */
+ case -1: /* The channel configuration is completely different */
+ pceStatus = -1; /* Not supported! */
+ break;
+ case 0: /* Nothing to do because PCE matches the old one exactly. */
+ default:
+ /* pceStatus = 0; */
+ break;
+ }
+ }
+ }
+
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+
+ return pceStatus;
+}
+
+/*!
+ \brief Prepares crossfade for USAC DASH IPF config change
+
+ \pTimeData Pointer to time data
+ \pTimeDataFlush Pointer to flushed time data
+ \numChannels Number of channels
+ \frameSize Size of frame
+ \interleaved Indicates if time data is interleaved
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
+ const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved) {
+ int i, ch, s1, s2;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ ErrorStatus = AAC_DEC_OK;
+
+ if (interleaved) {
+ s1 = 1;
+ s2 = numChannels;
+ } else {
+ s1 = frameSize;
+ s2 = 1;
+ }
+
+ for (ch = 0; ch < numChannels; ch++) {
+ const INT_PCM *pIn = &pTimeData[ch * s1];
+ for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ pTimeDataFlush[ch][i] = *pIn;
+ pIn += s2;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Applies crossfade for USAC DASH IPF config change
+
+ \pTimeData Pointer to time data
+ \pTimeDataFlush Pointer to flushed time data
+ \numChannels Number of channels
+ \frameSize Size of frame
+ \interleaved Indicates if time data is interleaved
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
+ INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved) {
+ int i, ch, s1, s2;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ ErrorStatus = AAC_DEC_OK;
+
+ if (interleaved) {
+ s1 = 1;
+ s2 = numChannels;
+ } else {
+ s1 = frameSize;
+ s2 = 1;
+ }
+
+ for (ch = 0; ch < numChannels; ch++) {
+ INT_PCM *pIn = &pTimeData[ch * s1];
+ for (i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ FIXP_SGL alpha = (FIXP_SGL)i
+ << (FRACT_BITS - 1 - TIME_DATA_FLUSH_SIZE_SF);
+ FIXP_DBL time = FX_PCM2FX_DBL(*pIn);
+ FIXP_DBL timeFlush = FX_PCM2FX_DBL(pTimeDataFlush[ch][i]);
+
+ *pIn = (INT_PCM)(FIXP_PCM)FX_DBL2FX_PCM(
+ timeFlush - fMult(timeFlush, alpha) + fMult(time, alpha));
+ pIn += s2;
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Parse PreRoll Extension Payload
+
+ \self Handle of AAC decoder
+ \numPrerollAU Number of preRoll AUs
+ \prerollAUOffset Offset to each preRoll AU
+ \prerollAULength Length of each preRoll AU
+
+ \return Error code
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
+ HANDLE_AACDECODER self, UINT *numPrerollAU, UINT *prerollAUOffset,
+ UINT *prerollAULength) {
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs;
+ AAC_DECODER_ERROR ErrorStatus;
+
+ INT auStartAnchor;
+ UINT independencyFlag;
+ UINT extPayloadPresentFlag;
+ UINT useDefaultLengthFlag;
+ UINT configLength = 0;
+ UINT preRollPossible = 1;
+ UINT i;
+ UCHAR configChanged = 0;
+ UCHAR config[TP_USAC_MAX_CONFIG_LEN] = {0};
+ UCHAR
+ implicitExplicitCfgDiff = 0; /* in case implicit and explicit config is
+ equal preroll AU's should be processed
+ after decoder reset */
+
+ ErrorStatus = AAC_DEC_OK;
+
+ hBs = transportDec_GetBitstream(self->hInput, 0);
+ bs = *hBs;
+
+ auStartAnchor = (INT)FDKgetValidBits(hBs);
+ if (auStartAnchor <= 0) {
+ ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
+ goto bail;
+ }
+
+ /* Independency flag */
+ FDKreadBit(hBs);
+
+ /* Payload present flag of extension ID_EXT_ELE_AUDIOPREROLL must be one */
+ extPayloadPresentFlag = FDKreadBits(hBs, 1);
+ if (!extPayloadPresentFlag) {
+ preRollPossible = 0;
+ }
+
+ /* Default length flag of extension ID_EXT_ELE_AUDIOPREROLL must be zero */
+ useDefaultLengthFlag = FDKreadBits(hBs, 1);
+ if (useDefaultLengthFlag) {
+ preRollPossible = 0;
+ }
+
+ if (preRollPossible) { /* extPayloadPresentFlag && !useDefaultLengthFlag */
+ /* Read overall ext payload length, useDefaultLengthFlag must be zero. */
+ escapedValue(hBs, 8, 16, 0);
+
+ /* Read RSVD60 Config size */
+ configLength = escapedValue(hBs, 4, 4, 8);
+
+ /* Avoid decoding pre roll frames if there was no config change and no
+ * config is included in the pre roll ext payload. */
+ }
+
+ /* If pre roll not possible then exit. */
+ if (preRollPossible == 0) {
+ /* Sanity check: if flushing is switched on, preRollPossible must be 1 */
+ if (self->flushStatus != AACDEC_FLUSH_OFF) {
+ /* Mismatch of current payload and flushing status */
+ self->flushStatus = AACDEC_FLUSH_OFF;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ goto bail;
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ if (configLength > 0) {
+ /* DASH IPF USAC Config Change: Read new config and compare with current
+ * config. Apply reconfiguration if config's are different. */
+ for (i = 0; i < configLength; i++) {
+ config[i] = FDKreadBits(hBs, 8);
+ }
+ TRANSPORTDEC_ERROR terr;
+ terr = transportDec_InBandConfig(self->hInput, config, configLength,
+ self->buildUpStatus, &configChanged, 0,
+ &implicitExplicitCfgDiff);
+ if (terr != TRANSPORTDEC_OK) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+ /* For the first frame buildUpStatus is not set and no flushing is performed
+ * but preroll AU's should processed. */
+ /* For USAC there is no idle state. */
+ if ((self->streamInfo.numChannels == 0) && !implicitExplicitCfgDiff &&
+ (self->flags[0] & AC_USAC)) {
+ self->buildUpStatus = AACDEC_USAC_BUILD_UP_ON;
+ /* sanity check: if buildUp status on -> flushing must be off */
+ if (self->flushStatus != AACDEC_FLUSH_OFF) {
+ self->flushStatus = AACDEC_FLUSH_OFF;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ /* We are interested in preroll AUs if an explicit or an implicit config
+ * change is signalized in other words if the build up status is set. */
+ if (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON) {
+ self->applyCrossfade |= FDKreadBit(hBs);
+ FDKreadBit(hBs); /* reserved */
+ /* Read num preroll AU's */
+ *numPrerollAU = escapedValue(hBs, 2, 4, 0);
+ /* check limits for USAC */
+ if (*numPrerollAU > AACDEC_MAX_NUM_PREROLL_AU_USAC) {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+ for (i = 0; i < *numPrerollAU; i++) {
+ /* For every AU get length and offset in the bitstream */
+ prerollAULength[i] = escapedValue(hBs, 16, 16, 0);
+ if (prerollAULength[i] > 0) {
+ prerollAUOffset[i] = auStartAnchor - (INT)FDKgetValidBits(hBs);
+ independencyFlag = FDKreadBit(hBs);
+ if (i == 0 && !independencyFlag) {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ FDKpushFor(hBs, prerollAULength[i] * 8 - 1);
+ self->prerollAULength[i] = (prerollAULength[i] * 8) + prerollAUOffset[i];
+ } else {
+ *numPrerollAU = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR; /* Something is wrong */
+ goto bail;
+ }
+ }
+
+bail:
+
+ *hBs = bs;
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief Parse Extension Payload
+
+ \self Handle of AAC decoder
+ \count Pointer to bit counter.
+ \previous_element ID of previous element (required by some extension payloads)
+
+ \return Error code
+*/
+static AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse(
+ HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM hBs, int *count,
+ MP4_ELEMENT_ID previous_element, int elIndex, int fIsFillElement) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ EXT_PAYLOAD_TYPE extension_type;
+ int bytes = (*count) >> 3;
+ int crcFlag = 0;
+
+ if (*count < 4) {
+ return AAC_DEC_PARSE_ERROR;
+ } else if ((INT)FDKgetValidBits(hBs) < *count) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ extension_type =
+ (EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4); /* bs_extension_type */
+ *count -= 4;
+
+ /* For ELD, the SBR signaling is explicit and parsed in
+ aacDecoder_ParseExplicitMpsAndSbr(), therefore skip SBR if implicit
+ present. */
+ if ((self->flags[0] & AC_ELD) && ((extension_type == EXT_SBR_DATA_CRC) ||
+ (extension_type == EXT_SBR_DATA))) {
+ extension_type = EXT_FIL; /* skip sbr data */
+ }
+
+ switch (extension_type) {
+ case EXT_DYNAMIC_RANGE: {
+ INT readBits =
+ aacDecoder_drcMarkPayload(self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA);
+
+ if (readBits > *count) { /* Read too much. Something went wrong! */
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ *count -= readBits;
+ } break;
+ case EXT_UNI_DRC: {
+ DRC_DEC_ERROR drcErr = DRC_DEC_OK;
+ DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+ INT nBitsRemaining = FDKgetValidBits(hBs);
+ INT readBits;
+
+ switch (self->streamInfo.aot) {
+ case AOT_AAC_LC:
+ case AOT_SBR:
+ case AOT_PS:
+ drcDecCodecMode = DRC_DEC_MPEG_4_AAC;
+ break;
+ default:
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ drcErr = FDK_drcDec_SetCodecMode(self->hUniDrcDecoder, drcDecCodecMode);
+ if (drcErr) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ drcErr = FDK_drcDec_ReadUniDrc(self->hUniDrcDecoder, hBs);
+ if (drcErr) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ readBits = (INT)nBitsRemaining - (INT)FDKgetValidBits(hBs);
+ if (readBits > *count) { /* Read too much. Something went wrong! */
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ *count -= readBits;
+ /* Skip any trailing bits */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ } break;
+ case EXT_LDSAC_DATA:
+ case EXT_SAC_DATA:
+ /* Read MPEG Surround Extension payload */
+ {
+ int err, mpsSampleRate, mpsFrameSize;
+
+ if (self->flags[0] & AC_PS_PRESENT) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ /* Handle SBR dual rate case */
+ if (self->streamInfo.extSamplingRate != 0) {
+ mpsSampleRate = self->streamInfo.extSamplingRate;
+ mpsFrameSize = self->streamInfo.aacSamplesPerFrame *
+ (self->streamInfo.extSamplingRate /
+ self->streamInfo.aacSampleRate);
+ } else {
+ mpsSampleRate = self->streamInfo.aacSampleRate;
+ mpsFrameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+ /* Setting of internal MPS state; may be reset in
+ CAacDecoder_SyncQmfMode if decoder is unable to decode with user
+ defined qmfMode */
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD))) {
+ self->mpsEnableCurr = self->mpsEnableUser;
+ }
+ if (self->mpsEnableCurr) {
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig) {
+ /* if not done yet, allocate full MPEG Surround decoder instance */
+ if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
+ SAC_INSTANCE_NOT_FULL_AVAILABLE) {
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
+ &self->qmfDomain)) {
+ return AAC_DEC_OUT_OF_MEMORY;
+ }
+ }
+ }
+ err = mpegSurroundDecoder_Parse(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, hBs, count,
+ self->streamInfo.aot, mpsSampleRate, mpsFrameSize,
+ self->flags[0] & AC_INDEP);
+ if (err == MPS_OK) {
+ self->flags[0] |= AC_MPS_PRESENT;
+ } else {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ /* Skip any trailing bytes */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ }
+ break;
+
+ case EXT_SBR_DATA_CRC:
+ crcFlag = 1;
+ FDK_FALLTHROUGH;
+ case EXT_SBR_DATA:
+ if (IS_CHANNEL_ELEMENT(previous_element)) {
+ SBR_ERROR sbrError;
+ UCHAR configMode = 0;
+ UCHAR configChanged = 0;
+
+ CAacDecoder_SyncQmfMode(self);
+
+ configMode |= AC_CM_ALLOC_MEM;
+
+ sbrError = sbrDecoder_InitElement(
+ self->hSbrDecoder, self->streamInfo.aacSampleRate,
+ self->streamInfo.extSamplingRate,
+ self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot,
+ previous_element, elIndex,
+ 2, /* Signalize that harmonicSBR shall be ignored in the config
+ change detection */
+ 0, configMode, &configChanged, self->downscaleFactor);
+
+ if (sbrError == SBRDEC_OK) {
+ sbrError = sbrDecoder_Parse(self->hSbrDecoder, hBs,
+ self->pDrmBsBuffer, self->drmBsBufferSize,
+ count, *count, crcFlag, previous_element,
+ elIndex, self->flags[0], self->elFlags);
+ /* Enable SBR for implicit SBR signalling but only if no severe error
+ * happend. */
+ if ((sbrError == SBRDEC_OK) || (sbrError == SBRDEC_PARSE_ERROR)) {
+ self->sbrEnabled = 1;
+ }
+ } else {
+ /* Do not try to apply SBR because initializing the element failed. */
+ self->sbrEnabled = 0;
+ }
+ /* Citation from ISO/IEC 14496-3 chapter 4.5.2.1.5.2
+ Fill elements containing an extension_payload() with an extension_type
+ of EXT_SBR_DATA or EXT_SBR_DATA_CRC shall not contain any other
+ extension_payload of any other extension_type.
+ */
+ if (fIsFillElement) {
+ FDKpushBiDirectional(hBs, *count);
+ *count = 0;
+ } else {
+ /* If this is not a fill element with a known length, we are screwed
+ * and further parsing makes no sense. */
+ if (sbrError != SBRDEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+ } else {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ break;
+
+ case EXT_FILL_DATA: {
+ int temp;
+
+ temp = FDKreadBits(hBs, 4);
+ bytes--;
+ if (temp != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ while (bytes > 0) {
+ temp = FDKreadBits(hBs, 8);
+ bytes--;
+ if (temp != 0xa5) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ }
+ *count = bytes << 3;
+ } break;
+
+ case EXT_DATA_ELEMENT: {
+ int dataElementVersion;
+
+ dataElementVersion = FDKreadBits(hBs, 4);
+ *count -= 4;
+ if (dataElementVersion == 0) /* ANC_DATA */
+ {
+ int temp, dataElementLength = 0;
+ do {
+ temp = FDKreadBits(hBs, 8);
+ *count -= 8;
+ dataElementLength += temp;
+ } while (temp == 255);
+
+ CAacDecoder_AncDataParse(&self->ancData, hBs, dataElementLength);
+ *count -= (dataElementLength << 3);
+ } else {
+ /* align = 0 */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ } break;
+
+ case EXT_DATA_LENGTH:
+ if (!fIsFillElement /* Makes no sens to have an additional length in a
+ fill ... */
+ &&
+ (self->flags[0] &
+ AC_ER)) /* ... element because this extension payload type was ... */
+ { /* ... created to circumvent the missing length in ER-Syntax. */
+ int bitCnt, len = FDKreadBits(hBs, 4);
+ *count -= 4;
+
+ if (len == 15) {
+ int add_len = FDKreadBits(hBs, 8);
+ *count -= 8;
+ len += add_len;
+
+ if (add_len == 255) {
+ len += FDKreadBits(hBs, 16);
+ *count -= 16;
+ }
+ }
+ len <<= 3;
+ bitCnt = len;
+
+ if ((EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4) == EXT_DATA_LENGTH) {
+ /* Check NOTE 2: The extension_payload() included here must
+ not have extension_type == EXT_DATA_LENGTH. */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ } else {
+ /* rewind and call myself again. */
+ FDKpushBack(hBs, 4);
+
+ error = CAacDecoder_ExtPayloadParse(
+ self, hBs, &bitCnt, previous_element, elIndex,
+ 1); /* Treat same as fill element */
+
+ *count -= len - bitCnt;
+ }
+ /* Note: the fall through in case the if statement above is not taken is
+ * intentional. */
+ break;
+ }
+ FDK_FALLTHROUGH;
+
+ case EXT_FIL:
+
+ default:
+ /* align = 4 */
+ FDKpushFor(hBs, *count);
+ *count = 0;
+ break;
+ }
+
+bail:
+ if ((error != AAC_DEC_OK) &&
+ fIsFillElement) { /* Skip the remaining extension bytes */
+ FDKpushBiDirectional(hBs, *count);
+ *count = 0;
+ /* Patch error code because decoding can go on. */
+ error = AAC_DEC_OK;
+ /* Be sure that parsing errors have been stored. */
+ }
+ return error;
+}
+
+static AAC_DECODER_ERROR aacDecoder_ParseExplicitMpsAndSbr(
+ HANDLE_AACDECODER self, HANDLE_FDK_BITSTREAM bs,
+ const MP4_ELEMENT_ID previous_element, const int previous_element_index,
+ const int element_index, const int el_cnt[]) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+ INT bitCnt = 0;
+
+ /* get the remaining bits of this frame */
+ bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0);
+
+ if ((self->flags[0] & AC_SBR_PRESENT) &&
+ (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD | AC_DRM))) {
+ SBR_ERROR err = SBRDEC_OK;
+ int chElIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE] +
+ el_cnt[ID_LFE] + el_cnt[ID_USAC_SCE] +
+ el_cnt[ID_USAC_CPE] + el_cnt[ID_USAC_LFE];
+ INT bitCntTmp = bitCnt;
+
+ if (self->flags[0] & AC_USAC) {
+ chElIdx = numChElements - 1;
+ } else {
+ chElIdx = 0; /* ELD case */
+ }
+
+ for (; chElIdx < numChElements; chElIdx += 1) {
+ MP4_ELEMENT_ID sbrType;
+ SBR_ERROR errTmp;
+ if (self->flags[0] & (AC_USAC)) {
+ FDK_ASSERT((self->elements[element_index] == ID_USAC_SCE) ||
+ (self->elements[element_index] == ID_USAC_CPE));
+ sbrType = IS_STEREO_SBR(self->elements[element_index],
+ self->usacStereoConfigIndex[element_index])
+ ? ID_CPE
+ : ID_SCE;
+ } else
+ sbrType = self->elements[chElIdx];
+ errTmp = sbrDecoder_Parse(self->hSbrDecoder, bs, self->pDrmBsBuffer,
+ self->drmBsBufferSize, &bitCnt, -1,
+ self->flags[0] & AC_SBRCRC, sbrType, chElIdx,
+ self->flags[0], self->elFlags);
+ if (errTmp != SBRDEC_OK) {
+ err = errTmp;
+ bitCntTmp = bitCnt;
+ bitCnt = 0;
+ }
+ }
+ switch (err) {
+ case SBRDEC_PARSE_ERROR:
+ /* Can not go on parsing because we do not
+ know the length of the SBR extension data. */
+ FDKpushFor(bs, bitCntTmp);
+ bitCnt = 0;
+ break;
+ case SBRDEC_OK:
+ self->sbrEnabled = 1;
+ break;
+ default:
+ self->frameOK = 0;
+ break;
+ }
+ }
+
+ if ((bitCnt > 0) && (self->flags[0] & (AC_USAC | AC_RSVD50))) {
+ if ((self->flags[0] & AC_MPS_PRESENT) ||
+ (self->elFlags[element_index] & AC_EL_USAC_MPS212)) {
+ int err;
+
+ err = mpegSurroundDecoder_ParseNoHeader(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, bs, &bitCnt,
+ self->flags[0] & AC_INDEP);
+ if (err != MPS_OK) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ }
+
+ if (self->flags[0] & AC_DRM) {
+ if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) {
+ FDKpushBiDirectional(bs, bitCnt);
+ }
+ }
+
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_DRM))) {
+ while (bitCnt > 7) {
+ ErrorStatus = CAacDecoder_ExtPayloadParse(
+ self, bs, &bitCnt, previous_element, previous_element_index, 0);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ }
+ }
+ return ErrorStatus;
+}
+
+/* Stream Configuration and Information.
+
+ This class holds configuration and information data for a stream to be
+ decoded. It provides the calling application as well as the decoder with
+ substantial information, e.g. profile, sampling rate, number of channels
+ found in the bitstream etc.
+*/
+static void CStreamInfoInit(CStreamInfo *pStreamInfo) {
+ pStreamInfo->aacSampleRate = 0;
+ pStreamInfo->profile = -1;
+ pStreamInfo->aot = AOT_NONE;
+
+ pStreamInfo->channelConfig = -1;
+ pStreamInfo->bitRate = 0;
+ pStreamInfo->aacSamplesPerFrame = 0;
+
+ pStreamInfo->extAot = AOT_NONE;
+ pStreamInfo->extSamplingRate = 0;
+
+ pStreamInfo->flags = 0;
+
+ pStreamInfo->epConfig = -1; /* default: no ER */
+
+ pStreamInfo->numChannels = 0;
+ pStreamInfo->sampleRate = 0;
+ pStreamInfo->frameSize = 0;
+
+ pStreamInfo->outputDelay = 0;
+
+ /* DRC */
+ pStreamInfo->drcProgRefLev =
+ -1; /* set program reference level to not indicated */
+ pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */
+}
+
+/*!
+ \brief Initialization of AacDecoderChannelInfo
+
+ The function initializes the pointers to AacDecoderChannelInfo for each
+ channel, set the start values for window shape and window sequence of
+ overlap&add to zero, set the overlap buffer to zero and initializes the
+ pointers to the window coefficients. \param bsFormat is the format of the AAC
+ bitstream
+
+ \return AACDECODER instance
+*/
+LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(
+ TRANSPORT_TYPE bsFormat) /*!< bitstream format (adif,adts,loas,...). */
+{
+ HANDLE_AACDECODER self;
+
+ self = GetAacDecoder();
+ if (self == NULL) {
+ goto bail;
+ }
+
+ FDK_QmfDomain_ClearRequested(&self->qmfDomain.globalConf);
+
+ /* Assign channel mapping info arrays (doing so removes dependency of settings
+ * header in API header). */
+ self->streamInfo.pChannelIndices = self->channelIndices;
+ self->streamInfo.pChannelType = self->channelType;
+ self->downscaleFactor = 1;
+ self->downscaleFactorInBS = 1;
+
+ /* initialize anc data */
+ CAacDecoder_AncDataInit(&self->ancData, NULL, 0);
+
+ /* initialize stream info */
+ CStreamInfoInit(&self->streamInfo);
+
+ /* initialize progam config */
+ CProgramConfig_Init(&self->pce);
+
+ /* initialize error concealment common data */
+ CConcealment_InitCommonData(&self->concealCommonData);
+ self->concealMethodUser = ConcealMethodNone; /* undefined -> auto mode */
+
+ self->hDrcInfo = GetDrcInfo();
+ if (self->hDrcInfo == NULL) {
+ goto bail;
+ }
+ /* Init common DRC structure */
+ aacDecoder_drcInit(self->hDrcInfo);
+ /* Set default frame delay */
+ aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY,
+ CConcealment_GetDelay(&self->concealCommonData));
+
+ self->workBufferCore2 = GetWorkBufferCore2();
+ if (self->workBufferCore2 == NULL) goto bail;
+
+ /* When RSVD60 is active use dedicated memory for core decoding */
+ self->pTimeData2 = GetWorkBufferCore5();
+ self->timeData2Size = GetRequiredMemWorkBufferCore5();
+ if (self->pTimeData2 == NULL) {
+ goto bail;
+ }
+
+ return self;
+
+bail:
+ CAacDecoder_Close(self);
+
+ return NULL;
+}
+
+/* Revert CAacDecoder_Init() */
+static void CAacDecoder_DeInit(HANDLE_AACDECODER self,
+ const int subStreamIndex) {
+ int ch;
+ int aacChannelOffset = 0, aacChannels = (8);
+ int numElements = (((8)) + (8)), elementOffset = 0;
+
+ if (self == NULL) return;
+
+ {
+ self->ascChannels[0] = 0;
+ self->elements[0] = ID_END;
+ }
+
+ for (ch = aacChannelOffset; ch < aacChannelOffset + aacChannels; ch++) {
+ if (self->pAacDecoderChannelInfo[ch] != NULL) {
+ if (self->pAacDecoderChannelInfo[ch]->pComStaticData != NULL) {
+ if (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 != NULL) {
+ if (ch == aacChannelOffset) {
+ FreeWorkBufferCore1(&self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1);
+ }
+ }
+ if (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->cplxPredictionData != NULL) {
+ FreeCplxPredictionData(&self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->cplxPredictionData);
+ }
+ /* Avoid double free of linked pComStaticData in case of CPE by settings
+ * pointer to NULL. */
+ if (ch < (8) - 1) {
+ if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
+ (self->pAacDecoderChannelInfo[ch + 1]->pComStaticData ==
+ self->pAacDecoderChannelInfo[ch]->pComStaticData)) {
+ self->pAacDecoderChannelInfo[ch + 1]->pComStaticData = NULL;
+ }
+ }
+ FDKfree(self->pAacDecoderChannelInfo[ch]->pComStaticData);
+ self->pAacDecoderChannelInfo[ch]->pComStaticData = NULL;
+ }
+ if (self->pAacDecoderChannelInfo[ch]->pComData != NULL) {
+ /* Avoid double free of linked pComData in case of CPE by settings
+ * pointer to NULL. */
+ if (ch < (8) - 1) {
+ if ((self->pAacDecoderChannelInfo[ch + 1] != NULL) &&
+ (self->pAacDecoderChannelInfo[ch + 1]->pComData ==
+ self->pAacDecoderChannelInfo[ch]->pComData)) {
+ self->pAacDecoderChannelInfo[ch + 1]->pComData = NULL;
+ }
+ }
+ if (ch == aacChannelOffset) {
+ FreeWorkBufferCore6(
+ (SCHAR **)&self->pAacDecoderChannelInfo[ch]->pComData);
+ } else {
+ FDKafree(self->pAacDecoderChannelInfo[ch]->pComData);
+ }
+ self->pAacDecoderChannelInfo[ch]->pComData = NULL;
+ }
+ }
+ if (self->pAacDecoderStaticChannelInfo[ch] != NULL) {
+ if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer != NULL) {
+ FreeOverlapBuffer(
+ &self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer);
+ }
+ if (self->pAacDecoderStaticChannelInfo[ch]->hArCo != NULL) {
+ CArco_Destroy(self->pAacDecoderStaticChannelInfo[ch]->hArCo);
+ }
+ FreeAacDecoderStaticChannelInfo(&self->pAacDecoderStaticChannelInfo[ch]);
+ }
+ if (self->pAacDecoderChannelInfo[ch] != NULL) {
+ FreeAacDecoderChannelInfo(&self->pAacDecoderChannelInfo[ch]);
+ }
+ }
+
+ {
+ int el;
+ for (el = elementOffset; el < elementOffset + numElements; el++) {
+ if (self->cpeStaticData[el] != NULL) {
+ FreeCpePersistentData(&self->cpeStaticData[el]);
+ }
+ }
+ }
+
+ FDK_Delay_Destroy(&self->usacResidualDelay);
+
+ self->aacChannels = 0;
+ self->streamInfo.aacSampleRate = 0;
+ self->streamInfo.sampleRate = 0;
+ /* This samplerate value is checked for configuration change, not the others
+ * above. */
+ self->samplingRateInfo[subStreamIndex].samplingRate = 0;
+}
+
+/*!
+ * \brief CAacDecoder_CtrlCFGChange Set config change parameters.
+ *
+ * \param self [i] handle to AACDECODER structure
+ * \param flushStatus [i] flush status: on|off
+ * \param flushCnt [i] flush frame counter
+ * \param buildUpStatus [i] build up status: on|off
+ * \param buildUpCnt [i] build up frame counter
+ *
+ * \return error
+ */
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,
+ UCHAR flushStatus,
+ SCHAR flushCnt,
+ UCHAR buildUpStatus,
+ SCHAR buildUpCnt) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ self->flushStatus = flushStatus;
+ self->flushCnt = flushCnt;
+ self->buildUpStatus = buildUpStatus;
+ self->buildUpCnt = buildUpCnt;
+
+ return (err);
+}
+
+/*!
+ * \brief CAacDecoder_FreeMem Free config dependent AAC memory.
+ *
+ * \param self [i] handle to AACDECODER structure
+ *
+ * \return error
+ */
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
+ const int subStreamIndex) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ CAacDecoder_DeInit(self, subStreamIndex);
+
+ return (err);
+}
+
+/* Destroy aac decoder */
+LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) {
+ if (self == NULL) return;
+
+ CAacDecoder_DeInit(self, 0);
+
+ {
+ int ch;
+ for (ch = 0; ch < (8); ch++) {
+ if (self->pTimeDataFlush[ch] != NULL) {
+ FreeTimeDataFlush(&self->pTimeDataFlush[ch]);
+ }
+ }
+ }
+
+ if (self->hDrcInfo) {
+ FreeDrcInfo(&self->hDrcInfo);
+ }
+
+ /* Free WorkBufferCore2 */
+ if (self->workBufferCore2 != NULL) {
+ FreeWorkBufferCore2(&self->workBufferCore2);
+ }
+ if (self->pTimeData2 != NULL) {
+ FreeWorkBufferCore5(&self->pTimeData2);
+ }
+
+ FDK_QmfDomain_Close(&self->qmfDomain);
+
+ FreeAacDecoder(&self);
+}
+
+/*!
+ \brief Initialization of decoder instance
+
+ The function initializes the decoder.
+
+ \return error status: 0 for success, <>0 for unsupported configurations
+*/
+LINKSPEC_CPP AAC_DECODER_ERROR
+CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc,
+ UCHAR configMode, UCHAR *configChanged) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ INT ascChannels, ascChanged = 0;
+ AACDEC_RENDER_MODE initRenderMode = AACDEC_RENDER_INVALID;
+ SCHAR usacStereoConfigIndex = -1;
+ int usacResidualDelayCompSamples = 0;
+ int elementOffset, aacChannelsOffset, aacChannelsOffsetIdx;
+ const int streamIndex = 0;
+ INT flushChannels = 0;
+
+ if (!self) return AAC_DEC_INVALID_HANDLE;
+
+ UCHAR downscaleFactor = self->downscaleFactor;
+ UCHAR downscaleFactorInBS = self->downscaleFactorInBS;
+
+ // set profile and check for supported aot
+ // leave profile on default (=-1) for all other supported MPEG-4 aot's except
+ // aot=2 (=AAC-LC)
+ switch (asc->m_aot) {
+ case AOT_AAC_LC:
+ self->streamInfo.profile = 1;
+ FDK_FALLTHROUGH;
+ case AOT_ER_AAC_SCAL:
+ if (asc->m_sc.m_gaSpecificConfig.m_layer > 0) {
+ /* aac_scalable_extension_element() currently not supported. */
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
+ FDK_FALLTHROUGH;
+ case AOT_SBR:
+ case AOT_PS:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ case AOT_DRM_AAC:
+ case AOT_DRM_SURROUND:
+ initRenderMode = AACDEC_RENDER_IMDCT;
+ break;
+ case AOT_ER_AAC_ELD:
+ initRenderMode = AACDEC_RENDER_ELDFB;
+ break;
+ case AOT_USAC:
+ initRenderMode = AACDEC_RENDER_IMDCT;
+ break;
+ default:
+ return AAC_DEC_UNSUPPORTED_AOT;
+ }
+
+ if (CProgramConfig_IsValid(&self->pce) && (asc->m_channelConfiguration > 0)) {
+ /* Compare the stored (old) PCE with a default PCE created from the (new)
+ channel_config (on a temporal buffer) to find out wheter we can keep it
+ (and its metadata) or not. */
+ int pceCmpResult;
+ C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1);
+
+ CProgramConfig_GetDefault(tmpPce, asc->m_channelConfiguration);
+ pceCmpResult = CProgramConfig_Compare(&self->pce, tmpPce);
+ if ((pceCmpResult < 0) /* Reset if PCEs are completely different ... */
+ ||
+ (pceCmpResult > 1)) { /* ... or have a different layout. */
+ CProgramConfig_Init(&self->pce);
+ } /* Otherwise keep the PCE (and its metadata). */
+ C_ALLOC_SCRATCH_END(tmpPce, CProgramConfig, 1);
+ } else {
+ CProgramConfig_Init(&self->pce);
+ }
+
+ /* set channels */
+ switch (asc->m_channelConfiguration) {
+ case 0:
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ self->chMapIndex = 0;
+ ascChannels = asc->m_sc.m_usacConfig.m_nUsacChannels;
+ break;
+ default:
+ /* get channels from program config (ASC) */
+ if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
+ ascChannels = asc->m_progrConfigElement.NumChannels;
+ if (ascChannels > 0) {
+ int el_tmp;
+ /* valid number of channels -> copy program config element (PCE)
+ * from ASC */
+ FDKmemcpy(&self->pce, &asc->m_progrConfigElement,
+ sizeof(CProgramConfig));
+ /* Built element table */
+ el_tmp = CProgramConfig_GetElementTable(
+ &asc->m_progrConfigElement, self->elements, (((8)) + (8)),
+ &self->chMapIndex);
+ for (; el_tmp < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ el_tmp++) {
+ self->elements[el_tmp] = ID_NONE;
+ }
+ } else {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ } else {
+ self->chMapIndex = 0;
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ break;
+ }
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ ascChannels = asc->m_channelConfiguration;
+ break;
+ case 11:
+ ascChannels = 7;
+ break;
+ case 7:
+ case 12:
+ case 14:
+ ascChannels = 8;
+ break;
+ default:
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ flushChannels = fMin(ascChannels, (8));
+ INT numChannel;
+ pcmDmx_GetParam(self->hPcmUtils, MIN_NUMBER_OF_OUTPUT_CHANNELS,
+ &numChannel);
+ flushChannels = fMin(fMax(numChannel, flushChannels), (8));
+ }
+
+ if (IS_USAC(asc->m_aot)) {
+ for (int el = 0; el < (INT)asc->m_sc.m_usacConfig.m_usacNumElements; el++) {
+ /* fix number of core channels aka ascChannels for stereoConfigIndex = 1
+ * cases */
+ if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 1) {
+ ascChannels--; /* stereoConfigIndex == 1 stereo cases do actually
+ contain only a mono core channel. */
+ } else if (asc->m_sc.m_usacConfig.element[el].m_stereoConfigIndex == 2) {
+ /* In this case it is necessary to follow up the DMX signal delay caused
+ by HBE also with the residual signal (2nd core channel). The SBR
+ overlap delay is not regarded here, this is handled by the MPS212
+ implementation.
+ */
+ if (asc->m_sc.m_usacConfig.element[el].m_harmonicSBR) {
+ usacResidualDelayCompSamples += asc->m_samplesPerFrame;
+ }
+ if (asc->m_sc.m_usacConfig.m_coreSbrFrameLengthIndex == 4) {
+ usacResidualDelayCompSamples +=
+ 6 * 16; /* difference between 12 SBR
+ overlap slots from SBR and 6
+ slots delayed in MPS212 */
+ }
+ }
+ }
+ }
+
+ aacChannelsOffset = 0;
+ aacChannelsOffsetIdx = 0;
+ elementOffset = 0;
+ if ((ascChannels <= 0) || (ascChannels > (8)) ||
+ (asc->m_channelConfiguration > AACDEC_MAX_CH_CONF)) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* Set syntax flags */
+ self->flags[streamIndex] = 0;
+ { FDKmemclear(self->elFlags, sizeof(self->elFlags)); }
+
+ if ((asc->m_channelConfiguration > 0) || IS_USAC(asc->m_aot)) {
+ if (IS_USAC(asc->m_aot)) {
+ /* copy pointer to usac config
+ (this is preliminary since there's an ongoing discussion about storing
+ the config-part of the bitstream rather than the complete decoded
+ configuration) */
+ self->pUsacConfig[streamIndex] = &asc->m_sc.m_usacConfig;
+
+ /* copy list of elements */
+ if (self->pUsacConfig[streamIndex]->m_usacNumElements >
+ (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ goto bail;
+ }
+
+ if (self->numUsacElements[streamIndex] !=
+ asc->m_sc.m_usacConfig.m_usacNumElements) {
+ ascChanged = 1;
+ }
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->numUsacElements[streamIndex] =
+ asc->m_sc.m_usacConfig.m_usacNumElements;
+ }
+
+ self->mpsEnableCurr = 0;
+ for (int _el = 0;
+ _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
+ _el++) {
+ int el = _el + elementOffset;
+ if (self->elements[el] !=
+ self->pUsacConfig[streamIndex]->element[_el].usacElementType) {
+ ascChanged = 1;
+ }
+ if (self->usacStereoConfigIndex[el] !=
+ asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->elements[el] =
+ self->pUsacConfig[streamIndex]->element[_el].usacElementType;
+ /* for Unified Stereo Coding */
+ self->usacStereoConfigIndex[el] =
+ asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex;
+ if (self->elements[el] == ID_USAC_CPE) {
+ self->mpsEnableCurr |= self->usacStereoConfigIndex[el] ? 1 : 0;
+ }
+ }
+
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_noiseFilling)
+ ? AC_EL_USAC_NOISE
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_stereoConfigIndex > 0)
+ ? AC_EL_USAC_MPS212
+ : 0;
+ self->elFlags[el] |= (asc->m_sc.m_usacConfig.element[_el].m_interTes)
+ ? AC_EL_USAC_ITES
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].m_pvc) ? AC_EL_USAC_PVC : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
+ ? AC_EL_USAC_LFE
+ : 0;
+ self->elFlags[el] |=
+ (asc->m_sc.m_usacConfig.element[_el].usacElementType == ID_USAC_LFE)
+ ? AC_EL_LFE
+ : 0;
+ if ((asc->m_sc.m_usacConfig.element[_el].usacElementType ==
+ ID_USAC_CPE) &&
+ ((self->usacStereoConfigIndex[el] == 0))) {
+ self->elFlags[el] |= AC_EL_USAC_CP_POSSIBLE;
+ }
+ }
+
+ self->hasAudioPreRoll = 0;
+ if (self->pUsacConfig[streamIndex]->m_usacNumElements) {
+ self->hasAudioPreRoll = asc->m_sc.m_usacConfig.element[0]
+ .extElement.usacExtElementHasAudioPreRoll;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->elements[elementOffset +
+ self->pUsacConfig[streamIndex]->m_usacNumElements] =
+ ID_END;
+ }
+ } else {
+ /* Initialize constant mappings for channel config 1-7 */
+ int i;
+ for (i = 0; i < AACDEC_CH_ELEMENTS_TAB_SIZE; i++) {
+ self->elements[i] = elementsTab[asc->m_channelConfiguration - 1][i];
+ }
+ for (; i < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1); i++) {
+ self->elements[i] = ID_NONE;
+ }
+ }
+
+ {
+ int ch;
+
+ for (ch = 0; ch < ascChannels; ch++) {
+ self->chMapping[ch] = ch;
+ }
+ for (; ch < (8); ch++) {
+ self->chMapping[ch] = 255;
+ }
+ }
+
+ self->chMapIndex = asc->m_channelConfiguration;
+ } else {
+ if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) {
+ /* Set matrix mixdown infos if available from PCE. */
+ pcmDmx_SetMatrixMixdownFromPce(
+ self->hPcmUtils, asc->m_progrConfigElement.MatrixMixdownIndexPresent,
+ asc->m_progrConfigElement.MatrixMixdownIndex,
+ asc->m_progrConfigElement.PseudoSurroundEnable);
+ }
+ }
+
+ self->streamInfo.channelConfig = asc->m_channelConfiguration;
+
+ if (self->streamInfo.aot != asc->m_aot) {
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.aot = asc->m_aot;
+ }
+ ascChanged = 1;
+ }
+
+ if (asc->m_aot == AOT_ER_AAC_ELD &&
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency != 0) {
+ if (self->samplingRateInfo[0].samplingRate !=
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency ||
+ self->samplingRateInfo[0].samplingRate * self->downscaleFactor !=
+ asc->m_samplingFrequency) {
+ /* get downscaledSamplingFrequency from ESC and compute the downscale
+ * factor */
+ downscaleFactorInBS =
+ asc->m_samplingFrequency /
+ asc->m_sc.m_eldSpecificConfig.m_downscaledSamplingFrequency;
+ if (downscaleFactorInBS == 1 || downscaleFactorInBS == 2 ||
+ downscaleFactorInBS == 3 || downscaleFactorInBS == 4) {
+ downscaleFactor = downscaleFactorInBS;
+ }
+ }
+ } else {
+ downscaleFactorInBS = 1;
+ downscaleFactor = 1;
+ }
+
+ if (self->downscaleFactorInBS != downscaleFactorInBS) {
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->downscaleFactorInBS = downscaleFactorInBS;
+ self->downscaleFactor = downscaleFactor;
+ }
+ ascChanged = 1;
+ }
+
+ if ((INT)asc->m_samplesPerFrame % downscaleFactor != 0) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* frameSize/dsf must be an integer
+ number */
+ }
+
+ self->streamInfo.bitRate = 0;
+
+ if (asc->m_aot == AOT_ER_AAC_ELD) {
+ if (self->useLdQmfTimeAlign !=
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->useLdQmfTimeAlign =
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
+ }
+ }
+
+ self->streamInfo.extAot = asc->m_extensionAudioObjectType;
+ if (self->streamInfo.extSamplingRate !=
+ (INT)asc->m_extensionSamplingFrequency) {
+ ascChanged = 1;
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency;
+ }
+ self->flags[streamIndex] |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0;
+ self->flags[streamIndex] |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0;
+ if (asc->m_sbrPresentFlag) {
+ self->sbrEnabled = 1;
+ self->sbrEnabledPrev = 1;
+ } else {
+ self->sbrEnabled = 0;
+ self->sbrEnabledPrev = 0;
+ }
+ if (self->sbrEnabled && asc->m_extensionSamplingFrequency) {
+ if (downscaleFactor != 1 && (downscaleFactor)&1) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale
+ factor */
+ }
+ if (configMode & AC_CM_ALLOC_MEM) {
+ self->streamInfo.extSamplingRate =
+ self->streamInfo.extSamplingRate / self->downscaleFactor;
+ }
+ }
+
+ /* --------- vcb11 ------------ */
+ self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0;
+
+ /* ---------- rvlc ------------ */
+ self->flags[streamIndex] |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0;
+
+ /* ----------- hcr ------------ */
+ self->flags[streamIndex] |= (asc->m_hcrFlag) ? AC_ER_HCR : 0;
+
+ if (asc->m_aot == AOT_ER_AAC_ELD) {
+ self->mpsEnableCurr = 0;
+ self->flags[streamIndex] |= AC_ELD;
+ self->flags[streamIndex] |=
+ (asc->m_sbrPresentFlag)
+ ? AC_SBR_PRESENT
+ : 0; /* Need to set the SBR flag for backward-compatibility
+ reasons. Even if SBR is not supported. */
+ self->flags[streamIndex] |=
+ (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0;
+ self->flags[streamIndex] |=
+ (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_MPS_PRESENT
+ : 0;
+ if (self->mpsApplicable) {
+ self->mpsEnableCurr = asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign;
+ }
+ }
+ self->flags[streamIndex] |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0;
+ self->flags[streamIndex] |= (asc->m_epConfig >= 0) ? AC_ER : 0;
+
+ if (asc->m_aot == AOT_USAC) {
+ self->flags[streamIndex] |= AC_USAC;
+ self->flags[streamIndex] |=
+ (asc->m_sc.m_usacConfig.element[0].m_stereoConfigIndex > 0)
+ ? AC_MPS_PRESENT
+ : 0;
+ }
+ if (asc->m_aot == AOT_DRM_AAC) {
+ self->flags[streamIndex] |= AC_DRM | AC_SBRCRC | AC_SCALABLE;
+ }
+ if (asc->m_aot == AOT_DRM_SURROUND) {
+ self->flags[streamIndex] |=
+ AC_DRM | AC_SBRCRC | AC_SCALABLE | AC_MPS_PRESENT;
+ FDK_ASSERT(!asc->m_psPresentFlag);
+ }
+ if ((asc->m_aot == AOT_AAC_SCAL) || (asc->m_aot == AOT_ER_AAC_SCAL)) {
+ self->flags[streamIndex] |= AC_SCALABLE;
+ }
+
+ if ((asc->m_epConfig >= 0) && (asc->m_channelConfiguration <= 0)) {
+ /* we have to know the number of channels otherwise no decoding is possible
+ */
+ return AAC_DEC_UNSUPPORTED_ER_FORMAT;
+ }
+
+ self->streamInfo.epConfig = asc->m_epConfig;
+ /* self->hInput->asc.m_epConfig = asc->m_epConfig; */
+
+ if (asc->m_epConfig > 1) return AAC_DEC_UNSUPPORTED_ER_FORMAT;
+
+ /* Check if samplerate changed. */
+ if ((self->samplingRateInfo[streamIndex].samplingRate !=
+ asc->m_samplingFrequency) ||
+ (self->streamInfo.aacSamplesPerFrame !=
+ (INT)asc->m_samplesPerFrame / downscaleFactor)) {
+ AAC_DECODER_ERROR error;
+
+ ascChanged = 1;
+
+ if (configMode & AC_CM_ALLOC_MEM) {
+ /* Update samplerate info. */
+ error = getSamplingRateInfo(
+ &self->samplingRateInfo[streamIndex], asc->m_samplesPerFrame,
+ asc->m_samplingFrequencyIndex, asc->m_samplingFrequency);
+ if (error != AAC_DEC_OK) {
+ return error;
+ }
+ self->streamInfo.aacSampleRate =
+ self->samplingRateInfo[0].samplingRate / self->downscaleFactor;
+ self->streamInfo.aacSamplesPerFrame =
+ asc->m_samplesPerFrame / self->downscaleFactor;
+ }
+ }
+
+ /* Check if amount of channels has changed. */
+ if (self->ascChannels[streamIndex] != ascChannels) {
+ ascChanged = 1;
+ }
+
+ /* detect config change */
+ if (configMode & AC_CM_DET_CFG_CHANGE) {
+ if (ascChanged != 0) {
+ *configChanged = 1;
+ }
+ return err;
+ }
+
+ /* set AC_USAC_SCFGI3 globally if any usac element uses */
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ if (self->sbrEnabled) {
+ for (int _el = 0;
+ _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements;
+ _el++) {
+ int el = elementOffset + _el;
+ if (IS_USAC_CHANNEL_ELEMENT(self->elements[el])) {
+ if (usacStereoConfigIndex < 0) {
+ usacStereoConfigIndex = self->usacStereoConfigIndex[el];
+ } else {
+ if ((usacStereoConfigIndex != self->usacStereoConfigIndex[el]) ||
+ (self->usacStereoConfigIndex[el] > 0)) {
+ goto bail;
+ }
+ }
+ }
+ }
+
+ if (usacStereoConfigIndex < 0) {
+ goto bail;
+ }
+
+ if (usacStereoConfigIndex == 3) {
+ self->flags[streamIndex] |= AC_USAC_SCFGI3;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (*configChanged) {
+ /* Set up QMF domain for AOTs with explicit signalling of SBR and or MPS.
+ This is to be able to play out the first frame alway with the correct
+ frame size and sampling rate even in case of concealment.
+ */
+ switch (asc->m_aot) {
+ case AOT_USAC:
+ if (self->sbrEnabled) {
+ const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32};
+
+ FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0);
+ FDK_ASSERT(streamIndex == 0);
+
+ self->qmfDomain.globalConf.nInputChannels_requested = ascChannels;
+ self->qmfDomain.globalConf.nOutputChannels_requested =
+ (usacStereoConfigIndex == 1) ? 2 : ascChannels;
+ self->qmfDomain.globalConf.flags_requested = 0;
+ self->qmfDomain.globalConf.nBandsAnalysis_requested =
+ map_sbrRatio_2_nAnaBands[asc->m_sc.m_usacConfig.m_sbrRatioIndex -
+ 1];
+ self->qmfDomain.globalConf.nBandsSynthesis_requested = 64;
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested =
+ (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 64 : 32;
+ self->qmfDomain.globalConf.nQmfOvTimeSlots_requested =
+ (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 12 : 6;
+ self->qmfDomain.globalConf.nQmfProcBands_requested = 64;
+ self->qmfDomain.globalConf.nQmfProcChannels_requested = 1;
+ self->qmfDomain.globalConf.parkChannel =
+ (usacStereoConfigIndex == 3) ? 1 : 0;
+ self->qmfDomain.globalConf.parkChannel_requested =
+ (usacStereoConfigIndex == 3) ? 1 : 0;
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
+ }
+ break;
+ case AOT_ER_AAC_ELD:
+ if (self->mpsEnableCurr &&
+ asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) {
+ SAC_INPUT_CONFIG sac_interface =
+ (self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF
+ : SAC_INTERFACE_TIME;
+ mpegSurroundDecoder_ConfigureQmfDomain(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
+ (UINT)self->streamInfo.aacSampleRate, asc->m_aot);
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1;
+ }
+ break;
+ default:
+ self->qmfDomain.globalConf.qmfDomainExplicitConfig =
+ 0; /* qmfDomain is initialized by SBR and MPS init functions if
+ required */
+ break;
+ }
+
+ /* Allocate all memory structures for each channel */
+ {
+ int ch = aacChannelsOffset;
+ for (int _ch = 0; _ch < ascChannels; _ch++) {
+ if (ch >= (8)) {
+ goto bail;
+ }
+ self->pAacDecoderChannelInfo[ch] = GetAacDecoderChannelInfo(ch);
+ /* This is temporary until the DynamicData is split into two or more
+ regions! The memory could be reused after completed core decoding. */
+ if (self->pAacDecoderChannelInfo[ch] == NULL) {
+ goto bail;
+ }
+ ch++;
+ }
+
+ int chIdx = aacChannelsOffsetIdx;
+ ch = aacChannelsOffset;
+ int _numElements;
+ _numElements = (((8)) + (8));
+ if (self->flags[streamIndex] & (AC_RSV603DA | AC_USAC)) {
+ _numElements = (int)asc->m_sc.m_usacConfig.m_usacNumElements;
+ }
+ for (int _el = 0; _el < _numElements; _el++) {
+ int el_channels = 0;
+ int el = elementOffset + _el;
+
+ if (self->flags[streamIndex] &
+ (AC_ER | AC_LD | AC_ELD | AC_RSV603DA | AC_USAC | AC_RSVD50)) {
+ if (ch >= ascChannels) {
+ break;
+ }
+ }
+
+ switch (self->elements[el]) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+
+ el_channels = CAacDecoder_GetELChannels(
+ self->elements[el], self->usacStereoConfigIndex[el]);
+
+ {
+ self->pAacDecoderChannelInfo[ch]->pComStaticData =
+ (CAacDecoderCommonStaticData *)FDKcalloc(
+ 1, sizeof(CAacDecoderCommonStaticData));
+ if (self->pAacDecoderChannelInfo[ch]->pComStaticData == NULL) {
+ goto bail;
+ }
+ if (ch == aacChannelsOffset) {
+ self->pAacDecoderChannelInfo[ch]->pComData =
+ (CAacDecoderCommonData *)GetWorkBufferCore6();
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 = GetWorkBufferCore1();
+ } else {
+ self->pAacDecoderChannelInfo[ch]->pComData =
+ (CAacDecoderCommonData *)FDKaalloc(
+ sizeof(CAacDecoderCommonData), ALIGNMENT_DEFAULT);
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 =
+ self->pAacDecoderChannelInfo[aacChannelsOffset]
+ ->pComStaticData->pWorkBufferCore1;
+ }
+ if ((self->pAacDecoderChannelInfo[ch]->pComData == NULL) ||
+ (self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1 == NULL)) {
+ goto bail;
+ }
+ self->pAacDecoderChannelInfo[ch]->pDynData =
+ &(self->pAacDecoderChannelInfo[ch]
+ ->pComData->pAacDecoderDynamicData[0]);
+ self->pAacDecoderChannelInfo[ch]->pSpectralCoefficient =
+ (SPECTRAL_PTR)&self->workBufferCore2[ch * 1024];
+
+ if (el_channels == 2) {
+ if (ch >= (8) - 1) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+ self->pAacDecoderChannelInfo[ch + 1]->pComData =
+ self->pAacDecoderChannelInfo[ch]->pComData;
+ self->pAacDecoderChannelInfo[ch + 1]->pComStaticData =
+ self->pAacDecoderChannelInfo[ch]->pComStaticData;
+ self->pAacDecoderChannelInfo[ch + 1]
+ ->pComStaticData->pWorkBufferCore1 =
+ self->pAacDecoderChannelInfo[ch]
+ ->pComStaticData->pWorkBufferCore1;
+ self->pAacDecoderChannelInfo[ch + 1]->pDynData =
+ &(self->pAacDecoderChannelInfo[ch]
+ ->pComData->pAacDecoderDynamicData[1]);
+ self->pAacDecoderChannelInfo[ch + 1]->pSpectralCoefficient =
+ (SPECTRAL_PTR)&self->workBufferCore2[(ch + 1) * 1024];
+ }
+
+ ch += el_channels;
+ }
+ chIdx += el_channels;
+ break;
+
+ default:
+ break;
+ }
+
+ if (self->elements[el] == ID_END) {
+ break;
+ }
+
+ el++;
+ }
+
+ chIdx = aacChannelsOffsetIdx;
+ ch = aacChannelsOffset;
+ for (int _ch = 0; _ch < ascChannels; _ch++) {
+ /* Allocate persistent channel memory */
+ {
+ self->pAacDecoderStaticChannelInfo[ch] =
+ GetAacDecoderStaticChannelInfo(ch);
+ if (self->pAacDecoderStaticChannelInfo[ch] == NULL) {
+ goto bail;
+ }
+ self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer =
+ GetOverlapBuffer(ch); /* This area size depends on the AOT */
+ if (self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer == NULL) {
+ goto bail;
+ }
+ if (self->flags[streamIndex] &
+ (AC_USAC | AC_RSVD50 | AC_RSV603DA /*|AC_BSAC*/)) {
+ self->pAacDecoderStaticChannelInfo[ch]->hArCo = CArco_Create();
+ if (self->pAacDecoderStaticChannelInfo[ch]->hArCo == NULL) {
+ goto bail;
+ }
+ }
+
+ if (!(self->flags[streamIndex] & (AC_USAC | AC_RSV603DA))) {
+ CPns_UpdateNoiseState(
+ &self->pAacDecoderChannelInfo[ch]->data.aac.PnsData,
+ &self->pAacDecoderStaticChannelInfo[ch]->pnsCurrentSeed,
+ self->pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
+ }
+ ch++;
+ }
+ chIdx++;
+ }
+
+ if (self->flags[streamIndex] & AC_USAC) {
+ for (int _ch = 0; _ch < flushChannels; _ch++) {
+ ch = aacChannelsOffset + _ch;
+ if (self->pTimeDataFlush[ch] == NULL) {
+ self->pTimeDataFlush[ch] = GetTimeDataFlush(ch);
+ if (self->pTimeDataFlush[ch] == NULL) {
+ goto bail;
+ }
+ }
+ }
+ }
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA)) {
+ int complexStereoPredPossible = 0;
+ ch = aacChannelsOffset;
+ chIdx = aacChannelsOffsetIdx;
+ for (int _el2 = 0; _el2 < (int)asc->m_sc.m_usacConfig.m_usacNumElements;
+ _el2++) {
+ int el2 = elementOffset + _el2;
+ int elCh = 0, ch2;
+
+ if ((self->elements[el2] == ID_USAC_CPE) &&
+ !(self->usacStereoConfigIndex[el2] == 1)) {
+ elCh = 2;
+ } else if (IS_CHANNEL_ELEMENT(self->elements[el2])) {
+ elCh = 1;
+ }
+
+ if (self->elFlags[el2] & AC_EL_USAC_CP_POSSIBLE) {
+ complexStereoPredPossible = 1;
+ if (self->cpeStaticData[el2] == NULL) {
+ self->cpeStaticData[el2] = GetCpePersistentData();
+ if (self->cpeStaticData[el2] == NULL) {
+ goto bail;
+ }
+ }
+ }
+
+ for (ch2 = 0; ch2 < elCh; ch2++) {
+ /* Hook element specific cpeStaticData into channel specific
+ * aacDecoderStaticChannelInfo */
+ self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData =
+ self->cpeStaticData[el2];
+ if (self->pAacDecoderStaticChannelInfo[ch]->pCpeStaticData !=
+ NULL) {
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData
+ .spectralCoeffs[ch2] =
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.spectralCoefficient;
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[ch2] =
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.specScale;
+ self->pAacDecoderStaticChannelInfo[ch]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
+ (FIXP_DBL *)self->pTimeData2;
+ }
+ chIdx++;
+ ch++;
+ } /* for each channel in current element */
+ if (complexStereoPredPossible && (elCh == 2)) {
+ /* needed once for all channels */
+ if (self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData == NULL) {
+ self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData =
+ GetCplxPredictionData();
+ }
+ if (self->pAacDecoderChannelInfo[ch - 1]
+ ->pComStaticData->cplxPredictionData == NULL) {
+ goto bail;
+ }
+ }
+ if (elCh > 0) {
+ self->pAacDecoderStaticChannelInfo[ch - elCh]->nfRandomSeed =
+ (ULONG)0x3039;
+ if (self->elements[el2] == ID_USAC_CPE) {
+ if (asc->m_sc.m_usacConfig.element[el2].m_stereoConfigIndex !=
+ 1) {
+ self->pAacDecoderStaticChannelInfo[ch - elCh + 1]
+ ->nfRandomSeed = (ULONG)0x10932;
+ }
+ }
+ }
+ } /* for each element */
+ }
+
+ if (ascChannels != self->aacChannels) {
+ /* Make allocated channel count persistent in decoder context. */
+ self->aacChannels = aacChannelsOffset + ch;
+ }
+ }
+
+ if (usacResidualDelayCompSamples) {
+ INT delayErr = FDK_Delay_Create(&self->usacResidualDelay,
+ (USHORT)usacResidualDelayCompSamples, 1);
+ if (delayErr) {
+ goto bail;
+ }
+ }
+
+ /* Make amount of signalled channels persistent in decoder context. */
+ self->ascChannels[streamIndex] = ascChannels;
+ /* Init the previous channel count values. This is required to avoid a
+ mismatch of memory accesses in the error concealment module and the
+ allocated channel structures in this function. */
+ self->aacChannelsPrev = 0;
+ }
+
+ if (self->pAacDecoderChannelInfo[0] != NULL) {
+ self->pDrmBsBuffer = self->pAacDecoderChannelInfo[0]
+ ->pComStaticData->pWorkBufferCore1->DrmBsBuffer;
+ self->drmBsBufferSize = DRM_BS_BUFFER_SIZE;
+ }
+
+ /* Update structures */
+ if (*configChanged) {
+ /* Things to be done for each channel, which do not involve allocating
+ memory. Doing these things only on the channels needed for the current
+ configuration (ascChannels) could lead to memory access violation later
+ (error concealment). */
+ int ch = 0;
+ int chIdx = 0;
+ for (int _ch = 0; _ch < self->ascChannels[streamIndex]; _ch++) {
+ switch (self->streamInfo.aot) {
+ case AOT_ER_AAC_ELD:
+ case AOT_ER_AAC_LD:
+ self->pAacDecoderChannelInfo[ch]->granuleLength =
+ self->streamInfo.aacSamplesPerFrame;
+ break;
+ default:
+ self->pAacDecoderChannelInfo[ch]->granuleLength =
+ self->streamInfo.aacSamplesPerFrame / 8;
+ break;
+ }
+ self->pAacDecoderChannelInfo[ch]->renderMode = initRenderMode;
+
+ mdct_init(&self->pAacDecoderStaticChannelInfo[ch]->IMdct,
+ self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
+ OverlapBufferSize);
+
+ self->pAacDecoderStaticChannelInfo[ch]->last_core_mode = FD_LONG;
+ self->pAacDecoderStaticChannelInfo[ch]->last_lpd_mode = 255;
+
+ self->pAacDecoderStaticChannelInfo[ch]->last_tcx_pitch = L_DIV;
+
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->drcData);
+
+ /* Delete mixdown metadata from the past */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+
+ /* Reset concealment only if ASC changed. Otherwise it will be done with
+ any config callback. E.g. every time the LATM SMC is present. */
+ CConcealment_InitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ &self->concealCommonData, initRenderMode,
+ self->streamInfo.aacSamplesPerFrame);
+ ch++;
+ chIdx++;
+ }
+ }
+
+ /* Update externally visible copy of flags */
+ self->streamInfo.flags = self->flags[0];
+
+ if (*configChanged) {
+ int drcDecSampleRate, drcDecFrameSize;
+
+ if (self->streamInfo.extSamplingRate != 0) {
+ drcDecSampleRate = self->streamInfo.extSamplingRate;
+ drcDecFrameSize = (self->streamInfo.aacSamplesPerFrame *
+ self->streamInfo.extSamplingRate) /
+ self->streamInfo.aacSampleRate;
+ } else {
+ drcDecSampleRate = self->streamInfo.aacSampleRate;
+ drcDecFrameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+
+ if (FDK_drcDec_Init(self->hUniDrcDecoder, drcDecFrameSize, drcDecSampleRate,
+ self->aacChannels) != 0)
+ goto bail;
+ }
+
+ if (asc->m_aot == AOT_USAC) {
+ pcmLimiter_SetAttack(self->hLimiter, (5));
+ pcmLimiter_SetThreshold(self->hLimiter, FL2FXCONST_DBL(0.89125094f));
+ }
+
+ return err;
+
+bail:
+ CAacDecoder_DeInit(self, 0);
+ return AAC_DEC_OUT_OF_MEMORY;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
+ HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
+ const INT timeDataSize, const int timeDataChannelOffset) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ CProgramConfig *pce;
+ HANDLE_FDK_BITSTREAM bs = transportDec_GetBitstream(self->hInput, 0);
+
+ MP4_ELEMENT_ID type = ID_NONE; /* Current element type */
+ INT aacChannels = 0; /* Channel counter for channels found in the bitstream */
+ const int streamIndex = 0; /* index of the current substream */
+
+ INT auStartAnchor = (INT)FDKgetValidBits(
+ bs); /* AU start bit buffer position for AU byte alignment */
+
+ INT checkSampleRate = self->streamInfo.aacSampleRate;
+
+ INT CConceal_TDFading_Applied[(8)] = {
+ 0}; /* Initialize status of Time Domain fading */
+
+ if (self->aacChannels <= 0) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ /* Any supported base layer valid AU will require more than 16 bits. */
+ if ((transportDec_GetAuBitsRemaining(self->hInput, 0) < 15) &&
+ (flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) == 0) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ /* Reset Program Config structure */
+ pce = &self->pce;
+ CProgramConfig_Reset(pce);
+
+ CAacDecoder_AncDataReset(&self->ancData);
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
+ !(self->flags[0] & (AC_USAC | AC_RSV603DA))) {
+ int ch;
+ if (self->streamInfo.channelConfig == 0) {
+ /* Init Channel/Element mapping table */
+ for (ch = 0; ch < (8); ch++) {
+ self->chMapping[ch] = 255;
+ }
+ if (!CProgramConfig_IsValid(pce)) {
+ int el;
+ for (el = 0; el < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ el++) {
+ self->elements[el] = ID_NONE;
+ }
+ }
+ }
+ }
+
+ if (self->downscaleFactor > 1 && (self->flags[0] & AC_ELD)) {
+ self->flags[0] |= AC_ELD_DOWNSCALE;
+ } else {
+ self->flags[0] &= ~AC_ELD_DOWNSCALE;
+ }
+ /* unsupported dsf (aacSampleRate has not yet been divided by dsf) -> divide
+ */
+ if (self->downscaleFactorInBS > 1 &&
+ (self->flags[0] & AC_ELD_DOWNSCALE) == 0) {
+ checkSampleRate =
+ self->streamInfo.aacSampleRate / self->downscaleFactorInBS;
+ }
+
+ /* Check sampling frequency */
+ if (self->streamInfo.aacSampleRate <= 0) {
+ /* Instance maybe uninitialized! */
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
+ }
+ switch (checkSampleRate) {
+ case 96000:
+ case 88200:
+ case 64000:
+ case 16000:
+ case 12000:
+ case 11025:
+ case 8000:
+ case 7350:
+ case 48000:
+ case 44100:
+ case 32000:
+ case 24000:
+ case 22050:
+ break;
+ default:
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ return AAC_DEC_UNSUPPORTED_SAMPLINGRATE;
+ }
+ break;
+ }
+
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ int ch;
+ /* Clear history */
+ for (ch = 0; ch < self->aacChannels; ch++) {
+ /* Reset concealment */
+ CConcealment_InitChannelData(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ &self->concealCommonData,
+ self->pAacDecoderChannelInfo[0]->renderMode,
+ self->streamInfo.aacSamplesPerFrame);
+ /* Clear overlap-add buffers to avoid clicks. */
+ FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer,
+ OverlapBufferSize * sizeof(FIXP_DBL));
+ }
+ if (self->streamInfo.channelConfig > 0) {
+ /* Declare the possibly adopted old PCE (with outdated metadata)
+ * invalid. */
+ CProgramConfig_Init(pce);
+ }
+ }
+ }
+
+ int pceRead = 0; /* Flag indicating a PCE in the current raw_data_block() */
+
+ INT hdaacDecoded = 0;
+ MP4_ELEMENT_ID previous_element =
+ ID_END; /* Last element ID (required for extension payload mapping */
+ UCHAR previous_element_index = 0; /* Canonical index of last element */
+ int element_count =
+ 0; /* Element counter for elements found in the bitstream */
+ int channel_element_count = 0; /* Channel element counter */
+ MP4_ELEMENT_ID
+ channel_elements[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /* Channel elements in bit stream order. */
+ int el_cnt[ID_LAST] = {0}; /* element counter ( robustness ) */
+ int element_count_prev_streams =
+ 0; /* Element count of all previous sub streams. */
+
+ while ((type != ID_END) && (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) &&
+ self->frameOK) {
+ int el_channels;
+
+ if (!(self->flags[0] &
+ (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD | AC_SCALABLE | AC_ER)))
+ type = (MP4_ELEMENT_ID)FDKreadBits(bs, 3);
+ else {
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ type = self->elements[element_count];
+ }
+
+ if ((self->flags[streamIndex] & (AC_USAC | AC_RSVD50) &&
+ element_count == 0) ||
+ (self->flags[streamIndex] & AC_RSV603DA)) {
+ self->flags[streamIndex] &= ~AC_INDEP;
+
+ if (FDKreadBit(bs)) {
+ self->flags[streamIndex] |= AC_INDEP;
+ }
+
+ int ch = aacChannels;
+ for (int chIdx = aacChannels; chIdx < self->ascChannels[streamIndex];
+ chIdx++) {
+ {
+ /* Robustness check */
+ if (ch >= self->aacChannels) {
+ return AAC_DEC_UNKNOWN;
+ }
+
+ /* if last frame was broken and this frame is no independent frame,
+ * correct decoding is impossible we need to trigger concealment */
+ if ((CConcealment_GetLastFrameOk(
+ &self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo,
+ 1) == 0) &&
+ !(self->flags[streamIndex] & AC_INDEP)) {
+ self->frameOK = 0;
+ }
+ ch++;
+ }
+ }
+ }
+
+ if ((INT)FDKgetValidBits(bs) < 0) {
+ self->frameOK = 0;
+ }
+
+ switch (type) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ el_channels = CAacDecoder_GetELChannels(
+ type, self->usacStereoConfigIndex[element_count]);
+
+ /*
+ Consistency check
+ */
+ {
+ int totalAscChannels = 0;
+
+ for (int i = 0; i < (1 * 1); i++) {
+ totalAscChannels += self->ascChannels[i];
+ }
+ if ((el_cnt[type] >= (totalAscChannels >> (el_channels - 1))) ||
+ (aacChannels > (totalAscChannels - el_channels))) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+ }
+
+ if (!(self->flags[streamIndex] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ int ch;
+ for (ch = 0; ch < el_channels; ch += 1) {
+ CPns_ResetData(&self->pAacDecoderChannelInfo[aacChannels + ch]
+ ->data.aac.PnsData,
+ &self->pAacDecoderChannelInfo[aacChannels + ch]
+ ->pComData->pnsInterChannelData);
+ }
+ }
+
+ if (self->frameOK) {
+ ErrorStatus = CChannelElement_Read(
+ bs, &self->pAacDecoderChannelInfo[aacChannels],
+ &self->pAacDecoderStaticChannelInfo[aacChannels],
+ self->streamInfo.aot, &self->samplingRateInfo[streamIndex],
+ self->flags[streamIndex], self->elFlags[element_count],
+ self->streamInfo.aacSamplesPerFrame, el_channels,
+ self->streamInfo.epConfig, self->hInput);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+
+ if (self->frameOK) {
+ /* Lookup the element and decode it only if it belongs to the current
+ * program */
+ if (CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig,
+ self->pAacDecoderChannelInfo[aacChannels]->ElementInstanceTag,
+ aacChannels, self->chMapping, self->channelType,
+ self->channelIndices, (8), &previous_element_index,
+ self->elements, type)) {
+ channel_elements[channel_element_count++] = type;
+ aacChannels += el_channels;
+ } else {
+ self->frameOK = 0;
+ }
+ /* Create SBR element for SBR for upsampling for LFE elements,
+ and if SBR was implicitly signaled, because the first frame(s)
+ may not contain SBR payload (broken encoder, bit errors). */
+ if (self->frameOK &&
+ ((self->flags[streamIndex] & AC_SBR_PRESENT) ||
+ (self->sbrEnabled == 1)) &&
+ !(self->flags[streamIndex] &
+ AC_USAC) /* Is done during explicit config set up */
+ ) {
+ SBR_ERROR sbrError;
+ UCHAR configMode = 0;
+ UCHAR configChanged = 0;
+ configMode |= AC_CM_ALLOC_MEM;
+
+ sbrError = sbrDecoder_InitElement(
+ self->hSbrDecoder, self->streamInfo.aacSampleRate,
+ self->streamInfo.extSamplingRate,
+ self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot, type,
+ previous_element_index, 2, /* Signalize that harmonicSBR shall
+ be ignored in the config change
+ detection */
+ 0, configMode, &configChanged, self->downscaleFactor);
+ if (sbrError != SBRDEC_OK) {
+ /* Do not try to apply SBR because initializing the element
+ * failed. */
+ self->sbrEnabled = 0;
+ }
+ }
+ }
+
+ el_cnt[type]++;
+ if (self->frameOK && (self->flags[streamIndex] & AC_USAC) &&
+ (type == ID_USAC_CPE || type == ID_USAC_SCE)) {
+ ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
+ self, bs, previous_element, previous_element_index, element_count,
+ el_cnt);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ }
+ }
+ break;
+
+ case ID_CCE:
+ /*
+ Consistency check
+ */
+ if (el_cnt[type] > self->ascChannels[streamIndex]) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+
+ if (self->frameOK) {
+ CAacDecoderCommonData commonData;
+ CAacDecoderCommonStaticData commonStaticData;
+ CWorkBufferCore1 workBufferCore1;
+ commonStaticData.pWorkBufferCore1 = &workBufferCore1;
+ /* memory for spectral lines temporal on scratch */
+ C_AALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024);
+
+ /* create dummy channel for CCE parsing on stack */
+ CAacDecoderChannelInfo tmpAacDecoderChannelInfo,
+ *pTmpAacDecoderChannelInfo;
+
+ FDKmemclear(mdctSpec, 1024 * sizeof(FIXP_DBL));
+
+ tmpAacDecoderChannelInfo.pDynData = commonData.pAacDecoderDynamicData;
+ tmpAacDecoderChannelInfo.pComData = &commonData;
+ tmpAacDecoderChannelInfo.pComStaticData = &commonStaticData;
+ tmpAacDecoderChannelInfo.pSpectralCoefficient =
+ (SPECTRAL_PTR)mdctSpec;
+ /* Assume AAC-LC */
+ tmpAacDecoderChannelInfo.granuleLength =
+ self->streamInfo.aacSamplesPerFrame / 8;
+ /* Reset PNS data. */
+ CPns_ResetData(
+ &tmpAacDecoderChannelInfo.data.aac.PnsData,
+ &tmpAacDecoderChannelInfo.pComData->pnsInterChannelData);
+ pTmpAacDecoderChannelInfo = &tmpAacDecoderChannelInfo;
+ /* do CCE parsing */
+ ErrorStatus = CChannelElement_Read(
+ bs, &pTmpAacDecoderChannelInfo, NULL, self->streamInfo.aot,
+ &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
+ AC_EL_GA_CCE, self->streamInfo.aacSamplesPerFrame, 1,
+ self->streamInfo.epConfig, self->hInput);
+
+ C_AALLOC_SCRATCH_END(mdctSpec, FIXP_DBL, 1024);
+
+ if (ErrorStatus) {
+ self->frameOK = 0;
+ }
+
+ if (self->frameOK) {
+ /* Lookup the element and decode it only if it belongs to the
+ * current program */
+ if (CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig,
+ pTmpAacDecoderChannelInfo->ElementInstanceTag, 0,
+ self->chMapping, self->channelType, self->channelIndices,
+ (8), &previous_element_index, self->elements, type)) {
+ /* decoding of CCE not supported */
+ } else {
+ self->frameOK = 0;
+ }
+ }
+ }
+ el_cnt[type]++;
+ break;
+
+ case ID_DSE: {
+ UCHAR element_instance_tag;
+
+ CDataStreamElement_Read(self, bs, &element_instance_tag, auStartAnchor);
+
+ if (!CProgramConfig_LookupElement(
+ pce, self->streamInfo.channelConfig, element_instance_tag, 0,
+ self->chMapping, self->channelType, self->channelIndices, (8),
+ &previous_element_index, self->elements, type)) {
+ /* most likely an error in bitstream occured */
+ // self->frameOK = 0;
+ }
+ } break;
+
+ case ID_PCE: {
+ int result = CProgramConfigElement_Read(bs, self->hInput, pce,
+ self->streamInfo.channelConfig,
+ auStartAnchor);
+ if (result < 0) {
+ /* Something went wrong */
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ self->frameOK = 0;
+ } else if (result > 1) {
+ /* Built element table */
+ int elIdx = CProgramConfig_GetElementTable(
+ pce, self->elements, (((8)) + (8)), &self->chMapIndex);
+ /* Reset the remaining tabs */
+ for (; elIdx < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1);
+ elIdx++) {
+ self->elements[elIdx] = ID_NONE;
+ }
+ /* Make new number of channel persistent */
+ self->ascChannels[streamIndex] = pce->NumChannels;
+ /* If PCE is not first element conceal this frame to avoid
+ * inconsistencies */
+ if (element_count != 0) {
+ self->frameOK = 0;
+ }
+ }
+ pceRead = (result >= 0) ? 1 : 0;
+ } break;
+
+ case ID_FIL: {
+ int bitCnt = FDKreadBits(bs, 4); /* bs_count */
+
+ if (bitCnt == 15) {
+ int esc_count = FDKreadBits(bs, 8); /* bs_esc_count */
+ bitCnt = esc_count + 14;
+ }
+
+ /* Convert to bits */
+ bitCnt <<= 3;
+
+ while (bitCnt > 0) {
+ ErrorStatus = CAacDecoder_ExtPayloadParse(
+ self, bs, &bitCnt, previous_element, previous_element_index, 1);
+ if (ErrorStatus != AAC_DEC_OK) {
+ self->frameOK = 0;
+ break;
+ }
+ }
+ } break;
+
+ case ID_EXT:
+ if (element_count >= (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr(
+ self, bs, previous_element, previous_element_index, element_count,
+ el_cnt);
+ break;
+
+ case ID_USAC_EXT: {
+ if ((element_count - element_count_prev_streams) >=
+ TP_USAC_MAX_ELEMENTS) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ /* parse extension element payload
+ q.v. rsv603daExtElement() ISO/IEC DIS 23008-3 Table 30
+ or UsacExElement() ISO/IEC FDIS 23003-3:2011(E) Table 21
+ */
+ int usacExtElementPayloadLength;
+ /* int usacExtElementStart, usacExtElementStop; */
+
+ if (FDKreadBit(bs)) { /* usacExtElementPresent */
+ if (FDKreadBit(bs)) { /* usacExtElementUseDefaultLength */
+ usacExtElementPayloadLength =
+ self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementDefaultLength;
+ } else {
+ usacExtElementPayloadLength = FDKreadBits(bs, 8);
+ if (usacExtElementPayloadLength == (UINT)(1 << 8) - 1) {
+ UINT valueAdd = FDKreadBits(bs, 16);
+ usacExtElementPayloadLength += (INT)valueAdd - 2;
+ }
+ }
+ if (usacExtElementPayloadLength > 0) {
+ int usacExtBitPos;
+
+ if (self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementPayloadFrag) {
+ /* usacExtElementStart = */ FDKreadBit(bs);
+ /* usacExtElementStop = */ FDKreadBit(bs);
+ } else {
+ /* usacExtElementStart = 1; */
+ /* usacExtElementStop = 1; */
+ }
+
+ usacExtBitPos = (INT)FDKgetValidBits(bs);
+
+ USAC_EXT_ELEMENT_TYPE usacExtElementType =
+ self->pUsacConfig[streamIndex]
+ ->element[element_count - element_count_prev_streams]
+ .extElement.usacExtElementType;
+
+ switch (usacExtElementType) {
+ case ID_EXT_ELE_UNI_DRC: /* uniDrcGain() */
+ if (streamIndex == 0) {
+ int drcErr;
+
+ drcErr = FDK_drcDec_ReadUniDrcGain(self->hUniDrcDecoder, bs);
+ if (drcErr != 0) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ /* Skip any remaining bits of extension payload */
+ usacExtBitPos = (usacExtElementPayloadLength * 8) -
+ (usacExtBitPos - (INT)FDKgetValidBits(bs));
+ if (usacExtBitPos < 0) {
+ self->frameOK = 0;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ FDKpushBiDirectional(bs, usacExtBitPos);
+ }
+ }
+ } break;
+ case ID_END:
+ case ID_USAC_END:
+ break;
+
+ default:
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ self->frameOK = 0;
+ break;
+ }
+
+ previous_element = type;
+ element_count++;
+
+ } /* while ( (type != ID_END) ... ) */
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ /* float decoder checks if bitsLeft is in range 0-7; only prerollAUs are
+ * byteAligned with respect to the first bit */
+ /* Byte alignment with respect to the first bit of the raw_data_block(). */
+ if (!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
+ (self->prerollAULength[self->accessUnit]) /* indicates preroll */
+ ) {
+ FDKbyteAlign(bs, auStartAnchor);
+ }
+
+ /* Check if all bits of the raw_data_block() have been read. */
+ if (transportDec_GetAuBitsTotal(self->hInput, 0) > 0) {
+ INT unreadBits = transportDec_GetAuBitsRemaining(self->hInput, 0);
+ /* for pre-roll frames pre-roll length has to be used instead of total AU
+ * lenght */
+ /* unreadBits regarding preroll bounds */
+ if (self->prerollAULength[self->accessUnit]) {
+ unreadBits = unreadBits - transportDec_GetAuBitsTotal(self->hInput, 0) +
+ (INT)self->prerollAULength[self->accessUnit];
+ }
+ if (((self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) &&
+ ((unreadBits < 0) || (unreadBits > 7)) &&
+ !(self->prerollAULength[self->accessUnit])) ||
+ ((!(self->flags[streamIndex] & (AC_RSVD50 | AC_USAC)) ||
+ (self->prerollAULength[self->accessUnit])) &&
+ (unreadBits != 0))) {
+ if ((((unreadBits < 0) || (unreadBits > 7)) && self->frameOK) &&
+ ((transportDec_GetFormat(self->hInput) == TT_DRM) &&
+ (self->flags[streamIndex] & AC_USAC))) {
+ /* Set frame OK because of fill bits. */
+ self->frameOK = 1;
+ } else {
+ self->frameOK = 0;
+ }
+
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK && self->frameOK == 0) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ /* Always put the bitbuffer at the right position after the current
+ * Access Unit. */
+ FDKpushBiDirectional(bs, unreadBits);
+ }
+ }
+
+ /* Check the last element. The terminator (ID_END) has to be the last one
+ * (even if ER syntax is used). */
+ if (self->frameOK && type != ID_END) {
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+ self->frameOK = 0;
+ }
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
+ channel_elements[channel_element_count++] = ID_END;
+ }
+ element_count = 0;
+ aacChannels = 0;
+ type = ID_NONE;
+ previous_element_index = 0;
+
+ while (type != ID_END &&
+ element_count < (3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)) {
+ int el_channels;
+
+ if ((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || !self->frameOK) {
+ channel_elements[element_count] = self->elements[element_count];
+ if (channel_elements[element_count] == ID_NONE) {
+ channel_elements[element_count] = ID_END;
+ }
+ }
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
+ type = self->elements[element_count];
+ } else {
+ type = channel_elements[element_count];
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) && self->frameOK) {
+ switch (type) {
+ case ID_SCE:
+ case ID_CPE:
+ case ID_LFE:
+ case ID_USAC_SCE:
+ case ID_USAC_CPE:
+ case ID_USAC_LFE:
+
+ el_channels = CAacDecoder_GetELChannels(
+ type, self->usacStereoConfigIndex[element_count]);
+
+ if (!hdaacDecoded) {
+ if (self->pAacDecoderStaticChannelInfo[aacChannels]
+ ->pCpeStaticData != NULL) {
+ self->pAacDecoderStaticChannelInfo[aacChannels]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer =
+ (FIXP_DBL *)pTimeData;
+ }
+ CChannelElement_Decode(
+ &self->pAacDecoderChannelInfo[aacChannels],
+ &self->pAacDecoderStaticChannelInfo[aacChannels],
+ &self->samplingRateInfo[streamIndex], self->flags[streamIndex],
+ self->elFlags[element_count], el_channels);
+ }
+ aacChannels += el_channels;
+ break;
+ case ID_NONE:
+ type = ID_END;
+ break;
+ default:
+ break;
+ }
+ }
+ element_count++;
+ }
+
+ /* More AAC channels than specified by the ASC not allowed. */
+ if ((aacChannels == 0 || aacChannels > self->aacChannels) &&
+ !(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ /* Do not overwrite current error */
+ if (ErrorStatus == AAC_DEC_OK) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ self->frameOK = 0;
+ aacChannels = 0;
+ }
+
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) {
+ if (TRANSPORTDEC_OK != transportDec_CrcCheck(self->hInput)) {
+ ErrorStatus = AAC_DEC_CRC_ERROR;
+ self->frameOK = 0;
+ }
+ }
+
+ /* Ensure that in case of concealment a proper error status is set. */
+ if ((self->frameOK == 0) && (ErrorStatus == AAC_DEC_OK)) {
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ if (self->frameOK && (flags & AACDEC_FLUSH)) {
+ aacChannels = self->aacChannelsPrev;
+ /* Because the downmix could be active, its necessary to restore the channel
+ * type and indices. */
+ FDKmemcpy(self->channelType, self->channelTypePrev,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
+ FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
+ (8) * sizeof(UCHAR)); /* restore */
+ self->sbrEnabled = self->sbrEnabledPrev;
+ } else {
+ /* store or restore the number of channels and the corresponding info */
+ if (self->frameOK && !(flags & AACDEC_CONCEAL)) {
+ self->aacChannelsPrev = aacChannels; /* store */
+ FDKmemcpy(self->channelTypePrev, self->channelType,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* store */
+ FDKmemcpy(self->channelIndicesPrev, self->channelIndices,
+ (8) * sizeof(UCHAR)); /* store */
+ self->sbrEnabledPrev = self->sbrEnabled;
+ } else {
+ if (self->aacChannels > 0) {
+ if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ aacChannels = self->aacChannels;
+ self->aacChannelsPrev = aacChannels; /* store */
+ } else {
+ aacChannels = self->aacChannelsPrev; /* restore */
+ }
+ FDKmemcpy(self->channelType, self->channelTypePrev,
+ (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */
+ FDKmemcpy(self->channelIndices, self->channelIndicesPrev,
+ (8) * sizeof(UCHAR)); /* restore */
+ self->sbrEnabled = self->sbrEnabledPrev;
+ }
+ }
+ }
+
+ /* Update number of output channels */
+ self->streamInfo.aacNumChannels = aacChannels;
+
+ /* Ensure consistency of IS_OUTPUT_VALID() macro. */
+ if (aacChannels == 0) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ }
+
+ if (pceRead == 1 && CProgramConfig_IsValid(pce)) {
+ /* Set matrix mixdown infos if available from PCE. */
+ pcmDmx_SetMatrixMixdownFromPce(
+ self->hPcmUtils, pce->MatrixMixdownIndexPresent,
+ pce->MatrixMixdownIndex, pce->PseudoSurroundEnable);
+ ;
+ }
+
+ /* If there is no valid data to transfrom into time domain, return. */
+ if (!IS_OUTPUT_VALID(ErrorStatus)) {
+ return ErrorStatus;
+ }
+
+ /* Setup the output channel mapping. The table below shows the three
+ * possibilities: # | chCfg | PCE | chMapIndex
+ * ---+-------+-----+------------------
+ * 1 | > 0 | no | chCfg
+ * 2 | 0 | yes | cChCfg
+ * 3 | 0 | no | aacChannels || 0
+ * ---+-------+-----+--------+------------------
+ * Where chCfg is the channel configuration index from ASC and cChCfg is a
+ * corresponding chCfg derived from a given PCE. The variable aacChannels
+ * represents the number of channel found during bitstream decoding. Due to
+ * the structure of the mapping table it can only be used for mapping if its
+ * value is smaller than 7. Otherwise we use the fallback (0) which is a
+ * simple pass-through. The possibility #3 should appear only with MPEG-2
+ * (ADTS) streams. This is mode is called "implicit channel mapping".
+ */
+ if ((self->streamInfo.channelConfig == 0) && !pce->isValid) {
+ self->chMapIndex = (aacChannels < 7) ? aacChannels : 0;
+ }
+
+ /*
+ Inverse transform
+ */
+ {
+ int c, cIdx;
+ int mapped, fCopyChMap = 1;
+ UCHAR drcChMap[(8)];
+
+ if ((self->streamInfo.channelConfig == 0) && CProgramConfig_IsValid(pce)) {
+ /* ISO/IEC 14496-3 says:
+ If a PCE is present, the exclude_mask bits correspond to the audio
+ channels in the SCE, CPE, CCE and LFE syntax elements in the order of
+ their appearance in the PCE. In the case of a CPE, the first
+ transmitted mask bit corresponds to the first channel in the CPE, the
+ second transmitted mask bit to the second channel. In the case of a
+ CCE, a mask bit is transmitted only if the coupling channel is
+ specified to be an independently switched coupling channel. Thus we
+ have to convert the internal channel mapping from "canonical" MPEG to
+ PCE order: */
+ UCHAR tmpChMap[(8)];
+ if (CProgramConfig_GetPceChMap(pce, tmpChMap, (8)) == 0) {
+ for (c = 0; c < aacChannels; c += 1) {
+ drcChMap[c] =
+ (self->chMapping[c] == 255) ? 255 : tmpChMap[self->chMapping[c]];
+ }
+ fCopyChMap = 0;
+ }
+ }
+ if (fCopyChMap != 0) {
+ FDKmemcpy(drcChMap, self->chMapping, (8) * sizeof(UCHAR));
+ }
+
+ /* Turn on/off DRC modules level normalization in digital domain depending
+ * on the limiter status. */
+ aacDecoder_drcSetParam(self->hDrcInfo, APPLY_NORMALIZATION,
+ (self->limiterEnableCurr) ? 0 : 1);
+
+ /* deactivate legacy DRC in case uniDrc is active, i.e. uniDrc payload is
+ * present and one of DRC or Loudness Normalization is switched on */
+ aacDecoder_drcSetParam(
+ self->hDrcInfo, UNIDRC_PRECEDENCE,
+ FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE));
+
+ /* Extract DRC control data and map it to channels (without bitstream delay)
+ */
+ mapped = aacDecoder_drcProlog(
+ self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
+ pce->ElementInstanceTag, drcChMap, aacChannels);
+ if (mapped > 0) {
+ /* If at least one DRC thread has been mapped to a channel threre was DRC
+ * data in the bitstream. */
+ self->flags[streamIndex] |= AC_DRC_PRESENT;
+ }
+
+ /* Create a reverse mapping table */
+ UCHAR Reverse_chMapping[((8) * 2)];
+ for (c = 0; c < aacChannels; c++) {
+ int d;
+ for (d = 0; d < aacChannels - 1; d++) {
+ if (self->chMapping[d] == c) {
+ break;
+ }
+ }
+ Reverse_chMapping[c] = d;
+ }
+
+ int el;
+ int el_channels;
+ c = 0;
+ cIdx = 0;
+ el_channels = 0;
+ for (el = 0; el < element_count; el++) {
+ int frameOk_butConceal =
+ 0; /* Force frame concealment during mute release active state. */
+ int concealApplyReturnCode;
+
+ if (self->flags[streamIndex] & (AC_USAC | AC_RSV603DA | AC_BSAC)) {
+ type = self->elements[el];
+ } else {
+ type = channel_elements[el];
+ }
+
+ {
+ int nElementChannels;
+
+ nElementChannels =
+ CAacDecoder_GetELChannels(type, self->usacStereoConfigIndex[el]);
+
+ el_channels += nElementChannels;
+
+ if (nElementChannels == 0) {
+ continue;
+ }
+ }
+
+ int offset;
+ int elCh = 0;
+ /* "c" iterates in canonical MPEG channel order */
+ for (; cIdx < el_channels; c++, cIdx++, elCh++) {
+ /* Robustness check */
+ if (c >= aacChannels) {
+ return AAC_DEC_UNKNOWN;
+ }
+
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo =
+ self->pAacDecoderChannelInfo[c];
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
+ self->pAacDecoderStaticChannelInfo[c];
+
+ /* Setup offset for time buffer traversal. */
+ {
+ pAacDecoderStaticChannelInfo =
+ self->pAacDecoderStaticChannelInfo[Reverse_chMapping[c]];
+ offset =
+ FDK_chMapDescr_getMapValue(
+ &self->mapDescr, Reverse_chMapping[cIdx], self->chMapIndex) *
+ timeDataChannelOffset;
+ }
+
+ if (flags & AACDEC_FLUSH) {
+ /* Clear pAacDecoderChannelInfo->pSpectralCoefficient because with
+ * AACDEC_FLUSH set it contains undefined data. */
+ FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
+ sizeof(FIXP_DBL) * self->streamInfo.aacSamplesPerFrame);
+ }
+
+ /* if The ics info is not valid and it will be stored and used in the
+ * following concealment method, mark the frame as erroneous */
+ {
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ CConcealmentInfo *hConcealmentInfo =
+ &pAacDecoderStaticChannelInfo->concealmentInfo;
+ const int mute_release_active =
+ (self->frameOK && !(flags & AACDEC_CONCEAL)) &&
+ ((hConcealmentInfo->concealState >= ConcealState_Mute) &&
+ (hConcealmentInfo->cntValidFrames + 1 <=
+ hConcealmentInfo->pConcealParams->numMuteReleaseFrames));
+ const int icsIsInvalid = (GetScaleFactorBandsTransmitted(pIcsInfo) >
+ GetScaleFactorBandsTotal(pIcsInfo));
+ const int icsInfoUsedinFadeOut =
+ !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 0);
+ if (icsInfoUsedinFadeOut && icsIsInvalid && !mute_release_active) {
+ self->frameOK = 0;
+ }
+ }
+
+ /*
+ Conceal defective spectral data
+ */
+ {
+ CAacDecoderChannelInfo **ppAacDecoderChannelInfo =
+ &pAacDecoderChannelInfo;
+ CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo =
+ &pAacDecoderStaticChannelInfo;
+ {
+ concealApplyReturnCode = CConcealment_Apply(
+ &(*ppAacDecoderStaticChannelInfo)->concealmentInfo,
+ *ppAacDecoderChannelInfo, *ppAacDecoderStaticChannelInfo,
+ &self->samplingRateInfo[streamIndex],
+ self->streamInfo.aacSamplesPerFrame,
+ pAacDecoderStaticChannelInfo->last_lpd_mode,
+ (self->frameOK && !(flags & AACDEC_CONCEAL)),
+ self->flags[streamIndex]);
+ }
+ }
+ if (concealApplyReturnCode == -1) {
+ frameOk_butConceal = 1;
+ }
+
+ if (flags & (AACDEC_INTR)) {
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(&pAacDecoderStaticChannelInfo->drcData);
+ }
+ if (flags & (AACDEC_CLRHIST)) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* Reset DRC control data for this channel */
+ aacDecoder_drcInitChannelData(
+ &pAacDecoderStaticChannelInfo->drcData);
+ }
+ }
+ /* The DRC module demands to be called with the gain field holding the
+ * gain scale. */
+ self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING;
+ /* DRC processing */
+ aacDecoder_drcApply(
+ self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo,
+ &pAacDecoderStaticChannelInfo->drcData, self->extGain, c,
+ self->streamInfo.aacSamplesPerFrame, self->sbrEnabled
+
+ );
+
+ if (timeDataSize < timeDataChannelOffset * self->aacChannels) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ break;
+ }
+ if (self->flushStatus && (self->flushCnt > 0) &&
+ !(flags & AACDEC_CONCEAL)) {
+ FDKmemclear(pTimeData + offset,
+ sizeof(FIXP_PCM) * self->streamInfo.aacSamplesPerFrame);
+ } else
+ switch (pAacDecoderChannelInfo->renderMode) {
+ case AACDEC_RENDER_IMDCT:
+
+ CBlock_FrequencyToTime(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
+ (self->frameOK && !(flags & AACDEC_CONCEAL) &&
+ !frameOk_butConceal),
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1
+ ->mdctOutTemp,
+ self->elFlags[el], elCh);
+
+ self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
+ break;
+ case AACDEC_RENDER_ELDFB: {
+ CBlock_FrequencyToTimeLowDelay(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame);
+ self->extGainDelay =
+ (self->streamInfo.aacSamplesPerFrame * 2 -
+ self->streamInfo.aacSamplesPerFrame / 2 - 1) /
+ 2;
+ } break;
+ case AACDEC_RENDER_LPD:
+
+ CLpd_RenderTimeSignal(
+ pAacDecoderStaticChannelInfo, pAacDecoderChannelInfo,
+ pTimeData + offset, self->streamInfo.aacSamplesPerFrame,
+ &self->samplingRateInfo[streamIndex],
+ (self->frameOK && !(flags & AACDEC_CONCEAL) &&
+ !frameOk_butConceal),
+ flags, self->flags[streamIndex]);
+
+ self->extGainDelay = self->streamInfo.aacSamplesPerFrame;
+ break;
+ default:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ break;
+ }
+ /* TimeDomainFading */
+ if (!CConceal_TDFading_Applied[c]) {
+ CConceal_TDFading_Applied[c] = CConcealment_TDFading(
+ self->streamInfo.aacSamplesPerFrame,
+ &self->pAacDecoderStaticChannelInfo[c], pTimeData + offset, 0);
+ if (c + 1 < (8) && c < aacChannels - 1) {
+ /* update next TDNoise Seed to avoid muting in case of Parametric
+ * Stereo */
+ self->pAacDecoderStaticChannelInfo[c + 1]
+ ->concealmentInfo.TDNoiseSeed =
+ self->pAacDecoderStaticChannelInfo[c]
+ ->concealmentInfo.TDNoiseSeed;
+ }
+ }
+ }
+ }
+
+ if (self->flags[streamIndex] & AC_USAC) {
+ int bsPseudoLr = 0;
+ mpegSurroundDecoder_IsPseudoLR(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, &bsPseudoLr);
+ /* ISO/IEC 23003-3, 7.11.2.6 Modification of core decoder output (pseudo
+ * LR) */
+ if ((aacChannels == 2) && bsPseudoLr) {
+ int i, offset2;
+ const FIXP_SGL invSqrt2 = FL2FXCONST_SGL(0.707106781186547f);
+ FIXP_PCM *pTD = pTimeData;
+
+ offset2 = timeDataChannelOffset;
+
+ for (i = 0; i < self->streamInfo.aacSamplesPerFrame; i++) {
+ FIXP_DBL L = FX_PCM2FX_DBL(pTD[0]);
+ FIXP_DBL R = FX_PCM2FX_DBL(pTD[offset2]);
+ L = fMult(L, invSqrt2);
+ R = fMult(R, invSqrt2);
+#if (SAMPLE_BITS == 16)
+ pTD[0] = FX_DBL2FX_PCM(fAddSaturate(L + R, (FIXP_DBL)0x8000));
+ pTD[offset2] = FX_DBL2FX_PCM(fAddSaturate(L - R, (FIXP_DBL)0x8000));
+#else
+ pTD[0] = FX_DBL2FX_PCM(L + R);
+ pTD[offset2] = FX_DBL2FX_PCM(L - R);
+#endif
+ pTD++;
+ }
+ }
+ }
+
+ /* Extract DRC control data and map it to channels (with bitstream delay) */
+ mapped = aacDecoder_drcEpilog(
+ self->hDrcInfo, bs, self->pAacDecoderStaticChannelInfo,
+ pce->ElementInstanceTag, drcChMap, aacChannels);
+ if (mapped > 0) {
+ /* If at least one DRC thread has been mapped to a channel threre was DRC
+ * data in the bitstream. */
+ self->flags[streamIndex] |= AC_DRC_PRESENT;
+ }
+ }
+
+ /* Add additional concealment delay */
+ self->streamInfo.outputDelay +=
+ CConcealment_GetDelay(&self->concealCommonData) *
+ self->streamInfo.aacSamplesPerFrame;
+
+ /* Map DRC data to StreamInfo structure */
+ aacDecoder_drcGetInfo(self->hDrcInfo, &self->streamInfo.drcPresMode,
+ &self->streamInfo.drcProgRefLev);
+
+ /* Reorder channel type information tables. */
+ if (!(self->flags[0] & AC_RSV603DA)) {
+ AUDIO_CHANNEL_TYPE types[(8)];
+ UCHAR idx[(8)];
+ int c;
+ int mapValue;
+
+ FDK_ASSERT(sizeof(self->channelType) == sizeof(types));
+ FDK_ASSERT(sizeof(self->channelIndices) == sizeof(idx));
+
+ FDKmemcpy(types, self->channelType, sizeof(types));
+ FDKmemcpy(idx, self->channelIndices, sizeof(idx));
+
+ for (c = 0; c < aacChannels; c++) {
+ mapValue =
+ FDK_chMapDescr_getMapValue(&self->mapDescr, c, self->chMapIndex);
+ self->channelType[mapValue] = types[c];
+ self->channelIndices[mapValue] = idx[c];
+ }
+ }
+
+ self->blockNumber++;
+
+ return ErrorStatus;
+}
+
+/*!
+ \brief returns the streaminfo pointer
+
+ The function hands back a pointer to the streaminfo structure
+
+ \return pointer to the struct
+*/
+LINKSPEC_CPP CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
+ if (!self) {
+ return NULL;
+ }
+ return &self->streamInfo;
+}
diff --git a/fdk-aac/libAACdec/src/aacdecoder.h b/fdk-aac/libAACdec/src/aacdecoder.h
new file mode 100644
index 0000000..20f4c45
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder.h
@@ -0,0 +1,465 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef AACDECODER_H
+#define AACDECODER_H
+
+#include "common_fix.h"
+
+#include "FDK_bitstream.h"
+
+#include "channel.h"
+
+#include "tpdec_lib.h"
+#include "FDK_audio.h"
+
+#include "block.h"
+
+#include "genericStds.h"
+
+#include "FDK_qmf_domain.h"
+
+#include "sbrdecoder.h"
+
+#include "aacdec_drc.h"
+
+#include "pcmdmx_lib.h"
+
+#include "FDK_drcDecLib.h"
+
+#include "limiter.h"
+
+#include "FDK_delay.h"
+
+#define TIME_DATA_FLUSH_SIZE (128)
+#define TIME_DATA_FLUSH_SIZE_SF (7)
+
+#define AACDEC_MAX_NUM_PREROLL_AU_USAC (3)
+#if (AACDEC_MAX_NUM_PREROLL_AU < 3)
+#undef AACDEC_MAX_NUM_PREROLL_AU
+#define AACDEC_MAX_NUM_PREROLL_AU AACDEC_MAX_NUM_PREROLL_AU_USAC
+#endif
+
+typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER;
+
+enum { L = 0, R = 1 };
+
+typedef struct {
+ unsigned char *buffer;
+ int bufferSize;
+ int offset[8];
+ int nrElements;
+} CAncData;
+
+typedef enum { NOT_DEFINED = -1, MODE_HQ = 0, MODE_LP = 1 } QMF_MODE;
+
+typedef struct {
+ int bsDelay;
+} SBR_PARAMS;
+
+enum {
+ AACDEC_FLUSH_OFF = 0,
+ AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1,
+ AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON = 2,
+ AACDEC_USAC_DASH_IPF_FLUSH_ON = 3
+};
+
+enum {
+ AACDEC_BUILD_UP_OFF = 0,
+ AACDEC_RSV60_BUILD_UP_ON = 1,
+ AACDEC_RSV60_BUILD_UP_ON_IN_BAND = 2,
+ AACDEC_USAC_BUILD_UP_ON = 3,
+ AACDEC_RSV60_BUILD_UP_IDLE = 4,
+ AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND = 5
+};
+
+typedef struct {
+ /* Usac Extension Elements */
+ USAC_EXT_ELEMENT_TYPE usacExtElementType[(3)];
+ UINT usacExtElementDefaultLength[(3)];
+ UCHAR usacExtElementPayloadFrag[(3)];
+} CUsacCoreExtensions;
+
+/* AAC decoder (opaque toward userland) struct declaration */
+struct AAC_DECODER_INSTANCE {
+ INT aacChannels; /*!< Amount of AAC decoder channels allocated. */
+ INT ascChannels[(1 *
+ 1)]; /*!< Amount of AAC decoder channels signalled in ASC. */
+ INT blockNumber; /*!< frame counter */
+
+ INT nrOfLayers;
+
+ INT outputInterleaved; /*!< PCM output format (interleaved/none interleaved).
+ */
+
+ HANDLE_TRANSPORTDEC hInput; /*!< Transport layer handle. */
+
+ SamplingRateInfo
+ samplingRateInfo[(1 * 1)]; /*!< Sampling Rate information table */
+
+ UCHAR
+ frameOK; /*!< Will be unset if a consistency check, e.g. CRC etc. fails */
+
+ UINT flags[(1 * 1)]; /*!< Flags for internal decoder use. DO NOT USE
+ self::streaminfo::flags ! */
+ UINT elFlags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Flags for internal decoder use (element specific). DO
+ NOT USE self::streaminfo::flags ! */
+
+ MP4_ELEMENT_ID elements[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Table where the element Id's are listed */
+ UCHAR elTags[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Table where the elements id Tags are listed */
+ UCHAR chMapping[((8) * 2)]; /*!< Table of MPEG canonical order to bitstream
+ channel order mapping. */
+
+ AUDIO_CHANNEL_TYPE channelType[(8)]; /*!< Audio channel type of each output
+ audio channel (from 0 upto
+ numChannels). */
+ UCHAR channelIndices[(8)]; /*!< Audio channel index for each output audio
+ channel (from 0 upto numChannels). */
+ /* See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a
+ * program_config_element() */
+
+ FDK_channelMapDescr mapDescr; /*!< Describes the output channel mapping. */
+ UCHAR chMapIndex; /*!< Index to access one line of the channelOutputMapping
+ table. This is required because not all 8 channel
+ configurations have the same output mapping. */
+ INT sbrDataLen; /*!< Expected length of the SBR remaining in bitbuffer after
+ the AAC payload has been pared. */
+
+ CProgramConfig pce;
+ CStreamInfo
+ streamInfo; /*!< Pointer to StreamInfo data (read from the bitstream) */
+ CAacDecoderChannelInfo
+ *pAacDecoderChannelInfo[(8)]; /*!< Temporal channel memory */
+ CAacDecoderStaticChannelInfo
+ *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */
+
+ FIXP_DBL *workBufferCore2;
+ PCM_DEC *pTimeData2;
+ INT timeData2Size;
+
+ CpePersistentData *cpeStaticData[(
+ 3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) +
+ 1)]; /*!< Pointer to persistent data shared by both channels of a CPE.
+This structure is allocated once for each CPE. */
+
+ CConcealParams concealCommonData;
+ CConcealmentMethod concealMethodUser;
+
+ CUsacCoreExtensions usacCoreExt; /*!< Data and handles to extend USAC FD/LPD
+ core decoder (SBR, MPS, ...) */
+ UINT numUsacElements[(1 * 1)];
+ UCHAR usacStereoConfigIndex[(3 * ((8) * 2) + (((8) * 2)) / 2 + 4 * (1) + 1)];
+ const CSUsacConfig *pUsacConfig[(1 * 1)];
+ INT nbDiv; /*!< number of frame divisions in LPD-domain */
+
+ UCHAR useLdQmfTimeAlign;
+
+ INT aacChannelsPrev; /*!< The amount of AAC core channels of the last
+ successful decode call. */
+ AUDIO_CHANNEL_TYPE channelTypePrev[(8)]; /*!< Array holding the channelType
+ values of the last successful
+ decode call. */
+ UCHAR
+ channelIndicesPrev[(8)]; /*!< Array holding the channelIndices values of
+ the last successful decode call. */
+
+ UCHAR
+ downscaleFactor; /*!< Variable to store a supported ELD downscale factor
+ of 1, 2, 3 or 4 */
+ UCHAR downscaleFactorInBS; /*!< Variable to store the (not necessarily
+ supported) ELD downscale factor discovered in
+ the bitstream */
+
+ HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */
+ UCHAR sbrEnabled; /*!< flag to store if SBR has been detected */
+ UCHAR sbrEnabledPrev; /*!< flag to store if SBR has been detected from
+ previous frame */
+ UCHAR psPossible; /*!< flag to store if PS is possible */
+ SBR_PARAMS sbrParams; /*!< struct to store all sbr parameters */
+
+ UCHAR *pDrmBsBuffer; /*!< Pointer to dynamic buffer which is used to reverse
+ the bits of the DRM SBR payload */
+ USHORT drmBsBufferSize; /*!< Size of the dynamic buffer which is used to
+ reverse the bits of the DRM SBR payload */
+ FDK_QMF_DOMAIN
+ qmfDomain; /*!< Instance of module for QMF domain data handling */
+
+ QMF_MODE qmfModeCurr; /*!< The current QMF mode */
+ QMF_MODE qmfModeUser; /*!< The QMF mode requested by the library user */
+
+ HANDLE_AAC_DRC hDrcInfo; /*!< handle to DRC data structure */
+ INT metadataExpiry; /*!< Metadata expiry time in milli-seconds. */
+
+ void *pMpegSurroundDecoder; /*!< pointer to mpeg surround decoder structure */
+ UCHAR mpsEnableUser; /*!< MPS enable user flag */
+ UCHAR mpsEnableCurr; /*!< MPS enable decoder state */
+ UCHAR mpsApplicable; /*!< MPS applicable */
+ SCHAR mpsOutputMode; /*!< setting: normal = 0, binaural = 1, stereo = 2, 5.1ch
+ = 3 */
+ INT mpsOutChannelsLast; /*!< The amount of channels returned by the last
+ successful MPS decoder call. */
+ INT mpsFrameSizeLast; /*!< The frame length returned by the last successful
+ MPS decoder call. */
+
+ CAncData ancData; /*!< structure to handle ancillary data */
+
+ HANDLE_PCM_DOWNMIX hPcmUtils; /*!< privat data for the PCM utils. */
+
+ TDLimiterPtr hLimiter; /*!< Handle of time domain limiter. */
+ UCHAR limiterEnableUser; /*!< The limiter configuration requested by the
+ library user */
+ UCHAR limiterEnableCurr; /*!< The current limiter configuration. */
+ FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */
+ UINT extGainDelay; /*!< Delay that must be accounted for extGain. */
+
+ INT_PCM pcmOutputBuffer[(8) * (1024 * 2)];
+
+ HANDLE_DRC_DECODER hUniDrcDecoder;
+ UCHAR multibandDrcPresent;
+ UCHAR numTimeSlots;
+ UINT loudnessInfoSetPosition[3];
+ SCHAR defaultTargetLoudness;
+
+ INT_PCM
+ *pTimeDataFlush[((8) * 2)]; /*!< Pointer to the flushed time data which
+ will be used for the crossfade in case of
+ an USAC DASH IPF config change */
+
+ UCHAR flushStatus; /*!< Indicates flush status: on|off */
+ SCHAR flushCnt; /*!< Flush frame counter */
+ UCHAR buildUpStatus; /*!< Indicates build up status: on|off */
+ SCHAR buildUpCnt; /*!< Build up frame counter */
+ UCHAR hasAudioPreRoll; /*!< Indicates preRoll status: on|off */
+ UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU + 1]; /*!< Relative offset of
+ the prerollAU end
+ position to the AU
+ start position in the
+ bitstream */
+ INT accessUnit; /*!< Number of the actual processed preroll accessUnit */
+ UCHAR applyCrossfade; /*!< if set crossfade for seamless stream switching is
+ applied */
+
+ FDK_SignalDelay usacResidualDelay; /*!< Delay residual signal to compensate
+ for eSBR delay of DMX signal in case of
+ stereoConfigIndex==2. */
+};
+
+#define AAC_DEBUG_EXTHLP \
+ "\
+--- AAC-Core ---\n\
+ 0x00010000 Header data\n\
+ 0x00020000 CRC data\n\
+ 0x00040000 Channel info\n\
+ 0x00080000 Section data\n\
+ 0x00100000 Scalefactor data\n\
+ 0x00200000 Pulse data\n\
+ 0x00400000 Tns data\n\
+ 0x00800000 Quantized spectrum\n\
+ 0x01000000 Requantized spectrum\n\
+ 0x02000000 Time output\n\
+ 0x04000000 Fatal errors\n\
+ 0x08000000 Buffer fullness\n\
+ 0x10000000 Average bitrate\n\
+ 0x20000000 Synchronization\n\
+ 0x40000000 Concealment\n\
+ 0x7FFF0000 all AAC-Core-Info\n\
+"
+
+/**
+ * \brief Synchronise QMF mode for all modules using QMF data.
+ * \param self decoder handle
+ */
+void CAacDecoder_SyncQmfMode(HANDLE_AACDECODER self);
+
+/**
+ * \brief Signal a bit stream interruption to the decoder
+ * \param self decoder handle
+ */
+void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self);
+
+/*!
+ \brief Initialize ancillary buffer
+
+ \ancData Pointer to ancillary data structure
+ \buffer Pointer to (external) anc data buffer
+ \size Size of the buffer pointed on by buffer
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData,
+ unsigned char *buffer, int size);
+
+/*!
+ \brief Get one ancillary data element
+
+ \ancData Pointer to ancillary data structure
+ \index Index of the anc data element to get
+ \ptr Pointer to a buffer receiving a pointer to the requested anc data element
+ \size Pointer to a buffer receiving the length of the requested anc data
+ element
+
+ \return Error code
+*/
+AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index,
+ unsigned char **ptr, int *size);
+
+/* initialization of aac decoder */
+LINKSPEC_H HANDLE_AACDECODER CAacDecoder_Open(TRANSPORT_TYPE bsFormat);
+
+/* Initialization of channel elements */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self,
+ const CSAudioSpecificConfig *asc,
+ UCHAR configMode,
+ UCHAR *configChanged);
+/*!
+ \brief Decodes one aac frame
+
+ The function decodes one aac frame. The decoding of coupling channel
+ elements are not supported. The transport layer might signal, that the
+ data of the current frame is invalid, e.g. as a result of a packet
+ loss in streaming mode.
+ The bitstream position of transportDec_GetBitstream(self->hInput) must
+ be exactly the end of the access unit, including all byte alignment bits.
+ For this purpose, the variable auStartAnchor is used.
+
+ \return error status
+*/
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame(
+ HANDLE_AACDECODER self, const UINT flags, FIXP_PCM *pTimeData,
+ const INT timeDataSize, const int timeDataChannelOffset);
+
+/* Free config dependent AAC memory */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_FreeMem(HANDLE_AACDECODER self,
+ const int subStreamIndex);
+
+/* Prepare crossfade for USAC DASH IPF config change */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PrepareCrossFade(
+ const INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved);
+
+/* Apply crossfade for USAC DASH IPF config change */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_ApplyCrossFade(
+ INT_PCM *pTimeData, INT_PCM **pTimeDataFlush, const INT numChannels,
+ const INT frameSize, const INT interleaved);
+
+/* Set flush and build up mode */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_CtrlCFGChange(HANDLE_AACDECODER self,
+ UCHAR flushStatus,
+ SCHAR flushCnt,
+ UCHAR buildUpStatus,
+ SCHAR buildUpCnt);
+
+/* Parse preRoll Extension Payload */
+LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_PreRollExtensionPayloadParse(
+ HANDLE_AACDECODER self, UINT *numPrerollAU, UINT *prerollAUOffset,
+ UINT *prerollAULength);
+
+/* Destroy aac decoder */
+LINKSPEC_H void CAacDecoder_Close(HANDLE_AACDECODER self);
+
+/* get streaminfo handle from decoder */
+LINKSPEC_H CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self);
+
+#endif /* #ifndef AACDECODER_H */
diff --git a/fdk-aac/libAACdec/src/aacdecoder_lib.cpp b/fdk-aac/libAACdec/src/aacdecoder_lib.cpp
new file mode 100644
index 0000000..7df17b9
--- /dev/null
+++ b/fdk-aac/libAACdec/src/aacdecoder_lib.cpp
@@ -0,0 +1,2035 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description:
+
+*******************************************************************************/
+
+#include "aacdecoder_lib.h"
+
+#include "aac_ram.h"
+#include "aacdecoder.h"
+#include "tpdec_lib.h"
+#include "FDK_core.h" /* FDK_tools version info */
+
+#include "sbrdecoder.h"
+
+#include "conceal.h"
+
+#include "aacdec_drc.h"
+
+#include "sac_dec_lib.h"
+
+#include "pcm_utils.h"
+
+/* Decoder library info */
+#define AACDECODER_LIB_VL0 3
+#define AACDECODER_LIB_VL1 0
+#define AACDECODER_LIB_VL2 0
+#define AACDECODER_LIB_TITLE "AAC Decoder Lib"
+#ifdef __ANDROID__
+#define AACDECODER_LIB_BUILD_DATE ""
+#define AACDECODER_LIB_BUILD_TIME ""
+#else
+#define AACDECODER_LIB_BUILD_DATE __DATE__
+#define AACDECODER_LIB_BUILD_TIME __TIME__
+#endif
+
+static AAC_DECODER_ERROR setConcealMethod(const HANDLE_AACDECODER self,
+ const INT method);
+
+static void aacDecoder_setMetadataExpiry(const HANDLE_AACDECODER self,
+ const INT value) {
+ /* check decoder handle */
+ if (self != NULL) {
+ INT mdExpFrame = 0; /* default: disable */
+
+ if ((value > 0) &&
+ (self->streamInfo.aacSamplesPerFrame >
+ 0)) { /* Determine the corresponding number of frames: */
+ FIXP_DBL frameTime = fDivNorm(self->streamInfo.aacSampleRate,
+ self->streamInfo.aacSamplesPerFrame * 1000);
+ mdExpFrame = fMultIceil(frameTime, value);
+ }
+
+ /* Configure DRC module */
+ aacDecoder_drcSetParam(self->hDrcInfo, DRC_DATA_EXPIRY_FRAME, mdExpFrame);
+
+ /* Configure PCM downmix module */
+ pcmDmx_SetParam(self->hPcmUtils, DMX_BS_DATA_EXPIRY_FRAME, mdExpFrame);
+ }
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR
+aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes) {
+ /* reset free bytes */
+ *pFreeBytes = 0;
+
+ /* check handle */
+ if (!self) return AAC_DEC_INVALID_HANDLE;
+
+ /* return nr of free bytes */
+ HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0);
+ *pFreeBytes = FDKgetFreeBits(hBs) >> 3;
+
+ /* success */
+ return AAC_DEC_OK;
+}
+
+/**
+ * Config Decoder using a CSAudioSpecificConfig struct.
+ */
+static LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Config(
+ HANDLE_AACDECODER self, const CSAudioSpecificConfig *pAscStruct,
+ UCHAR configMode, UCHAR *configChanged) {
+ AAC_DECODER_ERROR err;
+
+ /* Initialize AAC core decoder, and update self->streaminfo */
+ err = CAacDecoder_Init(self, pAscStruct, configMode, configChanged);
+
+ if (!FDK_chMapDescr_isValid(&self->mapDescr)) {
+ return AAC_DEC_UNSUPPORTED_CHANNELCONFIG;
+ }
+
+ return err;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self,
+ UCHAR *conf[],
+ const UINT length[]) {
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+ UINT layer, nrOfLayers = self->nrOfLayers;
+
+ for (layer = 0; layer < nrOfLayers; layer++) {
+ if (length[layer] > 0) {
+ errTp = transportDec_OutOfBandConfig(self->hInput, conf[layer],
+ length[layer], layer);
+ if (errTp != TRANSPORTDEC_OK) {
+ switch (errTp) {
+ case TRANSPORTDEC_NEED_TO_RESTART:
+ err = AAC_DEC_NEED_TO_RESTART;
+ break;
+ case TRANSPORTDEC_UNSUPPORTED_FORMAT:
+ err = AAC_DEC_UNSUPPORTED_FORMAT;
+ break;
+ default:
+ err = AAC_DEC_UNKNOWN;
+ break;
+ }
+ /* if baselayer is OK we continue decoding */
+ if (layer >= 1) {
+ self->nrOfLayers = layer;
+ err = AAC_DEC_OK;
+ }
+ break;
+ }
+ }
+ }
+
+ return err;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self,
+ UCHAR *buffer,
+ UINT length) {
+ FDK_BITSTREAM bs;
+ HANDLE_FDK_BITSTREAM hBs = &bs;
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+
+ if (length < 8) return AAC_DEC_UNKNOWN;
+
+ while (length >= 8) {
+ UINT size =
+ (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
+ DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;
+
+ if (length < size) return AAC_DEC_UNKNOWN;
+ if (size <= 8) return AAC_DEC_UNKNOWN;
+
+ FDKinitBitStream(hBs, buffer + 8, 0x10000000, (size - 8) * 8);
+
+ if ((buffer[4] == 'l') && (buffer[5] == 'u') && (buffer[6] == 'd') &&
+ (buffer[7] == 't')) {
+ uniDrcErr = FDK_drcDec_ReadLoudnessBox(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'd') && (buffer[5] == 'm') && (buffer[6] == 'i') &&
+ (buffer[7] == 'x')) {
+ uniDrcErr =
+ FDK_drcDec_ReadDownmixInstructions_Box(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'i') &&
+ (buffer[7] == '2')) {
+ uniDrcErr =
+ FDK_drcDec_ReadUniDrcInstructions_Box(self->hUniDrcDecoder, hBs);
+ } else if ((buffer[4] == 'u') && (buffer[5] == 'd') && (buffer[6] == 'c') &&
+ (buffer[7] == '2')) {
+ uniDrcErr =
+ FDK_drcDec_ReadUniDrcCoefficients_Box(self->hUniDrcDecoder, hBs);
+ }
+
+ if (uniDrcErr != DRC_DEC_OK) err = AAC_DEC_UNKNOWN;
+
+ buffer += size;
+ length -= size;
+ }
+
+ return err;
+}
+
+static INT aacDecoder_ConfigCallback(void *handle,
+ const CSAudioSpecificConfig *pAscStruct,
+ UCHAR configMode, UCHAR *configChanged) {
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+ AAC_DECODER_ERROR err = AAC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+
+ FDK_ASSERT(self != NULL);
+ {
+ { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); }
+ }
+ if (err == AAC_DEC_OK) {
+ /*
+ revert concealment method if either
+ - Interpolation concealment might not be meaningful
+ - Interpolation concealment is not implemented
+ */
+ if ((self->flags[0] & (AC_LD | AC_ELD) &&
+ (self->concealMethodUser == ConcealMethodNone) &&
+ CConcealment_GetDelay(&self->concealCommonData) >
+ 0) /* might not be meaningful but allow if user has set it
+ expicitly */
+ || (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) &&
+ CConcealment_GetDelay(&self->concealCommonData) >
+ 0) /* not implemented */
+ ) {
+ /* Revert to error concealment method Noise Substitution.
+ Because interpolation is not implemented for USAC or
+ the additional delay is unwanted for low delay codecs. */
+ setConcealMethod(self, 1);
+ }
+ aacDecoder_setMetadataExpiry(self, self->metadataExpiry);
+ errTp = TRANSPORTDEC_OK;
+ } else {
+ if (err == AAC_DEC_NEED_TO_RESTART) {
+ errTp = TRANSPORTDEC_NEED_TO_RESTART;
+ } else if (IS_INIT_ERROR(err)) {
+ errTp = TRANSPORTDEC_UNSUPPORTED_FORMAT;
+ } /* Fatal errors */
+ else {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ return errTp;
+}
+
+static INT aacDecoder_FreeMemCallback(void *handle,
+ const CSAudioSpecificConfig *pAscStruct) {
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+
+ const int subStreamIndex = 0;
+
+ FDK_ASSERT(self != NULL);
+
+ if (CAacDecoder_FreeMem(self, subStreamIndex) != AAC_DEC_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ /* free Ram_SbrDecoder and Ram_SbrDecChannel */
+ if (self->hSbrDecoder != NULL) {
+ if (sbrDecoder_FreeMem(&self->hSbrDecoder) != SBRDEC_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ /* free pSpatialDec and mpsData */
+ if (self->pMpegSurroundDecoder != NULL) {
+ if (mpegSurroundDecoder_FreeMem(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) != MPS_OK) {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+ }
+
+ /* free persistent qmf domain buffer, QmfWorkBufferCore3, QmfWorkBufferCore4,
+ * QmfWorkBufferCore5 and configuration variables */
+ FDK_QmfDomain_FreeMem(&self->qmfDomain);
+
+ return errTp;
+}
+
+static INT aacDecoder_CtrlCFGChangeCallback(
+ void *handle, const CCtrlCFGChange *pCtrlCFGChangeStruct) {
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
+
+ if (self != NULL) {
+ CAacDecoder_CtrlCFGChange(
+ self, pCtrlCFGChangeStruct->flushStatus, pCtrlCFGChangeStruct->flushCnt,
+ pCtrlCFGChangeStruct->buildUpStatus, pCtrlCFGChangeStruct->buildUpCnt);
+ } else {
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ return errTp;
+}
+
+static INT aacDecoder_SbrCallback(
+ void *handle, 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_SBRDECODER self = (HANDLE_SBRDECODER)handle;
+
+ INT errTp = sbrDecoder_Header(self, hBs, sampleRateIn, sampleRateOut,
+ samplesPerFrame, coreCodec, elementID,
+ elementIndex, harmonicSBR, stereoConfigIndex,
+ configMode, configChanged, downscaleFactor);
+
+ return errTp;
+}
+
+static INT aacDecoder_SscCallback(void *handle, 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) {
+ SACDEC_ERROR err;
+ TRANSPORTDEC_ERROR errTp;
+ HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
+
+ err = mpegSurroundDecoder_Config(
+ (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec,
+ samplingRate, frameSize, stereoConfigIndex, coreSbrFrameLengthIndex,
+ configBytes, configMode, configChanged);
+
+ switch (err) {
+ case MPS_UNSUPPORTED_CONFIG:
+ /* MPS found but invalid or not decodable by this instance */
+ /* We switch off MPS and keep going */
+ hAacDecoder->mpsEnableCurr = 0;
+ hAacDecoder->mpsApplicable = 0;
+ errTp = TRANSPORTDEC_OK;
+ break;
+ case MPS_PARSE_ERROR:
+ /* MPS found but invalid or not decodable by this instance */
+ hAacDecoder->mpsEnableCurr = 0;
+ hAacDecoder->mpsApplicable = 0;
+ if ((coreCodec == AOT_USAC) || (coreCodec == AOT_DRM_USAC) ||
+ IS_LOWDELAY(coreCodec)) {
+ errTp = TRANSPORTDEC_PARSE_ERROR;
+ } else {
+ errTp = TRANSPORTDEC_OK;
+ }
+ break;
+ case MPS_OK:
+ hAacDecoder->mpsApplicable = 1;
+ errTp = TRANSPORTDEC_OK;
+ break;
+ default:
+ /* especially Parsing error is critical for transport layer */
+ hAacDecoder->mpsApplicable = 0;
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+ }
+
+ return (INT)errTp;
+}
+
+static INT aacDecoder_UniDrcCallback(void *handle, HANDLE_FDK_BITSTREAM hBs,
+ const INT fullPayloadLength,
+ const INT payloadType,
+ const INT subStreamIndex,
+ const INT payloadStart,
+ const AUDIO_OBJECT_TYPE aot) {
+ DRC_DEC_ERROR err = DRC_DEC_OK;
+ TRANSPORTDEC_ERROR errTp;
+ HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle;
+ DRC_DEC_CODEC_MODE drcDecCodecMode = DRC_DEC_CODEC_MODE_UNDEFINED;
+
+ if (subStreamIndex != 0) {
+ return TRANSPORTDEC_OK;
+ }
+
+ else if (aot == AOT_USAC) {
+ drcDecCodecMode = DRC_DEC_MPEG_D_USAC;
+ }
+
+ err = FDK_drcDec_SetCodecMode(hAacDecoder->hUniDrcDecoder, drcDecCodecMode);
+ if (err) return (INT)TRANSPORTDEC_UNKOWN_ERROR;
+
+ if (payloadType == 0) /* uniDrcConfig */
+ {
+ err = FDK_drcDec_ReadUniDrcConfig(hAacDecoder->hUniDrcDecoder, hBs);
+ } else /* loudnessInfoSet */
+ {
+ err = FDK_drcDec_ReadLoudnessInfoSet(hAacDecoder->hUniDrcDecoder, hBs);
+ hAacDecoder->loudnessInfoSetPosition[1] = payloadStart;
+ hAacDecoder->loudnessInfoSetPosition[2] = fullPayloadLength;
+ }
+
+ if (err == DRC_DEC_OK)
+ errTp = TRANSPORTDEC_OK;
+ else
+ errTp = TRANSPORTDEC_UNKOWN_ERROR;
+
+ return (INT)errTp;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self,
+ UCHAR *buffer, int size) {
+ CAncData *ancData = &self->ancData;
+
+ return CAacDecoder_AncDataInit(ancData, buffer, size);
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self,
+ int index, UCHAR **ptr,
+ int *size) {
+ CAncData *ancData = &self->ancData;
+
+ return CAacDecoder_AncDataGet(ancData, index, ptr, size);
+}
+
+/* If MPS is present in stream, but not supported by this instance, we'll
+ have to switch off MPS and use QMF synthesis in the SBR module if required */
+static int isSupportedMpsConfig(AUDIO_OBJECT_TYPE aot,
+ unsigned int numInChannels,
+ unsigned int fMpsPresent) {
+ LIB_INFO libInfo[FDK_MODULE_LAST];
+ UINT mpsCaps;
+ int isSupportedCfg = 1;
+
+ FDKinitLibInfo(libInfo);
+
+ mpegSurroundDecoder_GetLibInfo(libInfo);
+
+ mpsCaps = FDKlibInfo_getCapabilities(libInfo, FDK_MPSDEC);
+
+ if (!(mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot)) {
+ /* We got an LD AOT but MPS decoder does not support LD. */
+ isSupportedCfg = 0;
+ }
+ if ((mpsCaps & CAPF_MPS_LD) && IS_LOWDELAY(aot) && !fMpsPresent) {
+ /* We got an LD AOT and the MPS decoder supports it.
+ * But LD-MPS is not explicitly signaled. */
+ isSupportedCfg = 0;
+ }
+ if (!(mpsCaps & CAPF_MPS_USAC) && IS_USAC(aot)) {
+ /* We got an USAC AOT but MPS decoder does not support USAC. */
+ isSupportedCfg = 0;
+ }
+ if (!(mpsCaps & CAPF_MPS_STD) && !IS_LOWDELAY(aot) && !IS_USAC(aot)) {
+ /* We got an GA AOT but MPS decoder does not support it. */
+ isSupportedCfg = 0;
+ }
+ /* Check whether the MPS modul supports the given number of input channels: */
+ switch (numInChannels) {
+ case 1:
+ if (!(mpsCaps & CAPF_MPS_1CH_IN)) {
+ /* We got a one channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ case 2:
+ if (!(mpsCaps & CAPF_MPS_2CH_IN)) {
+ /* We got a two channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ case 5:
+ case 6:
+ if (!(mpsCaps & CAPF_MPS_6CH_IN)) {
+ /* We got a six channel input to MPS decoder but it does not support it.
+ */
+ isSupportedCfg = 0;
+ }
+ break;
+ default:
+ isSupportedCfg = 0;
+ }
+
+ return (isSupportedCfg);
+}
+
+static AAC_DECODER_ERROR setConcealMethod(
+ const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
+ const INT method) {
+ AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
+ CConcealParams *pConcealData = NULL;
+ int method_revert = 0;
+ HANDLE_SBRDECODER hSbrDec = NULL;
+ HANDLE_AAC_DRC hDrcInfo = NULL;
+ HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
+ CConcealmentMethod backupMethod = ConcealMethodNone;
+ int backupDelay = 0;
+ int bsDelay = 0;
+
+ /* check decoder handle */
+ if (self != NULL) {
+ pConcealData = &self->concealCommonData;
+ hSbrDec = self->hSbrDecoder;
+ hDrcInfo = self->hDrcInfo;
+ hPcmDmx = self->hPcmUtils;
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
+ /* Interpolation concealment is not implemented for USAC/RSVD50 */
+ /* errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail; */
+ method_revert = 1;
+ }
+ if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) {
+ /* Interpolation concealment is not implemented for USAC/RSVD50 */
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+ /* Get current method/delay */
+ backupMethod = CConcealment_GetMethod(pConcealData);
+ backupDelay = CConcealment_GetDelay(pConcealData);
+
+ /* Be sure to set AAC and SBR concealment method simultaneously! */
+ errorStatus = CConcealment_SetParams(
+ pConcealData,
+ (method_revert == 0) ? (int)method : (int)1, // concealMethod
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeOutSlope
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealFadeInSlope
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, // concealMuteRelease
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED // concealComfNoiseLevel
+ );
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ goto bail;
+ }
+
+ /* Get new delay */
+ bsDelay = CConcealment_GetDelay(pConcealData);
+
+ {
+ SBR_ERROR sbrErr = SBRDEC_OK;
+
+ /* set SBR bitstream delay */
+ sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay);
+
+ switch (sbrErr) {
+ case SBRDEC_OK:
+ case SBRDEC_NOT_INITIALIZED:
+ if (self != NULL) {
+ /* save the param value and set later
+ (when SBR has been initialized) */
+ self->sbrParams.bsDelay = bsDelay;
+ }
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay);
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ goto bail;
+ }
+
+ if (errorStatus == AAC_DEC_OK) {
+ PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay);
+ switch (err) {
+ case PCMDMX_INVALID_HANDLE:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ case PCMDMX_OK:
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ }
+
+bail:
+ if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) {
+ /* Revert to the initial state */
+ CConcealment_SetParams(
+ pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED,
+ AACDEC_CONCEAL_PARAM_NOT_SPECIFIED);
+ /* Revert SBR bitstream delay */
+ sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay);
+ /* Revert DRC bitstream delay */
+ aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay);
+ /* Revert PCM mixdown bitstream delay */
+ pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, backupDelay);
+ }
+
+ return errorStatus;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_SetParam(
+ const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */
+ const AACDEC_PARAM param, /*!< Parameter to set */
+ const INT value) /*!< Parameter valued */
+{
+ AAC_DECODER_ERROR errorStatus = AAC_DEC_OK;
+ HANDLE_TRANSPORTDEC hTpDec = NULL;
+ TRANSPORTDEC_ERROR errTp = TRANSPORTDEC_OK;
+ HANDLE_AAC_DRC hDrcInfo = NULL;
+ HANDLE_PCM_DOWNMIX hPcmDmx = NULL;
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+ TDLimiterPtr hPcmTdl = NULL;
+ DRC_DEC_ERROR uniDrcErr = DRC_DEC_OK;
+
+ /* check decoder handle */
+ if (self != NULL) {
+ hTpDec = self->hInput;
+ hDrcInfo = self->hDrcInfo;
+ hPcmDmx = self->hPcmUtils;
+ hPcmTdl = self->hLimiter;
+ } else {
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ goto bail;
+ }
+
+ /* configure the subsystems */
+ switch (param) {
+ case AAC_PCM_MIN_OUTPUT_CHANNELS:
+ if (value < -1 || value > (8)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, MIN_NUMBER_OF_OUTPUT_CHANNELS, value);
+ break;
+
+ case AAC_PCM_MAX_OUTPUT_CHANNELS:
+ if (value < -1 || value > (8)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, MAX_NUMBER_OF_OUTPUT_CHANNELS, value);
+
+ if (dmxErr != PCMDMX_OK) {
+ goto bail;
+ }
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, MAX_OUTPUT_CHANNELS, value);
+ if (value > 0) {
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
+ DRC_DEC_TARGET_CHANNEL_COUNT_REQUESTED,
+ (FIXP_DBL)value);
+ }
+ break;
+
+ case AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE:
+ dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_DUAL_CHANNEL_MODE, value);
+ break;
+
+ case AAC_PCM_LIMITER_ENABLE:
+ if (value < -2 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ self->limiterEnableUser = value;
+ break;
+
+ case AAC_PCM_LIMITER_ATTACK_TIME:
+ if (value <= 0) { /* module function converts value to unsigned */
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ switch (pcmLimiter_SetAttack(hPcmTdl, value)) {
+ case TDLIMIT_OK:
+ break;
+ case TDLIMIT_INVALID_HANDLE:
+ return AAC_DEC_INVALID_HANDLE;
+ case TDLIMIT_INVALID_PARAMETER:
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ break;
+
+ case AAC_PCM_LIMITER_RELEAS_TIME:
+ if (value <= 0) { /* module function converts value to unsigned */
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ switch (pcmLimiter_SetRelease(hPcmTdl, value)) {
+ case TDLIMIT_OK:
+ break;
+ case TDLIMIT_INVALID_HANDLE:
+ return AAC_DEC_INVALID_HANDLE;
+ case TDLIMIT_INVALID_PARAMETER:
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ break;
+
+ case AAC_METADATA_PROFILE: {
+ DMX_PROFILE_TYPE dmxProfile;
+ INT mdExpiry = -1; /* in ms (-1: don't change) */
+
+ switch ((AAC_MD_PROFILE)value) {
+ case AAC_MD_PROFILE_MPEG_STANDARD:
+ dmxProfile = DMX_PRFL_STANDARD;
+ break;
+ case AAC_MD_PROFILE_MPEG_LEGACY:
+ dmxProfile = DMX_PRFL_MATRIX_MIX;
+ break;
+ case AAC_MD_PROFILE_MPEG_LEGACY_PRIO:
+ dmxProfile = DMX_PRFL_FORCE_MATRIX_MIX;
+ break;
+ case AAC_MD_PROFILE_ARIB_JAPAN:
+ dmxProfile = DMX_PRFL_ARIB_JAPAN;
+ mdExpiry = 550; /* ms */
+ break;
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ dmxErr = pcmDmx_SetParam(hPcmDmx, DMX_PROFILE_SETTING, (INT)dmxProfile);
+ if (dmxErr != PCMDMX_OK) {
+ goto bail;
+ }
+ if ((self != NULL) && (mdExpiry >= 0)) {
+ self->metadataExpiry = mdExpiry;
+ /* Determine the corresponding number of frames and configure all
+ * related modules. */
+ aacDecoder_setMetadataExpiry(self, mdExpiry);
+ }
+ } break;
+
+ case AAC_METADATA_EXPIRY_TIME:
+ if (value < 0) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (self != NULL) {
+ self->metadataExpiry = value;
+ /* Determine the corresponding number of frames and configure all
+ * related modules. */
+ aacDecoder_setMetadataExpiry(self, value);
+ }
+ break;
+
+ case AAC_PCM_OUTPUT_CHANNEL_MAPPING:
+ if (value < 0 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ /* CAUTION: The given value must be inverted to match the logic! */
+ FDK_chMapDescr_setPassThrough(&self->mapDescr, !value);
+ break;
+
+ case AAC_QMF_LOWPOWER:
+ if (value < -1 || value > 1) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ /**
+ * Set QMF mode (might be overriden)
+ * 0:HQ (complex)
+ * 1:LP (partially complex)
+ */
+ self->qmfModeUser = (QMF_MODE)value;
+ break;
+
+ case AAC_DRC_ATTENUATION_FACTOR:
+ /* DRC compression factor (where 0 is no and 127 is max compression) */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_CUT_SCALE, value);
+ break;
+
+ case AAC_DRC_BOOST_FACTOR:
+ /* DRC boost factor (where 0 is no and 127 is max boost) */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BOOST_SCALE, value);
+ break;
+
+ case AAC_DRC_REFERENCE_LEVEL:
+ if ((value >= 0) &&
+ ((value < 40) || (value > 127))) /* allowed range: -10 to -31.75 dB */
+ return AAC_DEC_SET_PARAM_FAIL;
+ /* DRC target reference level quantized in 0.25dB steps using values
+ [40..127]. Negative values switch off loudness normalisation. Negative
+ values also switch off MPEG-4 DRC, while MPEG-D DRC can be separately
+ switched on/off with AAC_UNIDRC_SET_EFFECT */
+ errorStatus = aacDecoder_drcSetParam(hDrcInfo, TARGET_REF_LEVEL, value);
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder,
+ DRC_DEC_LOUDNESS_NORMALIZATION_ON,
+ (FIXP_DBL)(value >= 0));
+ /* set target loudness also for MPEG-D DRC */
+ self->defaultTargetLoudness = (SCHAR)value;
+ break;
+
+ case AAC_DRC_HEAVY_COMPRESSION:
+ /* Don't need to overwrite cut/boost values */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, APPLY_HEAVY_COMPRESSION, value);
+ break;
+
+ case AAC_DRC_DEFAULT_PRESENTATION_MODE:
+ /* DRC default presentation mode */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, DEFAULT_PRESENTATION_MODE, value);
+ break;
+
+ case AAC_DRC_ENC_TARGET_LEVEL:
+ /* Encoder target level for light (i.e. not heavy) compression:
+ Target reference level assumed at encoder for deriving limiting gains
+ */
+ errorStatus =
+ aacDecoder_drcSetParam(hDrcInfo, ENCODER_TARGET_LEVEL, value);
+ break;
+
+ case AAC_UNIDRC_SET_EFFECT:
+ if ((value < -1) || (value > 6)) return AAC_DEC_SET_PARAM_FAIL;
+ uniDrcErr = FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_EFFECT_TYPE,
+ (FIXP_DBL)value);
+ break;
+ case AAC_TPDEC_CLEAR_BUFFER:
+ errTp = transportDec_SetParam(hTpDec, TPDEC_PARAM_RESET, 1);
+ self->streamInfo.numLostAccessUnits = 0;
+ self->streamInfo.numBadBytes = 0;
+ self->streamInfo.numTotalBytes = 0;
+ /* aacDecoder_SignalInterruption(self); */
+ break;
+ case AAC_CONCEAL_METHOD:
+ /* Changing the concealment method can introduce additional bitstream
+ delay. And that in turn affects sub libraries and modules which makes
+ the whole thing quite complex. So the complete changing routine is
+ packed into a helper function which keeps all modules and libs in a
+ consistent state even in the case an error occures. */
+ errorStatus = setConcealMethod(self, value);
+ if (errorStatus == AAC_DEC_OK) {
+ self->concealMethodUser = (CConcealmentMethod)value;
+ }
+ break;
+
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ } /* switch(param) */
+
+bail:
+
+ if (errorStatus == AAC_DEC_OK) {
+ /* Check error code returned by DMX module library: */
+ switch (dmxErr) {
+ case PCMDMX_OK:
+ break;
+ case PCMDMX_INVALID_HANDLE:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) {
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ if (errorStatus == AAC_DEC_OK) {
+ /* Check error code returned by MPEG-D DRC decoder library: */
+ switch (uniDrcErr) {
+ case 0:
+ break;
+ case -9998:
+ errorStatus = AAC_DEC_INVALID_HANDLE;
+ break;
+ default:
+ errorStatus = AAC_DEC_SET_PARAM_FAIL;
+ break;
+ }
+ }
+
+ return (errorStatus);
+}
+LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,
+ UINT nrOfLayers) {
+ AAC_DECODER_INSTANCE *aacDec = NULL;
+ HANDLE_TRANSPORTDEC pIn;
+ int err = 0;
+ int stereoConfigIndex = -1;
+
+ UINT nrOfLayers_min = fMin(nrOfLayers, (UINT)1);
+
+ /* Allocate transport layer struct. */
+ pIn = transportDec_Open(transportFmt, TP_FLAG_MPEG4, nrOfLayers_min);
+ if (pIn == NULL) {
+ return NULL;
+ }
+
+ transportDec_SetParam(pIn, TPDEC_PARAM_IGNORE_BUFFERFULLNESS, 1);
+
+ /* Allocate AAC decoder core struct. */
+ aacDec = CAacDecoder_Open(transportFmt);
+
+ if (aacDec == NULL) {
+ transportDec_Close(&pIn);
+ goto bail;
+ }
+ aacDec->hInput = pIn;
+
+ aacDec->nrOfLayers = nrOfLayers_min;
+
+ /* Setup channel mapping descriptor. */
+ FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0);
+
+ /* Register Config Update callback. */
+ transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback,
+ (void *)aacDec);
+
+ /* Register Free Memory callback. */
+ transportDec_RegisterFreeMemCallback(pIn, aacDecoder_FreeMemCallback,
+ (void *)aacDec);
+
+ /* Register config switch control callback. */
+ transportDec_RegisterCtrlCFGChangeCallback(
+ pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec);
+
+ FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN));
+ /* open SBR decoder */
+ if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) {
+ err = -1;
+ goto bail;
+ }
+ aacDec->qmfModeUser = NOT_DEFINED;
+ transportDec_RegisterSbrCallback(aacDec->hInput, aacDecoder_SbrCallback,
+ (void *)aacDec->hSbrDecoder);
+
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder,
+ stereoConfigIndex, &aacDec->qmfDomain)) {
+ err = -1;
+ goto bail;
+ }
+ /* Set MPEG Surround defaults */
+ aacDec->mpsEnableUser = 0;
+ aacDec->mpsEnableCurr = 0;
+ aacDec->mpsApplicable = 0;
+ aacDec->mpsOutputMode = (SCHAR)SACDEC_OUT_MODE_NORMAL;
+ transportDec_RegisterSscCallback(pIn, aacDecoder_SscCallback, (void *)aacDec);
+
+ {
+ if (FDK_drcDec_Open(&(aacDec->hUniDrcDecoder), DRC_DEC_ALL) != 0) {
+ err = -1;
+ goto bail;
+ }
+ }
+
+ transportDec_RegisterUniDrcConfigCallback(pIn, aacDecoder_UniDrcCallback,
+ (void *)aacDec,
+ aacDec->loudnessInfoSetPosition);
+ aacDec->defaultTargetLoudness = (SCHAR)96;
+
+ pcmDmx_Open(&aacDec->hPcmUtils);
+ if (aacDec->hPcmUtils == NULL) {
+ err = -1;
+ goto bail;
+ }
+
+ aacDec->hLimiter =
+ pcmLimiter_Create(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS,
+ (FIXP_DBL)MAXVAL_DBL, (8), 96000);
+ if (NULL == aacDec->hLimiter) {
+ err = -1;
+ goto bail;
+ }
+ aacDec->limiterEnableUser = (UCHAR)-1;
+ aacDec->limiterEnableCurr = 0;
+
+ /* Assure that all modules have same delay */
+ if (setConcealMethod(aacDec,
+ CConcealment_GetMethod(&aacDec->concealCommonData))) {
+ err = -1;
+ goto bail;
+ }
+
+bail:
+ if (err == -1) {
+ aacDecoder_Close(aacDec);
+ aacDec = NULL;
+ }
+ return aacDec;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self,
+ UCHAR *pBuffer[],
+ const UINT bufferSize[],
+ UINT *pBytesValid) {
+ TRANSPORTDEC_ERROR tpErr;
+ /* loop counter for layers; if not TT_MP4_RAWPACKETS used as index for only
+ available layer */
+ INT layer = 0;
+ INT nrOfLayers = self->nrOfLayers;
+
+ {
+ for (layer = 0; layer < nrOfLayers; layer++) {
+ {
+ tpErr = transportDec_FillData(self->hInput, pBuffer[layer],
+ bufferSize[layer], &pBytesValid[layer],
+ layer);
+ if (tpErr != TRANSPORTDEC_OK) {
+ return AAC_DEC_UNKNOWN; /* Must be an internal error */
+ }
+ }
+ }
+ }
+
+ return AAC_DEC_OK;
+}
+
+static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) {
+ CAacDecoder_SignalInterruption(self);
+
+ if (self->hSbrDecoder != NULL) {
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1);
+ }
+ if (self->mpsEnableUser) {
+ mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_BS_INTERRUPTION, 1);
+ }
+}
+
+static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi,
+ HANDLE_FDK_BITSTREAM hBs,
+ INT nBits,
+ AAC_DECODER_ERROR ErrorStatus) {
+ /* calculate bit difference (amount of bits moved forward) */
+ nBits = nBits - (INT)FDKgetValidBits(hBs);
+
+ /* Note: The amount of bits consumed might become negative when parsing a
+ bit stream with several sub frames, and we find out at the last sub frame
+ that the total frame length does not match the sum of sub frame length.
+ If this happens, the transport decoder might want to rewind to the supposed
+ ending of the transport frame, and this position might be before the last
+ access unit beginning. */
+
+ /* Calc bitrate. */
+ if (pSi->frameSize > 0) {
+ /* bitRate = nBits * sampleRate / frameSize */
+ int ratio_e = 0;
+ FIXP_DBL ratio_m = fDivNorm(pSi->sampleRate, pSi->frameSize, &ratio_e);
+ pSi->bitRate = (INT)fMultNorm(nBits, DFRACT_BITS - 1, ratio_m, ratio_e,
+ DFRACT_BITS - 1);
+ }
+
+ /* bit/byte counters */
+ {
+ INT nBytes;
+
+ nBytes = nBits >> 3;
+ pSi->numTotalBytes += nBytes;
+ if (IS_OUTPUT_VALID(ErrorStatus)) {
+ pSi->numTotalAccessUnits++;
+ }
+ if (IS_DECODE_ERROR(ErrorStatus)) {
+ pSi->numBadBytes += nBytes;
+ pSi->numBadAccessUnits++;
+ }
+ }
+}
+
+static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) {
+ INT n;
+
+ transportDec_GetMissingAccessUnitCount(&n, self->hInput);
+
+ return n;
+}
+
+LINKSPEC_CPP AAC_DECODER_ERROR
+aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData_extern,
+ const INT timeDataSize_extern, const UINT flags) {
+ AAC_DECODER_ERROR ErrorStatus;
+ INT layer;
+ INT nBits;
+ HANDLE_FDK_BITSTREAM hBs;
+ int fTpInterruption = 0; /* Transport originated interruption detection. */
+ int fTpConceal = 0; /* Transport originated concealment. */
+ INT_PCM *pTimeData = NULL;
+ INT timeDataSize = 0;
+ UINT accessUnit = 0;
+ UINT numAccessUnits = 1;
+ UINT numPrerollAU = 0;
+ int fEndAuNotAdjusted = 0; /* The end of the access unit was not adjusted */
+ int applyCrossfade = 1; /* flag indicates if flushing was possible */
+ FIXP_PCM *pTimeDataFixpPcm; /* Signal buffer for decoding process before PCM
+ processing */
+ INT timeDataFixpPcmSize;
+ PCM_DEC *pTimeDataPcmPost; /* Signal buffer for PCM post-processing */
+ INT timeDataPcmPostSize;
+
+ if (self == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ pTimeData = self->pcmOutputBuffer;
+ timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer);
+
+ if (flags & AACDEC_INTR) {
+ self->streamInfo.numLostAccessUnits = 0;
+ }
+ hBs = transportDec_GetBitstream(self->hInput, 0);
+
+ /* Get current bits position for bitrate calculation. */
+ nBits = FDKgetValidBits(hBs);
+
+ if (flags & AACDEC_CLRHIST) {
+ if (self->flags[0] & AC_USAC) {
+ /* 1) store AudioSpecificConfig always in AudioSpecificConfig_Parse() */
+ /* 2) free memory of dynamic allocated data */
+ CSAudioSpecificConfig asc;
+ transportDec_GetAsc(self->hInput, 0, &asc);
+ aacDecoder_FreeMemCallback(self, &asc);
+ self->streamInfo.numChannels = 0;
+ /* 3) restore AudioSpecificConfig */
+ transportDec_OutOfBandConfig(self->hInput, asc.config,
+ (asc.configBits + 7) >> 3, 0);
+ }
+ }
+
+ if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) ||
+ (self->flushStatus == AACDEC_RSV60_DASH_IPF_ATSC_FLUSH_ON) ||
+ (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND))) {
+ TRANSPORTDEC_ERROR err;
+
+ for (layer = 0; layer < self->nrOfLayers; layer++) {
+ err = transportDec_ReadAccessUnit(self->hInput, layer);
+ if (err != TRANSPORTDEC_OK) {
+ switch (err) {
+ case TRANSPORTDEC_NOT_ENOUGH_BITS:
+ ErrorStatus = AAC_DEC_NOT_ENOUGH_BITS;
+ goto bail;
+ case TRANSPORTDEC_SYNC_ERROR:
+ self->streamInfo.numLostAccessUnits =
+ aacDecoder_EstimateNumberOfLostFrames(self);
+ fTpInterruption = 1;
+ break;
+ case TRANSPORTDEC_NEED_TO_RESTART:
+ ErrorStatus = AAC_DEC_NEED_TO_RESTART;
+ goto bail;
+ case TRANSPORTDEC_CRC_ERROR:
+ fTpConceal = 1;
+ break;
+ case TRANSPORTDEC_UNSUPPORTED_FORMAT:
+ ErrorStatus = AAC_DEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ default:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ }
+ }
+ } else {
+ if (self->streamInfo.numLostAccessUnits > 0) {
+ self->streamInfo.numLostAccessUnits--;
+ }
+ }
+
+ self->frameOK = 1;
+
+ UINT prerollAUOffset[AACDEC_MAX_NUM_PREROLL_AU];
+ UINT prerollAULength[AACDEC_MAX_NUM_PREROLL_AU];
+ for (int i = 0; i < AACDEC_MAX_NUM_PREROLL_AU + 1; i++)
+ self->prerollAULength[i] = 0;
+
+ INT auStartAnchor;
+ HANDLE_FDK_BITSTREAM hBsAu;
+
+ /* Process preroll frames and current frame */
+ do {
+ if (!(flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) &&
+ (self->flushStatus != AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON) &&
+ (accessUnit == 0) &&
+ (self->hasAudioPreRoll ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_IDLE_IN_BAND)) &&
+ !fTpInterruption &&
+ !fTpConceal /* Bit stream pointer needs to be at the beginning of a
+ (valid) AU. */
+ ) {
+ ErrorStatus = CAacDecoder_PreRollExtensionPayloadParse(
+ self, &numPrerollAU, prerollAUOffset, prerollAULength);
+
+ if (ErrorStatus != AAC_DEC_OK) {
+ switch (ErrorStatus) {
+ case AAC_DEC_NOT_ENOUGH_BITS:
+ goto bail;
+ case AAC_DEC_PARSE_ERROR:
+ self->frameOK = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ numAccessUnits += numPrerollAU;
+ }
+
+ hBsAu = transportDec_GetBitstream(self->hInput, 0);
+ auStartAnchor = (INT)FDKgetValidBits(hBsAu);
+
+ self->accessUnit = accessUnit;
+ if (accessUnit < numPrerollAU) {
+ FDKpushFor(hBsAu, prerollAUOffset[accessUnit]);
+ }
+
+ /* Signal bit stream interruption to other modules if required. */
+ if (fTpInterruption || (flags & AACDEC_INTR)) {
+ aacDecoder_SignalInterruption(self);
+ if (!(flags & AACDEC_INTR)) {
+ ErrorStatus = AAC_DEC_TRANSPORT_SYNC_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Clearing core data will be done in CAacDecoder_DecodeFrame() below.
+ Tell other modules to clear states if required. */
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1);
+ mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_CLEAR_HISTORY, 1);
+ if (FDK_QmfDomain_ClearPersistentMemory(&self->qmfDomain) != 0) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ }
+ }
+
+ /* Empty bit buffer in case of flush request. */
+ if (flags & AACDEC_FLUSH && !(flags & AACDEC_CONCEAL)) {
+ if (!self->flushStatus) {
+ transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1);
+ self->streamInfo.numLostAccessUnits = 0;
+ self->streamInfo.numBadBytes = 0;
+ self->streamInfo.numTotalBytes = 0;
+ }
+ }
+ /* Reset the output delay field. The modules will add their figures one
+ * after another. */
+ self->streamInfo.outputDelay = 0;
+
+ if (self->limiterEnableUser == (UCHAR)-2) {
+ /* Enable limiter only for RSVD60. */
+ self->limiterEnableCurr = (self->flags[0] & AC_RSV603DA) ? 1 : 0;
+ } else if (self->limiterEnableUser == (UCHAR)-1) {
+ /* Enable limiter for all non-lowdelay AOT's. */
+ self->limiterEnableCurr = (self->flags[0] & (AC_LD | AC_ELD)) ? 0 : 1;
+ } else {
+ /* Use limiter configuration as requested. */
+ self->limiterEnableCurr = self->limiterEnableUser;
+ }
+ /* reset limiter gain on a per frame basis */
+ self->extGain[0] = FL2FXCONST_DBL(1.0f / (float)(1 << TDL_GAIN_SCALING));
+
+ pTimeDataFixpPcm = pTimeData;
+ timeDataFixpPcmSize = timeDataSize;
+
+ ErrorStatus = CAacDecoder_DecodeFrame(
+ self,
+ flags | (fTpConceal ? AACDEC_CONCEAL : 0) |
+ ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
+ : 0),
+ pTimeDataFixpPcm + 0, timeDataFixpPcmSize,
+ self->streamInfo.aacSamplesPerFrame + 0);
+
+ /* if flushing for USAC DASH IPF was not possible go on with decoding
+ * preroll */
+ if ((self->flags[0] & AC_USAC) &&
+ (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
+ !(flags & AACDEC_CONCEAL) && (ErrorStatus != AAC_DEC_OK)) {
+ applyCrossfade = 0;
+ } else /* USAC DASH IPF flushing possible begin */
+ {
+ if (!((flags & (AACDEC_CONCEAL | AACDEC_FLUSH)) || fTpConceal ||
+ self->flushStatus) &&
+ (!(IS_OUTPUT_VALID(ErrorStatus)) || !(accessUnit < numPrerollAU))) {
+ TRANSPORTDEC_ERROR tpErr;
+ tpErr = transportDec_EndAccessUnit(self->hInput);
+ if (tpErr != TRANSPORTDEC_OK) {
+ self->frameOK = 0;
+ }
+ } else { /* while preroll processing later possibly an error in the
+ renderer part occurrs */
+ if (IS_OUTPUT_VALID(ErrorStatus)) {
+ fEndAuNotAdjusted = 1;
+ }
+ }
+
+ /* If the current pTimeDataFixpPcm does not contain a valid signal, there
+ * nothing else we can do, so bail. */
+ if (!IS_OUTPUT_VALID(ErrorStatus)) {
+ goto bail;
+ }
+
+ {
+ self->streamInfo.sampleRate = self->streamInfo.aacSampleRate;
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+
+ self->streamInfo.numChannels = self->streamInfo.aacNumChannels;
+
+ {
+ FDK_Delay_Apply(&self->usacResidualDelay,
+ pTimeDataFixpPcm +
+ 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0,
+ self->streamInfo.frameSize, 0);
+ }
+
+ /* Setting of internal MPS state; may be reset in CAacDecoder_SyncQmfMode
+ if decoder is unable to decode with user defined qmfMode */
+ if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD))) {
+ self->mpsEnableCurr =
+ (self->mpsEnableUser &&
+ isSupportedMpsConfig(self->streamInfo.aot,
+ self->streamInfo.numChannels,
+ (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0));
+ }
+
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
+ self->mpsEnableCurr) {
+ /* if not done yet, allocate full MPEG Surround decoder instance */
+ if (mpegSurroundDecoder_IsFullMpegSurroundDecoderInstanceAvailable(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder) ==
+ SAC_INSTANCE_NOT_FULL_AVAILABLE) {
+ if (mpegSurroundDecoder_Open(
+ (CMpegSurroundDecoder **)&self->pMpegSurroundDecoder, -1,
+ &self->qmfDomain)) {
+ return AAC_DEC_OUT_OF_MEMORY;
+ }
+ }
+ }
+
+ CAacDecoder_SyncQmfMode(self);
+
+ if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig &&
+ self->mpsEnableCurr) {
+ SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder)
+ ? SAC_INTERFACE_QMF
+ : SAC_INTERFACE_TIME;
+ /* needs to be done before first SBR apply. */
+ mpegSurroundDecoder_ConfigureQmfDomain(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface,
+ (UINT)self->streamInfo.aacSampleRate, self->streamInfo.aot);
+ if (self->qmfDomain.globalConf.nBandsAnalysis_requested > 0) {
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested =
+ self->streamInfo.aacSamplesPerFrame /
+ self->qmfDomain.globalConf.nBandsAnalysis_requested;
+ } else {
+ self->qmfDomain.globalConf.nQmfTimeSlots_requested = 0;
+ }
+ }
+
+ self->qmfDomain.globalConf.TDinput = pTimeData;
+
+ switch (FDK_QmfDomain_Configure(&self->qmfDomain)) {
+ default:
+ case QMF_DOMAIN_INIT_ERROR:
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ case QMF_DOMAIN_OUT_OF_MEMORY:
+ ErrorStatus = AAC_DEC_OUT_OF_MEMORY;
+ goto bail;
+ case QMF_DOMAIN_OK:
+ break;
+ }
+
+ /* sbr decoder */
+
+ if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) ||
+ self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState >
+ ConcealState_FadeIn) {
+ self->frameOK = 0; /* if an error has occured do concealment in the SBR
+ decoder too */
+ }
+
+ if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+ int chIdx, numCoreChannel = self->streamInfo.numChannels;
+
+ /* set params */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
+ self->sbrParams.bsDelay);
+ sbrDecoder_SetParam(
+ self->hSbrDecoder, SBR_FLUSH_DATA,
+ (flags & AACDEC_FLUSH) |
+ ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH
+ : 0));
+
+ if (self->streamInfo.aot == AOT_ER_AAC_ELD) {
+ /* Configure QMF */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN,
+ (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0);
+ }
+
+ {
+ PCMDMX_ERROR dmxErr;
+ INT maxOutCh = 0;
+
+ dmxErr = pcmDmx_GetParam(self->hPcmUtils,
+ MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh);
+ if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) {
+ /* Disable PS processing if we have to create a mono output signal.
+ */
+ self->psPossible = 0;
+ }
+ }
+
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF,
+ (self->mpsEnableCurr) ? 2 : 0);
+
+ INT_PCM *input;
+ input = (INT_PCM *)self->workBufferCore2;
+ FDKmemcpy(input, pTimeData,
+ sizeof(INT_PCM) * (self->streamInfo.numChannels) *
+ (self->streamInfo.frameSize));
+
+ /* apply SBR processing */
+ sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData,
+ timeDataSize, &self->streamInfo.numChannels,
+ &self->streamInfo.sampleRate,
+ &self->mapDescr, self->chMapIndex,
+ self->frameOK, &self->psPossible);
+
+ if (sbrError == SBRDEC_OK) {
+ /* Update data in streaminfo structure. Assume that the SBR upsampling
+ factor is either 1, 2, 8/3 or 4. Maximum upsampling factor is 4
+ (CELP+SBR or USAC 4:1 SBR) */
+ self->flags[0] |= AC_SBR_PRESENT;
+ if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
+ if (self->streamInfo.aacSampleRate >> 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize =
+ self->streamInfo.aacSamplesPerFrame >> 2;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2;
+ } else if (self->streamInfo.aacSampleRate >> 1 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize =
+ self->streamInfo.aacSamplesPerFrame >> 1;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1;
+ } else if (self->streamInfo.aacSampleRate << 1 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 1;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1;
+ } else if (self->streamInfo.aacSampleRate << 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 2;
+ self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2;
+ } else if (self->streamInfo.frameSize == 768) {
+ self->streamInfo.frameSize =
+ (self->streamInfo.aacSamplesPerFrame << 3) / 3;
+ self->streamInfo.outputDelay =
+ (self->streamInfo.outputDelay << 3) / 3;
+ } else {
+ ErrorStatus = AAC_DEC_SET_PARAM_FAIL;
+ goto bail;
+ }
+ } else {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame;
+ }
+ self->streamInfo.outputDelay +=
+ sbrDecoder_GetDelay(self->hSbrDecoder);
+
+ if (self->psPossible) {
+ self->flags[0] |= AC_PS_PRESENT;
+ }
+ for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels;
+ chIdx += 1) {
+ self->channelType[chIdx] = ACT_FRONT;
+ self->channelIndices[chIdx] = chIdx;
+ }
+ }
+ if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ }
+
+ if (self->mpsEnableCurr) {
+ int err, sac_interface, nChannels, frameSize;
+
+ nChannels = self->streamInfo.numChannels;
+ frameSize = self->streamInfo.frameSize;
+ sac_interface = SAC_INTERFACE_TIME;
+
+ if (self->sbrEnabled && self->hSbrDecoder)
+ sac_interface = SAC_INTERFACE_QMF;
+ if (self->streamInfo.aot == AOT_USAC) {
+ if (self->flags[0] & AC_USAC_SCFGI3) {
+ sac_interface = SAC_INTERFACE_TIME;
+ }
+ }
+ err = mpegSurroundDecoder_SetParam(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ SACDEC_INTERFACE, sac_interface);
+
+ if (err == 0) {
+ err = mpegSurroundDecoder_Apply(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder,
+ (INT_PCM *)self->workBufferCore2, pTimeData, timeDataSize,
+ self->streamInfo.aacSamplesPerFrame, &nChannels, &frameSize,
+ self->streamInfo.sampleRate, self->streamInfo.aot,
+ self->channelType, self->channelIndices, &self->mapDescr);
+ }
+
+ if (err == MPS_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ if (err == 0) {
+ /* Update output parameter */
+ self->streamInfo.numChannels = nChannels;
+ self->streamInfo.frameSize = frameSize;
+ self->streamInfo.outputDelay += mpegSurroundDecoder_GetDelay(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
+ /* Save current parameter for possible concealment of next frame */
+ self->mpsOutChannelsLast = nChannels;
+ self->mpsFrameSizeLast = frameSize;
+ } else if ((self->mpsOutChannelsLast > 0) &&
+ (self->mpsFrameSizeLast > 0)) {
+ /* Restore parameters of last frame ... */
+ self->streamInfo.numChannels = self->mpsOutChannelsLast;
+ self->streamInfo.frameSize = self->mpsFrameSizeLast;
+ /* ... and clear output buffer so that potentially corrupted data does
+ * not reach the framework. */
+ FDKmemclear(pTimeData, self->mpsOutChannelsLast *
+ self->mpsFrameSizeLast * sizeof(INT_PCM));
+ /* Additionally proclaim that this frame had errors during decoding.
+ */
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ } else {
+ ErrorStatus = AAC_DEC_UNKNOWN; /* no output */
+ }
+ }
+
+ /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */
+
+ if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) {
+ SBR_ERROR sbrError = SBRDEC_OK;
+
+ /* set params */
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY,
+ self->sbrParams.bsDelay);
+
+ sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1);
+
+ /* apply SBR processing */
+ sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData,
+ timeDataSize, &self->streamInfo.numChannels,
+ &self->streamInfo.sampleRate,
+ &self->mapDescr, self->chMapIndex,
+ self->frameOK, &self->psPossible);
+
+ if (sbrError == SBRDEC_OK) {
+ /* Update data in streaminfo structure. Assume that the SBR upsampling
+ * factor is either 1,2 or 4 */
+ self->flags[0] |= AC_SBR_PRESENT;
+ if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) {
+ if (self->streamInfo.frameSize == 768) {
+ self->streamInfo.frameSize =
+ (self->streamInfo.aacSamplesPerFrame * 8) / 3;
+ } else if (self->streamInfo.aacSampleRate << 2 ==
+ self->streamInfo.sampleRate) {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 2;
+ } else {
+ self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame
+ << 1;
+ }
+ }
+
+ self->flags[0] &= ~AC_PS_PRESENT;
+ }
+ if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ }
+
+ /* Use dedicated memory for PCM postprocessing */
+ pTimeDataPcmPost = self->pTimeData2;
+ timeDataPcmPostSize = self->timeData2Size;
+
+ {
+ const int size =
+ self->streamInfo.frameSize * self->streamInfo.numChannels;
+ FDK_ASSERT(timeDataPcmPostSize >= size);
+ for (int i = 0; i < size; i++) {
+ pTimeDataPcmPost[i] =
+ (PCM_DEC)FX_PCM2PCM_DEC(pTimeData[i]) >> PCM_OUT_HEADROOM;
+ }
+ }
+
+ {
+ if ((FDK_drcDec_GetParam(self->hUniDrcDecoder, DRC_DEC_IS_ACTIVE)) &&
+ !(self->flags[0] & AC_RSV603DA)) {
+ /* Apply DRC gains*/
+ int ch, drcDelay = 0;
+ int needsDeinterleaving = 0;
+ FIXP_DBL *drcWorkBuffer = NULL;
+ FIXP_DBL channelGain[(8)];
+ int reverseInChannelMap[(8)];
+ int reverseOutChannelMap[(8)];
+ int numDrcOutChannels = FDK_drcDec_GetParam(
+ self->hUniDrcDecoder, DRC_DEC_TARGET_CHANNEL_COUNT_SELECTED);
+ FDKmemclear(channelGain, sizeof(channelGain));
+ for (ch = 0; ch < (8); ch++) {
+ reverseInChannelMap[ch] = ch;
+ reverseOutChannelMap[ch] = ch;
+ }
+
+ /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF
+ domain signal before the QMF synthesis. Therefore the DRC gains
+ need to be delayed by the QMF synthesis delay. */
+ if (self->sbrEnabled) drcDelay = 257;
+ if (self->mpsEnableCurr) drcDelay = 257;
+ /* Take into account concealment delay */
+ drcDelay += CConcealment_GetDelay(&self->concealCommonData) *
+ self->streamInfo.frameSize;
+
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ UCHAR mapValue = FDK_chMapDescr_getMapValue(
+ &self->mapDescr, (UCHAR)ch, self->chMapIndex);
+ if (mapValue < (8)) reverseInChannelMap[mapValue] = ch;
+ }
+ for (ch = 0; ch < (int)numDrcOutChannels; ch++) {
+ UCHAR mapValue = FDK_chMapDescr_getMapValue(
+ &self->mapDescr, (UCHAR)ch, numDrcOutChannels);
+ if (mapValue < (8)) reverseOutChannelMap[mapValue] = ch;
+ }
+
+ /* The output of SBR and MPS is interleaved. Deinterleaving may be
+ * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved
+ * audio only. */
+ if ((self->streamInfo.numChannels > 1) &&
+ (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) {
+ /* interleaving/deinterleaving is performed on upper part of
+ * pTimeDataPcmPost. Check if this buffer is large enough. */
+ if (timeDataPcmPostSize <
+ (INT)(2 * self->streamInfo.numChannels *
+ self->streamInfo.frameSize * sizeof(PCM_DEC))) {
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ goto bail;
+ }
+ needsDeinterleaving = 1;
+ drcWorkBuffer =
+ (FIXP_DBL *)pTimeDataPcmPost +
+ self->streamInfo.numChannels * self->streamInfo.frameSize;
+ FDK_deinterleave(
+ pTimeDataPcmPost, drcWorkBuffer, self->streamInfo.numChannels,
+ self->streamInfo.frameSize, self->streamInfo.frameSize);
+ } else {
+ drcWorkBuffer = (FIXP_DBL *)pTimeDataPcmPost;
+ }
+
+ /* prepare Loudness Normalisation gain */
+ FDK_drcDec_SetParam(self->hUniDrcDecoder, DRC_DEC_TARGET_LOUDNESS,
+ (INT)-self->defaultTargetLoudness *
+ FL2FXCONST_DBL(1.0f / (float)(1 << 9)));
+ FDK_drcDec_SetChannelGains(self->hUniDrcDecoder,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, channelGain,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ FDK_drcDec_Preprocess(self->hUniDrcDecoder);
+
+ /* apply DRC1 gain sequence */
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay, DRC_DEC_DRC1,
+ ch, reverseInChannelMap[ch] - ch, 1,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ }
+ /* apply downmix */
+ FDK_drcDec_ApplyDownmix(
+ self->hUniDrcDecoder, reverseInChannelMap, reverseOutChannelMap,
+ drcWorkBuffer,
+ &self->streamInfo.numChannels); /* self->streamInfo.numChannels
+ may change here */
+ /* apply DRC2/3 gain sequence */
+ for (ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ FDK_drcDec_ProcessTime(self->hUniDrcDecoder, drcDelay,
+ DRC_DEC_DRC2_DRC3, ch,
+ reverseOutChannelMap[ch] - ch, 1,
+ drcWorkBuffer, self->streamInfo.frameSize);
+ }
+
+ if (needsDeinterleaving) {
+ FDK_interleave(
+ drcWorkBuffer, pTimeDataPcmPost, self->streamInfo.numChannels,
+ self->streamInfo.frameSize, self->streamInfo.frameSize);
+ }
+ }
+ }
+
+ if (self->streamInfo.extAot != AOT_AAC_SLS) {
+ INT pcmLimiterScale = 0;
+ PCMDMX_ERROR dmxErr = PCMDMX_OK;
+ if (flags & (AACDEC_INTR)) {
+ /* delete data from the past (e.g. mixdown coeficients) */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+ }
+ if (flags & (AACDEC_CLRHIST)) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* delete data from the past (e.g. mixdown coeficients) */
+ pcmDmx_Reset(self->hPcmUtils, PCMDMX_RESET_BS_DATA);
+ }
+ }
+
+ INT interleaved = 0;
+ interleaved |= (self->sbrEnabled) ? 1 : 0;
+ interleaved |= (self->mpsEnableCurr) ? 1 : 0;
+
+ /* do PCM post processing */
+ dmxErr = pcmDmx_ApplyFrame(
+ self->hPcmUtils, pTimeDataPcmPost, timeDataFixpPcmSize,
+ self->streamInfo.frameSize, &self->streamInfo.numChannels,
+ interleaved, self->channelType, self->channelIndices,
+ &self->mapDescr,
+ (self->limiterEnableCurr) ? &pcmLimiterScale : NULL);
+ if (dmxErr == PCMDMX_OUTPUT_BUFFER_TOO_SMALL) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ goto bail;
+ }
+ if ((ErrorStatus == AAC_DEC_OK) && (dmxErr == PCMDMX_INVALID_MODE)) {
+ /* Announce the framework that the current combination of channel
+ * configuration and downmix settings are not know to produce a
+ * predictable behavior and thus maybe produce strange output. */
+ ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ if (flags & AACDEC_CLRHIST) {
+ if (!(self->flags[0] & AC_USAC)) {
+ /* Delete the delayed signal. */
+ pcmLimiter_Reset(self->hLimiter);
+ }
+ }
+
+ if (self->limiterEnableCurr) {
+ /* use workBufferCore2 buffer for interleaving */
+ PCM_LIM *pInterleaveBuffer;
+ int blockLength = self->streamInfo.frameSize;
+
+ /* Set actual signal parameters */
+ pcmLimiter_SetNChannels(self->hLimiter, self->streamInfo.numChannels);
+ pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate);
+ pcmLimiterScale += PCM_OUT_HEADROOM;
+
+ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
+ (self->mpsEnableCurr)) {
+ pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost;
+ } else {
+ pInterleaveBuffer = (PCM_LIM *)pTimeData;
+ /* applyLimiter requests for interleaved data */
+ /* Interleave ouput buffer */
+ FDK_interleave(pTimeDataPcmPost, pInterleaveBuffer,
+ self->streamInfo.numChannels, blockLength,
+ self->streamInfo.frameSize);
+ }
+
+ pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData,
+ self->extGain, &pcmLimiterScale, 1,
+ self->extGainDelay, self->streamInfo.frameSize);
+
+ {
+ /* Announce the additional limiter output delay */
+ self->streamInfo.outputDelay += pcmLimiter_GetDelay(self->hLimiter);
+ }
+ } else {
+ /* If numChannels = 1 we do not need interleaving. The same applies if
+ SBR or MPS are used, since their output is interleaved already
+ (resampled or not) */
+ if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) ||
+ (self->mpsEnableCurr)) {
+ scaleValuesSaturate(
+ pTimeData, pTimeDataPcmPost,
+ self->streamInfo.frameSize * self->streamInfo.numChannels,
+ PCM_OUT_HEADROOM);
+
+ } else {
+ scaleValuesSaturate(
+ (INT_PCM *)self->workBufferCore2, pTimeDataPcmPost,
+ self->streamInfo.frameSize * self->streamInfo.numChannels,
+ PCM_OUT_HEADROOM);
+ /* Interleave ouput buffer */
+ FDK_interleave((INT_PCM *)self->workBufferCore2, pTimeData,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize,
+ self->streamInfo.frameSize);
+ }
+ }
+ } /* if (self->streamInfo.extAot != AOT_AAC_SLS)*/
+
+ if (self->flags[0] & AC_USAC) {
+ if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
+ !(flags & AACDEC_CONCEAL)) {
+ CAacDecoder_PrepareCrossFade(pTimeData, self->pTimeDataFlush,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, 1);
+ }
+
+ /* prepare crossfade buffer for fade in */
+ if (!applyCrossfade && self->applyCrossfade &&
+ !(flags & AACDEC_CONCEAL)) {
+ for (int ch = 0; ch < self->streamInfo.numChannels; ch++) {
+ for (int i = 0; i < TIME_DATA_FLUSH_SIZE; i++) {
+ self->pTimeDataFlush[ch][i] = 0;
+ }
+ }
+ applyCrossfade = 1;
+ }
+
+ if (applyCrossfade && self->applyCrossfade &&
+ !(accessUnit < numPrerollAU) &&
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ CAacDecoder_ApplyCrossFade(pTimeData, self->pTimeDataFlush,
+ self->streamInfo.numChannels,
+ self->streamInfo.frameSize, 1);
+ self->applyCrossfade = 0;
+ }
+ }
+
+ /* Signal interruption to take effect in next frame. */
+ if ((flags & AACDEC_FLUSH || self->flushStatus) &&
+ !(flags & AACDEC_CONCEAL)) {
+ aacDecoder_SignalInterruption(self);
+ }
+
+ /* Update externally visible copy of flags */
+ self->streamInfo.flags = self->flags[0];
+
+ } /* USAC DASH IPF flushing possible end */
+ if (accessUnit < numPrerollAU) {
+ FDKpushBack(hBsAu, auStartAnchor - (INT)FDKgetValidBits(hBsAu));
+ } else {
+ if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) ||
+ (self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON_IN_BAND) ||
+ (self->buildUpStatus == AACDEC_USAC_BUILD_UP_ON)) {
+ self->buildUpCnt--;
+
+ if (self->buildUpCnt < 0) {
+ self->buildUpStatus = 0;
+ }
+ }
+
+ if (self->flags[0] & AC_USAC) {
+ if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON &&
+ !(flags & AACDEC_CONCEAL)) {
+ self->streamInfo.frameSize = 0;
+ }
+ }
+ }
+
+ if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) {
+ accessUnit++;
+ }
+ } while ((accessUnit < numAccessUnits) ||
+ ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) &&
+ !(flags & AACDEC_CONCEAL)));
+
+bail:
+
+ /* error in renderer part occurred, ErrorStatus was set to invalid output */
+ if (fEndAuNotAdjusted && !IS_OUTPUT_VALID(ErrorStatus) &&
+ (accessUnit < numPrerollAU)) {
+ transportDec_EndAccessUnit(self->hInput);
+ }
+
+ /* Update Statistics */
+ aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits,
+ ErrorStatus);
+ if (((self->streamInfo.numChannels <= 0) ||
+ (self->streamInfo.frameSize <= 0) ||
+ (self->streamInfo.sampleRate <= 0)) &&
+ IS_OUTPUT_VALID(ErrorStatus)) {
+ /* Ensure consistency of IS_OUTPUT_VALID() macro. */
+ ErrorStatus = AAC_DEC_UNKNOWN;
+ }
+
+ /* Check whether external output buffer is large enough. */
+ if (timeDataSize_extern <
+ self->streamInfo.numChannels * self->streamInfo.frameSize) {
+ ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL;
+ }
+
+ /* Update external output buffer. */
+ if (IS_OUTPUT_VALID(ErrorStatus)) {
+ FDKmemcpy(pTimeData_extern, pTimeData,
+ self->streamInfo.numChannels * self->streamInfo.frameSize *
+ sizeof(*pTimeData));
+ } else {
+ FDKmemclear(pTimeData_extern,
+ timeDataSize_extern * sizeof(*pTimeData_extern));
+ }
+
+ return ErrorStatus;
+}
+
+LINKSPEC_CPP void aacDecoder_Close(HANDLE_AACDECODER self) {
+ if (self == NULL) return;
+
+ if (self->hLimiter != NULL) {
+ pcmLimiter_Destroy(self->hLimiter);
+ }
+
+ if (self->hPcmUtils != NULL) {
+ pcmDmx_Close(&self->hPcmUtils);
+ }
+
+ FDK_drcDec_Close(&self->hUniDrcDecoder);
+
+ if (self->pMpegSurroundDecoder != NULL) {
+ mpegSurroundDecoder_Close(
+ (CMpegSurroundDecoder *)self->pMpegSurroundDecoder);
+ }
+
+ if (self->hSbrDecoder != NULL) {
+ sbrDecoder_Close(&self->hSbrDecoder);
+ }
+
+ if (self->hInput != NULL) {
+ transportDec_Close(&self->hInput);
+ }
+
+ CAacDecoder_Close(self);
+}
+
+LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) {
+ return CAacDecoder_GetStreamInfo(self);
+}
+
+LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) {
+ int i;
+
+ if (info == NULL) {
+ return -1;
+ }
+
+ sbrDecoder_GetLibInfo(info);
+ mpegSurroundDecoder_GetLibInfo(info);
+ transportDec_GetLibInfo(info);
+ FDK_toolsGetLibInfo(info);
+ pcmDmx_GetLibInfo(info);
+ pcmLimiter_GetLibInfo(info);
+ FDK_drcDec_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 -1;
+ }
+ info += i;
+
+ info->module_id = FDK_AACDEC;
+ /* build own library info */
+ info->version =
+ LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2);
+ LIB_VERSION_STRING(info);
+ info->build_date = AACDECODER_LIB_BUILD_DATE;
+ info->build_time = AACDECODER_LIB_BUILD_TIME;
+ info->title = AACDECODER_LIB_TITLE;
+
+ /* Set flags */
+ info->flags = 0 | CAPF_AAC_LC | CAPF_ER_AAC_LC | CAPF_ER_AAC_SCAL |
+ CAPF_AAC_VCB11 | CAPF_AAC_HCR | CAPF_AAC_RVLC | CAPF_ER_AAC_LD |
+ CAPF_ER_AAC_ELD | CAPF_AAC_CONCEALMENT | CAPF_AAC_DRC |
+ CAPF_AAC_MPEG4 | CAPF_AAC_DRM_BSFORMAT | CAPF_AAC_1024 |
+ CAPF_AAC_960 | CAPF_AAC_512 | CAPF_AAC_480 |
+ CAPF_AAC_ELD_DOWNSCALE
+
+ | CAPF_AAC_USAC | CAPF_ER_AAC_ELDV2 | CAPF_AAC_UNIDRC;
+ /* End of flags */
+
+ return 0;
+}
diff --git a/fdk-aac/libAACdec/src/arm/block_arm.cpp b/fdk-aac/libAACdec/src/arm/block_arm.cpp
new file mode 100644
index 0000000..3c1b4ba
--- /dev/null
+++ b/fdk-aac/libAACdec/src/arm/block_arm.cpp
@@ -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 decoder library ******************************
+
+ Author(s): Arthur Tritthart
+
+ Description: (ARM optimised) Scaling of spectral data
+
+*******************************************************************************/
+
+#define FUNCTION_CBlock_ScaleSpectralData_func1
+
+/* Note: This loop is only separated for ARM in order to save cycles
+ by loop unrolling. The ARM core provides by default a 5-cycle
+ loop overhead per sample, that goes down to 1-cycle per sample
+ with an optimal 4x-loop construct (do - 4x - while).
+*/
+static inline void CBlock_ScaleSpectralData_func1(
+ FIXP_DBL *pSpectrum, int maxSfbs, const SHORT *RESTRICT BandOffsets,
+ int SpecScale_window, const SHORT *RESTRICT pSfbScale, int window) {
+ int band_offset = 0;
+ for (int band = 0; band < maxSfbs; band++) {
+ int runs = band_offset;
+ band_offset = BandOffsets[band + 1];
+ runs = band_offset - runs; /* is always a multiple of 4 */
+ FDK_ASSERT((runs & 3) == 0);
+ int scale =
+ fMin(DFRACT_BITS - 1, SpecScale_window - pSfbScale[window * 16 + band]);
+
+ if (scale) {
+ do {
+ FIXP_DBL tmp0, tmp1, tmp2, tmp3;
+ tmp0 = pSpectrum[0];
+ tmp1 = pSpectrum[1];
+ tmp2 = pSpectrum[2];
+ tmp3 = pSpectrum[3];
+ tmp0 >>= scale;
+ tmp1 >>= scale;
+ tmp2 >>= scale;
+ tmp3 >>= scale;
+ *pSpectrum++ = tmp0;
+ *pSpectrum++ = tmp1;
+ *pSpectrum++ = tmp2;
+ *pSpectrum++ = tmp3;
+ } while ((runs = runs - 4) != 0);
+ } else {
+ pSpectrum += runs;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/block.cpp b/fdk-aac/libAACdec/src/block.cpp
new file mode 100644
index 0000000..b3d09a6
--- /dev/null
+++ b/fdk-aac/libAACdec/src/block.cpp
@@ -0,0 +1,1260 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: long/short-block decoding
+
+*******************************************************************************/
+
+#include "block.h"
+
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "scale.h"
+#include "FDK_tools_rom.h"
+
+#include "usacdec_fac.h"
+#include "usacdec_lpd.h"
+#include "usacdec_lpc.h"
+#include "FDK_trigFcts.h"
+
+#include "ac_arith_coder.h"
+
+#include "aacdec_hcr.h"
+#include "rvlc.h"
+
+#if defined(__arm__)
+#include "arm/block_arm.cpp"
+#endif
+
+/*!
+ \brief Read escape sequence of codeword
+
+ The function reads the escape sequence from the bitstream,
+ if the absolute value of the quantized coefficient has the
+ value 16.
+ A limitation is implemented to maximal 21 bits according to
+ ISO/IEC 14496-3:2009(E) 4.6.3.3.
+ This limits the escape prefix to a maximum of eight 1's.
+ If more than eight 1's are read, MAX_QUANTIZED_VALUE + 1 is
+ returned, independent of the sign of parameter q.
+
+ \return quantized coefficient
+*/
+LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const LONG q) /*!< quantized coefficient */
+{
+ if (fAbs(q) != 16) return (q);
+
+ LONG i, off;
+ for (i = 4; i < 13; i++) {
+ if (FDKreadBit(bs) == 0) break;
+ }
+
+ if (i == 13) return (MAX_QUANTIZED_VALUE + 1);
+
+ off = FDKreadBits(bs, i);
+ i = off + (1 << i);
+
+ if (q < 0) i = -i;
+
+ return i;
+}
+
+AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
+ UINT flags) {
+ int temp;
+ int band;
+ int group;
+ int position = 0; /* accu for intensity delta coding */
+ int factor = pAacDecoderChannelInfo->pDynData->RawDataInfo
+ .GlobalGain; /* accu for scale factor delta coding */
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ group++) {
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ switch (pCodeBook[band]) {
+ case ZERO_HCB: /* zero book */
+ pScaleFactor[band] = 0;
+ break;
+
+ default: /* decode scale factor */
+ if (!((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) && band == 0 &&
+ group == 0)) {
+ temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ factor += temp - 60; /* MIDFAC 1.5 dB */
+ }
+ pScaleFactor[band] = factor - 100;
+ break;
+
+ case INTENSITY_HCB: /* intensity steering */
+ case INTENSITY_HCB2:
+ temp = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ position += temp - 60;
+ pScaleFactor[band] = position - 100;
+ break;
+
+ case NOISE_HCB: /* PNS */
+ if (flags & (AC_MPEGD_RES | AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ CPns_Read(&pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb,
+ pAacDecoderChannelInfo->pDynData->aScaleFactor,
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain,
+ band, group);
+ break;
+ }
+ }
+ pCodeBook += 16;
+ pScaleFactor += 16;
+ }
+
+ return AAC_DEC_OK;
+}
+
+void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR maxSfbs,
+ SamplingRateInfo *pSamplingRateInfo) {
+ int band;
+ int window;
+ const SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT *RESTRICT pSpecScale = pAacDecoderChannelInfo->specScale;
+ int groupwin, group;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ SPECTRAL_PTR RESTRICT pSpectralCoefficient =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+
+ FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
+
+ for (window = 0, group = 0;
+ group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
+ for (groupwin = 0; groupwin < GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ groupwin++, window++) {
+ int SpecScale_window = pSpecScale[window];
+ FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength);
+
+ /* find scaling for current window */
+ for (band = 0; band < maxSfbs; band++) {
+ SpecScale_window =
+ fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]);
+ }
+
+ if (pAacDecoderChannelInfo->pDynData->TnsData.Active &&
+ pAacDecoderChannelInfo->pDynData->TnsData.NumberOfFilters[window] >
+ 0) {
+ int filter_index, SpecScale_window_tns;
+ int tns_start, tns_stop;
+
+ /* Find max scale of TNS bands */
+ SpecScale_window_tns = 0;
+ tns_start = GetMaximumTnsBands(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo->samplingRateIndex);
+ tns_stop = 0;
+ for (filter_index = 0;
+ filter_index < (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .NumberOfFilters[window];
+ filter_index++) {
+ for (band = pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StartBand;
+ band < pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StopBand;
+ band++) {
+ SpecScale_window_tns =
+ fMax(SpecScale_window_tns, (int)pSfbScale[window * 16 + band]);
+ }
+ /* Find TNS line boundaries for all TNS filters */
+ tns_start =
+ fMin(tns_start, (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StartBand);
+ tns_stop =
+ fMax(tns_stop, (int)pAacDecoderChannelInfo->pDynData->TnsData
+ .Filter[window][filter_index]
+ .StopBand);
+ }
+ SpecScale_window_tns = SpecScale_window_tns +
+ pAacDecoderChannelInfo->pDynData->TnsData.GainLd;
+ FDK_ASSERT(tns_stop >= tns_start);
+ /* Consider existing headroom of all MDCT lines inside the TNS bands. */
+ SpecScale_window_tns -=
+ getScalefactor(pSpectrum + BandOffsets[tns_start],
+ BandOffsets[tns_stop] - BandOffsets[tns_start]);
+ if (SpecScale_window <= 17) {
+ SpecScale_window_tns++;
+ }
+ /* Add enough mantissa head room such that the spectrum is still
+ representable after applying TNS. */
+ SpecScale_window = fMax(SpecScale_window, SpecScale_window_tns);
+ }
+
+ /* store scaling of current window */
+ pSpecScale[window] = SpecScale_window;
+
+#ifdef FUNCTION_CBlock_ScaleSpectralData_func1
+
+ CBlock_ScaleSpectralData_func1(pSpectrum, maxSfbs, BandOffsets,
+ SpecScale_window, pSfbScale, window);
+
+#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ for (band = 0; band < maxSfbs; band++) {
+ int scale = fMin(DFRACT_BITS - 1,
+ SpecScale_window - pSfbScale[window * 16 + band]);
+ if (scale) {
+ FDK_ASSERT(scale > 0);
+
+ /* following relation can be used for optimizations:
+ * (BandOffsets[i]%4) == 0 for all i */
+ int max_index = BandOffsets[band + 1];
+ DWORD_ALIGNED(pSpectrum);
+ for (int index = BandOffsets[band]; index < max_index; index++) {
+ pSpectrum[index] >>= scale;
+ }
+ }
+ }
+#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */
+ }
+ }
+}
+
+AAC_DECODER_ERROR CBlock_ReadSectionData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
+ int top, band;
+ int sect_len, sect_len_incr;
+ int group;
+ UCHAR sect_cb;
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ /* HCR input (long) */
+ SHORT *pNumLinesInSec =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
+ int numLinesInSecIdx = 0;
+ UCHAR *pHcrCodeBook =
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
+ const SHORT *BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection = 0;
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16));
+
+ const int nbits =
+ (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3;
+
+ int sect_esc_val = (1 << nbits) - 1;
+
+ UCHAR ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ for (group = 0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ group++) {
+ for (band = 0; band < ScaleFactorBandsTransmitted;) {
+ sect_len = 0;
+ if (flags & AC_ER_VCB11) {
+ sect_cb = (UCHAR)FDKreadBits(bs, 5);
+ } else
+ sect_cb = (UCHAR)FDKreadBits(bs, 4);
+
+ if (((flags & AC_ER_VCB11) == 0) || (sect_cb < 11) ||
+ ((sect_cb > 11) && (sect_cb < 16))) {
+ sect_len_incr = FDKreadBits(bs, nbits);
+ while (sect_len_incr == sect_esc_val) {
+ sect_len += sect_esc_val;
+ sect_len_incr = FDKreadBits(bs, nbits);
+ }
+ } else {
+ sect_len_incr = 1;
+ }
+
+ sect_len += sect_len_incr;
+
+ top = band + sect_len;
+
+ if (flags & AC_ER_HCR) {
+ /* HCR input (long) -- collecting sideinfo (for HCR-_long_ only) */
+ if (numLinesInSecIdx >= MAX_SFB_HCR) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ if (top > (int)GetNumberOfScaleFactorBands(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo)) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+ pNumLinesInSec[numLinesInSecIdx] = BandOffsets[top] - BandOffsets[band];
+ numLinesInSecIdx++;
+ if (sect_cb == BOOKSCL) {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ } else {
+ *pHcrCodeBook++ = sect_cb;
+ }
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection++;
+ }
+
+ /* Check spectral line limits */
+ if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) {
+ if (top > 64) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ } else { /* short block */
+ if (top + group * 16 > (8 * 16)) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ }
+
+ /* Check if decoded codebook index is feasible */
+ if ((sect_cb == BOOKSCL) ||
+ ((sect_cb == INTENSITY_HCB || sect_cb == INTENSITY_HCB2) &&
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.CommonWindow == 0)) {
+ return AAC_DEC_INVALID_CODE_BOOK;
+ }
+
+ /* Store codebook index */
+ for (; band < top; band++) {
+ pCodeBook[group * 16 + band] = sect_cb;
+ }
+ }
+ }
+
+ return ErrorStatus;
+}
+
+/* mso: provides a faster way to i-quantize a whole band in one go */
+
+/**
+ * \brief inverse quantize one sfb. Each value of the sfb is processed according
+ * to the formula: spectrum[i] = Sign(spectrum[i]) * Matissa(spectrum[i])^(4/3)
+ * * 2^(lsb/4).
+ * \param spectrum pointer to first line of the sfb to be inverse quantized.
+ * \param noLines number of lines belonging to the sfb.
+ * \param lsb last 2 bits of the scale factor of the sfb.
+ * \param scale max allowed shift scale for the sfb.
+ */
+static inline void InverseQuantizeBand(
+ FIXP_DBL *RESTRICT spectrum, const FIXP_DBL *RESTRICT InverseQuantTabler,
+ const FIXP_DBL *RESTRICT MantissaTabler,
+ const SCHAR *RESTRICT ExponentTabler, INT noLines, INT scale) {
+ scale = scale + 1; /* +1 to compensate fMultDiv2 shift-right in loop */
+
+ FIXP_DBL *RESTRICT ptr = spectrum;
+ FIXP_DBL signedValue;
+
+ for (INT i = noLines; i--;) {
+ if ((signedValue = *ptr++) != FL2FXCONST_DBL(0)) {
+ FIXP_DBL value = fAbs(signedValue);
+ UINT freeBits = CntLeadingZeros(value);
+ UINT exponent = 32 - freeBits;
+
+ UINT x = (UINT)(LONG)value << (INT)freeBits;
+ x <<= 1; /* shift out sign bit to avoid masking later on */
+ UINT tableIndex = x >> 24;
+ x = (x >> 20) & 0x0F;
+
+ UINT r0 = (UINT)(LONG)InverseQuantTabler[tableIndex + 0];
+ UINT r1 = (UINT)(LONG)InverseQuantTabler[tableIndex + 1];
+ UINT temp = (r1 - r0) * x + (r0 << 4);
+
+ value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]);
+
+ /* + 1 compensates fMultDiv2() */
+ scaleValueInPlace(&value, scale + ExponentTabler[exponent]);
+
+ signedValue = (signedValue < (FIXP_DBL)0) ? -value : value;
+ ptr[-1] = signedValue;
+ }
+ }
+}
+
+static inline FIXP_DBL maxabs_D(const FIXP_DBL *pSpectralCoefficient,
+ const int noLines) {
+ /* Find max spectral line value of the current sfb */
+ FIXP_DBL locMax = (FIXP_DBL)0;
+ int i;
+
+ DWORD_ALIGNED(pSpectralCoefficient);
+
+ for (i = noLines; i-- > 0;) {
+ /* Expensive memory access */
+ locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax);
+ }
+
+ return locMax;
+}
+
+AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
+ UCHAR active_band_search) {
+ int window, group, groupwin, band;
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ SHORT *RESTRICT pSfbScale = pAacDecoderChannelInfo->pDynData->aSfbScale;
+ SHORT *RESTRICT pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ const SHORT total_bands =
+ GetScaleFactorBandsTotal(&pAacDecoderChannelInfo->icsInfo);
+
+ FDKmemclear(pAacDecoderChannelInfo->pDynData->aSfbScale,
+ (8 * 16) * sizeof(SHORT));
+
+ for (window = 0, group = 0;
+ group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) {
+ for (groupwin = 0; groupwin < GetWindowGroupLength(
+ &pAacDecoderChannelInfo->icsInfo, group);
+ groupwin++, window++) {
+ /* inverse quantization */
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++) {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength) +
+ BandOffsets[band];
+ FIXP_DBL locMax;
+
+ const int noLines = BandOffsets[band + 1] - BandOffsets[band];
+ const int bnds = group * 16 + band;
+
+ if ((pCodeBook[bnds] == ZERO_HCB) ||
+ (pCodeBook[bnds] == INTENSITY_HCB) ||
+ (pCodeBook[bnds] == INTENSITY_HCB2))
+ continue;
+
+ if (pCodeBook[bnds] == NOISE_HCB) {
+ /* Leave headroom for PNS values. + 1 because ceil(log2(2^(0.25*3))) =
+ 1, worst case of additional headroom required because of the
+ scalefactor. */
+ pSfbScale[window * 16 + band] = (pScaleFactor[bnds] >> 2) + 1;
+ continue;
+ }
+
+ locMax = maxabs_D(pSpectralCoefficient, noLines);
+
+ if (active_band_search) {
+ if (locMax != FIXP_DBL(0)) {
+ band_is_noise[group * 16 + band] = 0;
+ }
+ }
+
+ /* Cheap robustness improvement - Do not remove!!! */
+ if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+
+ /* Added by Youliy Ninov:
+ The inverse quantization operation is given by (ISO/IEC 14496-3:2009(E))
+ by:
+
+ x_invquant=Sign(x_quant). abs(x_quant)^(4/3)
+
+ We apply a gain, derived from the scale factor for the particular sfb,
+ according to the following function:
+
+ gain=2^(0.25*ScaleFactor)
+
+ So, after scaling we have:
+
+ x_rescale=gain*x_invquant=Sign(x_quant)*2^(0.25*ScaleFactor)*abs(s_quant)^(4/3)
+
+ We could represent the ScaleFactor as:
+
+ ScaleFactor= (ScaleFactor >> 2)*4 + ScaleFactor %4
+
+ When we substitute it we get:
+
+ x_rescale=Sign(x_quant)*2^(ScaleFactor>>2)* (
+ 2^(0.25*(ScaleFactor%4))*abs(s_quant)^(4/3))
+
+ When we set: msb=(ScaleFactor>>2) and lsb=(ScaleFactor%4), we obtain:
+
+ x_rescale=Sign(x_quant)*(2^msb)* ( 2^(lsb/4)*abs(s_quant)^(4/3))
+
+ The rescaled output can be represented by:
+ mantissa : Sign(x_quant)*( 2^(lsb/4)*abs(s_quant)^(4/3))
+ exponent :(2^msb)
+
+ */
+
+ int msb = pScaleFactor[bnds] >> 2;
+
+ /* Inverse quantize band only if it is not empty */
+ if (locMax != FIXP_DBL(0)) {
+ int lsb = pScaleFactor[bnds] & 0x03;
+
+ int scale = EvaluatePower43(&locMax, lsb);
+
+ scale = CntLeadingZeros(locMax) - scale - 2;
+
+ pSfbScale[window * 16 + band] = msb - scale;
+ InverseQuantizeBand(pSpectralCoefficient, InverseQuantTable,
+ MantissaTable[lsb], ExponentTable[lsb], noLines,
+ scale);
+ } else {
+ pSfbScale[window * 16 + band] = msb;
+ }
+
+ } /* for (band=0; band < ScaleFactorBandsTransmitted; band++) */
+
+ /* Make sure the array is cleared to the end */
+ SHORT start_clear = BandOffsets[ScaleFactorBandsTransmitted];
+ SHORT end_clear = BandOffsets[total_bands];
+ int diff_clear = (int)(end_clear - start_clear);
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, window,
+ pAacDecoderChannelInfo->granuleLength) +
+ start_clear;
+ FDKmemclear(pSpectralCoefficient, diff_clear * sizeof(FIXP_DBL));
+
+ } /* for (groupwin=0; groupwin <
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group);
+ groupwin++, window++) */
+ } /* for (window=0, group=0; group <
+ GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++)*/
+
+ return AAC_DEC_OK;
+}
+
+AAC_DECODER_ERROR CBlock_ReadSpectralData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags) {
+ int index, i;
+ const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+
+ SPECTRAL_PTR pSpectralCoefficient =
+ pAacDecoderChannelInfo->pSpectralCoefficient;
+
+ FDK_ASSERT(BandOffsets != NULL);
+
+ FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM));
+
+ if ((flags & AC_ER_HCR) == 0) {
+ int group;
+ int groupoffset;
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+ int ScaleFactorBandsTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ int granuleLength = pAacDecoderChannelInfo->granuleLength;
+
+ groupoffset = 0;
+
+ /* plain huffman decoder short */
+ int max_group = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+
+ for (group = 0; group < max_group; group++) {
+ int max_groupwin =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
+ int band;
+
+ int bnds = group * 16;
+
+ int bandOffset1 = BandOffsets[0];
+ for (band = 0; band < ScaleFactorBandsTransmitted; band++, bnds++) {
+ UCHAR currentCB = pCodeBook[bnds];
+ int bandOffset0 = bandOffset1;
+ bandOffset1 = BandOffsets[band + 1];
+
+ /* patch to run plain-huffman-decoder with vcb11 input codebooks
+ * (LAV-checking might be possible below using the virtual cb and a
+ * LAV-table) */
+ if ((currentCB >= 16) && (currentCB <= 31)) {
+ pCodeBook[bnds] = currentCB = 11;
+ }
+ if (((currentCB != ZERO_HCB) && (currentCB != NOISE_HCB) &&
+ (currentCB != INTENSITY_HCB) && (currentCB != INTENSITY_HCB2))) {
+ const CodeBookDescription *hcb =
+ &AACcodeBookDescriptionTable[currentCB];
+ int step = hcb->Dimension;
+ int offset = hcb->Offset;
+ int bits = hcb->numBits;
+ int mask = (1 << bits) - 1;
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+ int groupwin;
+
+ FIXP_DBL *mdctSpectrum =
+ &pSpectralCoefficient[groupoffset * granuleLength];
+
+ if (offset == 0) {
+ for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
+ for (index = bandOffset0; index < bandOffset1; index += step) {
+ int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ for (i = 0; i < step; i++, idx >>= bits) {
+ FIXP_DBL tmp = (FIXP_DBL)((idx & mask) - offset);
+ if (tmp != FIXP_DBL(0)) tmp = (FDKreadBit(bs)) ? -tmp : tmp;
+ mdctSpectrum[index + i] = tmp;
+ }
+
+ if (currentCB == ESCBOOK) {
+ for (int j = 0; j < 2; j++)
+ mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
+ bs, (LONG)mdctSpectrum[index + j]);
+ }
+ }
+ mdctSpectrum += granuleLength;
+ }
+ } else {
+ for (groupwin = 0; groupwin < max_groupwin; groupwin++) {
+ for (index = bandOffset0; index < bandOffset1; index += step) {
+ int idx = CBlock_DecodeHuffmanWordCB(bs, CodeBook);
+ for (i = 0; i < step; i++, idx >>= bits) {
+ mdctSpectrum[index + i] = (FIXP_DBL)((idx & mask) - offset);
+ }
+ if (currentCB == ESCBOOK) {
+ for (int j = 0; j < 2; j++)
+ mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape(
+ bs, (LONG)mdctSpectrum[index + j]);
+ }
+ }
+ mdctSpectrum += granuleLength;
+ }
+ }
+ }
+ }
+ groupoffset += max_groupwin;
+ }
+ /* plain huffman decoding (short) finished */
+ }
+
+ /* HCR - Huffman Codeword Reordering short */
+ else /* if ( flags & AC_ER_HCR ) */
+
+ {
+ H_HCR_INFO hHcr = &pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo;
+
+ int hcrStatus = 0;
+
+ /* advanced Huffman decoding starts here (HCR decoding :) */
+ if (pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData != 0) {
+ /* HCR initialization short */
+ hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+ if (hcrStatus != 0) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ /* HCR decoding short */
+ hcrStatus =
+ HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs);
+
+ if (hcrStatus != 0) {
+#if HCR_ERROR_CONCEALMENT
+ HcrMuteErroneousLines(hHcr);
+#else
+ return AAC_DEC_DECODE_FRAME_ERROR;
+#endif /* HCR_ERROR_CONCEALMENT */
+ }
+
+ FDKpushFor(bs, pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .lenOfReorderedSpectralData);
+ }
+ }
+ /* HCR - Huffman Codeword Reordering short finished */
+
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) &&
+ !(flags & (AC_ELD | AC_SCALABLE))) {
+ /* apply pulse data */
+ CPulseData_Apply(
+ &pAacDecoderChannelInfo->pDynData->specificTo.aac.PulseData,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo),
+ SPEC_LONG(pSpectralCoefficient));
+ }
+
+ return AAC_DEC_OK;
+}
+
+static const FIXP_SGL noise_level_tab[8] = {
+ /* FDKpow(2, (float)(noise_level-14)/3.0f) * 2; (*2 to compensate for
+ fMultDiv2) noise_level_tab(noise_level==0) == 0 by definition
+ */
+ FX_DBL2FXCONST_SGL(0x00000000 /*0x0a145173*/),
+ FX_DBL2FXCONST_SGL(0x0cb2ff5e),
+ FX_DBL2FXCONST_SGL(0x10000000),
+ FX_DBL2FXCONST_SGL(0x1428a2e7),
+ FX_DBL2FXCONST_SGL(0x1965febd),
+ FX_DBL2FXCONST_SGL(0x20000000),
+ FX_DBL2FXCONST_SGL(0x28514606),
+ FX_DBL2FXCONST_SGL(0x32cbfd33)};
+
+void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
+ UCHAR *band_is_noise) {
+ const SHORT *swb_offset = GetScaleFactorBandOffsets(
+ &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
+ int g, win, gwin, sfb, noiseFillingStartOffset, nfStartOffset_sfb;
+
+ /* Obtain noise level and scale factor offset. */
+ int noise_level = pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .fd_noise_level_and_offset >>
+ 5;
+ const FIXP_SGL noiseVal_pos = noise_level_tab[noise_level];
+
+ /* noise_offset can change even when noise_level=0. Neccesary for IGF stereo
+ * filling */
+ const int noise_offset = (pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .fd_noise_level_and_offset &
+ 0x1f) -
+ 16;
+
+ int max_sfb =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+
+ noiseFillingStartOffset =
+ (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ ? 20
+ : 160;
+ if (pAacDecoderChannelInfo->granuleLength == 96) {
+ noiseFillingStartOffset =
+ (3 * noiseFillingStartOffset) /
+ 4; /* scale offset with 3/4 for coreCoderFrameLength == 768 */
+ }
+
+ /* determine sfb from where on noise filling is applied */
+ for (sfb = 0; swb_offset[sfb] < noiseFillingStartOffset; sfb++)
+ ;
+ nfStartOffset_sfb = sfb;
+
+ /* if (noise_level!=0) */
+ {
+ for (g = 0, win = 0; g < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ g++) {
+ int windowGroupLength =
+ GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, g);
+ for (sfb = nfStartOffset_sfb; sfb < max_sfb; sfb++) {
+ int bin_start = swb_offset[sfb];
+ int bin_stop = swb_offset[sfb + 1];
+
+ int flagN = band_is_noise[g * 16 + sfb];
+
+ /* if all bins of one sfb in one window group are zero modify the scale
+ * factor by noise_offset */
+ if (flagN) {
+ /* Change scaling factors for empty signal bands */
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] +=
+ noise_offset;
+ /* scale factor "sf" implied gain "g" is g = 2^(sf/4) */
+ for (gwin = 0; gwin < windowGroupLength; gwin++) {
+ pAacDecoderChannelInfo->pDynData
+ ->aSfbScale[(win + gwin) * 16 + sfb] += (noise_offset >> 2);
+ }
+ }
+
+ ULONG seed = *nfRandomSeed;
+ /* + 1 because exponent of MantissaTable[lsb][0] is always 1. */
+ int scale =
+ (pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] >>
+ 2) +
+ 1;
+ int lsb =
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[g * 16 + sfb] & 3;
+ FIXP_DBL mantissa = MantissaTable[lsb][0];
+
+ for (gwin = 0; gwin < windowGroupLength; gwin++) {
+ FIXP_DBL *pSpec =
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient, win + gwin,
+ pAacDecoderChannelInfo->granuleLength);
+
+ int scale1 = scale - pAacDecoderChannelInfo->pDynData
+ ->aSfbScale[(win + gwin) * 16 + sfb];
+ FIXP_DBL scaled_noiseVal_pos =
+ scaleValue(fMultDiv2(noiseVal_pos, mantissa), scale1);
+ FIXP_DBL scaled_noiseVal_neg = -scaled_noiseVal_pos;
+
+ /* If the whole band is zero, just fill without checking */
+ if (flagN) {
+ for (int bin = bin_start; bin < bin_stop; bin++) {
+ seed = (ULONG)(
+ (UINT64)seed * 69069 +
+ 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
+ pSpec[bin] =
+ (seed & 0x10000) ? scaled_noiseVal_neg : scaled_noiseVal_pos;
+ } /* for (bin...) */
+ }
+ /*If band is sparsely filled, check for 0 and fill */
+ else {
+ for (int bin = bin_start; bin < bin_stop; bin++) {
+ if (pSpec[bin] == (FIXP_DBL)0) {
+ seed = (ULONG)(
+ (UINT64)seed * 69069 +
+ 5); /* Inlined: UsacRandomSign - origin in usacdec_lpd.h */
+ pSpec[bin] = (seed & 0x10000) ? scaled_noiseVal_neg
+ : scaled_noiseVal_pos;
+ }
+ } /* for (bin...) */
+ }
+
+ } /* for (gwin...) */
+ *nfRandomSeed = seed;
+ } /* for (sfb...) */
+ win += windowGroupLength;
+ } /* for (g...) */
+
+ } /* ... */
+}
+
+AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
+ const UINT flags) {
+ AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
+ ARITH_CODING_ERROR error = ARITH_CODER_OK;
+ int arith_reset_flag, lg, numWin, win, winLen;
+ const SHORT *RESTRICT BandOffsets;
+
+ /* number of transmitted spectral coefficients */
+ BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo,
+ pSamplingRateInfo);
+ lg = BandOffsets[GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo->icsInfo)];
+
+ numWin = GetWindowsPerFrame(&pAacDecoderChannelInfo->icsInfo);
+ winLen = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo))
+ ? (int)frame_length
+ : (int)frame_length / numWin;
+
+ if (flags & AC_INDEP) {
+ arith_reset_flag = 1;
+ } else {
+ arith_reset_flag = (USHORT)FDKreadBits(hBs, 1);
+ }
+
+ for (win = 0; win < numWin; win++) {
+ error =
+ CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs,
+ SPEC(pAacDecoderChannelInfo->pSpectralCoefficient,
+ win, pAacDecoderChannelInfo->granuleLength),
+ lg, winLen, arith_reset_flag && (win == 0));
+ if (error != ARITH_CODER_OK) {
+ goto bail;
+ }
+ }
+
+bail:
+ if (error == ARITH_CODER_ERROR) {
+ errorAAC = AAC_DEC_PARSE_ERROR;
+ }
+
+ return errorAAC;
+}
+
+void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
+ const UINT elFlags, const int channel,
+ const int common_window) {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_MPEGD_RES | AC_RSV603DA))) {
+ CPns_Apply(&pAacDecoderChannelInfo[channel]->data.aac.PnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[channel]->specScale,
+ pAacDecoderChannelInfo[channel]->pDynData->aScaleFactor,
+ pSamplingRateInfo,
+ pAacDecoderChannelInfo[channel]->granuleLength, channel);
+ }
+
+ UCHAR nbands =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[channel]->icsInfo);
+
+ CTns_Apply(&pAacDecoderChannelInfo[channel]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[channel]->icsInfo,
+ pAacDecoderChannelInfo[channel]->pSpectralCoefficient,
+ pSamplingRateInfo, pAacDecoderChannelInfo[channel]->granuleLength,
+ nbands, (elFlags & AC_EL_ENHANCED_NOISE) ? 1 : 0, flags);
+}
+
+static int getWindow2Nr(int length, int shape) {
+ int nr = 0;
+
+ if (shape == 2) {
+ /* Low Overlap, 3/4 zeroed */
+ nr = (length * 3) >> 2;
+ }
+
+ return nr;
+}
+
+FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n) {
+ FIXP_DBL corr = (FIXP_DBL)0;
+ FIXP_DBL ener = (FIXP_DBL)1;
+
+ int headroom_x = getScalefactor(x, n);
+ int headroom_y = getScalefactor(y, n);
+
+ /*Calculate the normalization necessary due to addition*/
+ /* Check for power of two /special case */
+ INT width_shift = (INT)(fNormz((FIXP_DBL)n));
+ /* Get the number of bits necessary minus one, because we need one sign bit
+ * only */
+ width_shift = 31 - width_shift;
+
+ for (int i = 0; i < n; i++) {
+ corr +=
+ fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >> width_shift;
+ ener += fPow2Div2((y[i] << headroom_y)) >> width_shift;
+ }
+
+ int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
+ int exp_ener = ((17 - headroom_y) << 1) + width_shift + 1;
+
+ int temp_exp = 0;
+ FIXP_DBL output = fDivNormSigned(corr, ener, &temp_exp);
+
+ int output_exp = (exp_corr - exp_ener) + temp_exp;
+
+ INT output_shift = 17 - output_exp;
+ output_shift = fMin(output_shift, 31);
+
+ output = scaleValue(output, -output_shift);
+
+ return output;
+}
+
+void CBlock_FrequencyToTime(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
+ UINT elFlags, INT elCh) {
+ int fr, fl, tl, nSpec;
+
+#if defined(FDK_ASSERT_ENABLE)
+ LONG nSamples;
+#endif
+
+ /* Determine left slope length (fl), right slope length (fr) and transform
+ length (tl). USAC: The slope length may mismatch with the previous frame in
+ case of LPD / FD transitions. The adjustment is handled by the imdct
+ implementation.
+ */
+ tl = frameLen;
+ nSpec = 1;
+
+ switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) {
+ default:
+ case BLOCK_LONG:
+ fl = frameLen;
+ fr = frameLen -
+ getWindow2Nr(frameLen,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo));
+ /* New startup needs differentiation between sine shape and low overlap
+ shape. This is a special case for the LD-AAC transformation windows,
+ because the slope length can be different while using the same window
+ sequence. */
+ if (pAacDecoderStaticChannelInfo->IMdct.prev_tl == 0) {
+ fl = fr;
+ }
+ break;
+ case BLOCK_STOP:
+ fl = frameLen >> 3;
+ fr = frameLen;
+ break;
+ case BLOCK_START: /* or StopStartSequence */
+ fl = frameLen;
+ fr = frameLen >> 3;
+ break;
+ case BLOCK_SHORT:
+ fl = fr = frameLen >> 3;
+ tl >>= 3;
+ nSpec = 8;
+ break;
+ }
+
+ {
+ int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
+
+ if (pAacDecoderStaticChannelInfo->last_core_mode == LPD) {
+ INT fac_FB = 1;
+ if (elFlags & AC_EL_FULLBANDLPD) {
+ fac_FB = 2;
+ }
+
+ FIXP_DBL *synth;
+
+ /* Keep some free space at the beginning of the buffer. To be used for
+ * past data */
+ if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
+ synth = pWorkBuffer1 + ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB);
+ } else {
+ synth = pWorkBuffer1 + PIT_MAX_MAX * fac_FB;
+ }
+
+ int fac_length =
+ (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT)
+ ? (frameLen >> 4)
+ : (frameLen >> 3);
+
+ INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
+ FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
+
+ int nbDiv = (elFlags & AC_EL_FULLBANDLPD) ? 2 : 4;
+ int lFrame = (elFlags & AC_EL_FULLBANDLPD) ? frameLen / 2 : frameLen;
+ int nbSubfr =
+ lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
+ int LpdSfd = (nbDiv * nbSubfr) >> 1;
+ int SynSfd = LpdSfd - BPF_SFD;
+
+ FDKmemclear(
+ pitch,
+ sizeof(
+ pitch)); // added to prevent ferret errors in bass_pf_1sf_delay
+ FDKmemclear(pit_gain, sizeof(pit_gain));
+
+ /* FAC case */
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0 ||
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 4) {
+ FIXP_DBL fac_buf[LFAC];
+ FIXP_LPC *A = pAacDecoderChannelInfo->data.usac.lp_coeff[0];
+
+ if (!frameOk || last_frame_lost ||
+ (pAacDecoderChannelInfo->data.usac.fac_data[0] == NULL)) {
+ FDKmemclear(fac_buf,
+ pAacDecoderChannelInfo->granuleLength * sizeof(FIXP_DBL));
+ pAacDecoderChannelInfo->data.usac.fac_data[0] = fac_buf;
+ pAacDecoderChannelInfo->data.usac.fac_data_e[0] = 0;
+ }
+
+ INT A_exp; /* linear prediction coefficients exponent */
+ {
+ for (int i = 0; i < M_LP_FILTER_ORDER; i++) {
+ A[i] = FX_DBL2FX_LPC(fixp_cos(
+ fMult(pAacDecoderStaticChannelInfo->lpc4_lsf[i],
+ FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+
+ E_LPC_f_lsp_a_conversion(A, A, &A_exp);
+ }
+
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ CLpd_FAC_Acelp2Mdct(
+ &pAacDecoderStaticChannelInfo->IMdct, synth,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec,
+ pAacDecoderChannelInfo->data.usac.fac_data[0],
+ pAacDecoderChannelInfo->data.usac.fac_data_e[0], fac_length,
+ frameLen, tl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, A, A_exp, &pAacDecoderStaticChannelInfo->acelp,
+ (FIXP_DBL)0, /* FAC gain has already been applied. */
+ (last_frame_lost || !frameOk), 1,
+ pAacDecoderStaticChannelInfo->last_lpd_mode, 0,
+ pAacDecoderChannelInfo->currAliasingSymmetry);
+
+ } else {
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ imlt_block(
+ &pAacDecoderStaticChannelInfo->IMdct, synth,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
+ FDKgetWindowSlope(
+ fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, (FIXP_DBL)0,
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+ }
+ FDK_ASSERT(nSamples == frameLen);
+
+ /* The "if" clause is entered both for fullbandLpd mono and
+ * non-fullbandLpd*. The "else"-> just for fullbandLpd stereo*/
+ if (!(elFlags & AC_EL_LPDSTEREOIDX)) {
+ FDKmemcpy(pitch, pAacDecoderStaticChannelInfo->old_T_pf,
+ SynSfd * sizeof(INT));
+ FDKmemcpy(pit_gain, pAacDecoderStaticChannelInfo->old_gain_pf,
+ SynSfd * sizeof(FIXP_DBL));
+
+ for (int i = SynSfd; i < LpdSfd + 3; i++) {
+ pitch[i] = L_SUBFR;
+ pit_gain[i] = (FIXP_DBL)0;
+ }
+
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 0) {
+ pitch[SynSfd] = pitch[SynSfd - 1];
+ pit_gain[SynSfd] = pit_gain[SynSfd - 1];
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ pitch[SynSfd + 1] = pitch[SynSfd];
+ pit_gain[SynSfd + 1] = pit_gain[SynSfd];
+ }
+ }
+
+ /* Copy old data to the beginning of the buffer */
+ {
+ FDKmemcpy(
+ pWorkBuffer1, pAacDecoderStaticChannelInfo->old_synth,
+ ((PIT_MAX_MAX - (1 * L_SUBFR)) * fac_FB) * sizeof(FIXP_DBL));
+ }
+
+ FIXP_DBL *p2_synth = pWorkBuffer1 + (PIT_MAX_MAX * fac_FB);
+
+ /* recalculate pitch gain to allow postfilering on FAC area */
+ for (int i = 0; i < SynSfd + 2; i++) {
+ int T = pitch[i];
+ FIXP_DBL gain = pit_gain[i];
+
+ if (gain > (FIXP_DBL)0) {
+ gain = get_gain(&p2_synth[i * L_SUBFR * fac_FB],
+ &p2_synth[(i * L_SUBFR * fac_FB) - fac_FB * T],
+ L_SUBFR * fac_FB);
+ pit_gain[i] = gain;
+ }
+ }
+
+ bass_pf_1sf_delay(p2_synth, pitch, pit_gain, frameLen,
+ (LpdSfd + 2) * L_SUBFR + BPF_SFD * L_SUBFR,
+ frameLen - (LpdSfd + 4) * L_SUBFR, outSamples,
+ pAacDecoderStaticChannelInfo->mem_bpf);
+ }
+
+ } else /* last_core_mode was not LPD */
+ {
+ FIXP_DBL *tmp =
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->mdctOutTemp;
+#if defined(FDK_ASSERT_ENABLE)
+ nSamples =
+#endif
+ imlt_block(&pAacDecoderStaticChannelInfo->IMdct, tmp,
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale, nSpec, frameLen, tl,
+ FDKgetWindowSlope(
+ fl, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(
+ fr, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, (FIXP_DBL)0,
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+
+ scaleValuesSaturate(outSamples, tmp, frameLen, MDCT_OUT_HEADROOM);
+ }
+ }
+
+ FDK_ASSERT(nSamples == frameLen);
+
+ pAacDecoderStaticChannelInfo->last_core_mode =
+ (pAacDecoderChannelInfo->icsInfo.WindowSequence == BLOCK_SHORT) ? FD_SHORT
+ : FD_LONG;
+ pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
+}
+
+#include "ldfiltbank.h"
+void CBlock_FrequencyToTimeLowDelay(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const short frameLen) {
+ InvMdctTransformLowDelay_fdk(
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient),
+ pAacDecoderChannelInfo->specScale[0], outSamples,
+ pAacDecoderStaticChannelInfo->pOverlapBuffer, frameLen);
+}
diff --git a/fdk-aac/libAACdec/src/block.h b/fdk-aac/libAACdec/src/block.h
new file mode 100644
index 0000000..f0f56cd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/block.h
@@ -0,0 +1,345 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: long/short-block decoding
+
+*******************************************************************************/
+
+#ifndef BLOCK_H
+#define BLOCK_H
+
+#include "common_fix.h"
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+/* PNS (of block) */
+void CPns_Read(CPnsData *pPnsData, HANDLE_FDK_BITSTREAM bs,
+ const CodeBookDescription *hcb, SHORT *pScaleFactor,
+ UCHAR global_gain, int band, int group);
+
+void CPns_Apply(const CPnsData *pPnsData, const CIcsInfo *pIcsInfo,
+ SPECTRAL_PTR pSpectrum, const SHORT *pSpecScale,
+ const SHORT *pScaleFactor,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const int channel);
+
+void CBlock_ApplyNoise(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, ULONG *nfRandomSeed,
+ UCHAR *band_is_noise);
+
+/* TNS (of block) */
+/*!
+ \brief Read tns data-present flag from bitstream
+
+ The function reads the data-present flag for tns from
+ the bitstream.
+
+ \return none
+*/
+void CTns_ReadDataPresentFlag(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData);
+
+void CTns_ReadDataPresentUsac(HANDLE_FDK_BITSTREAM hBs, CTnsData *pTnsData0,
+ CTnsData *pTnsData1, UCHAR *ptns_on_lr,
+ const CIcsInfo *pIcsInfo, const UINT flags,
+ const UINT elFlags, const int fCommonWindow);
+
+AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, CTnsData *pTnsData,
+ const CIcsInfo *pIcsInfo, const UINT flags);
+
+void CTns_Apply(CTnsData *RESTRICT pTnsData, /*!< pointer to aac decoder info */
+ const CIcsInfo *pIcsInfo, SPECTRAL_PTR pSpectralCoefficient,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const INT granuleLength, const UCHAR nbands,
+ const UCHAR igf_active, const UINT flags);
+
+/* Block */
+
+LONG CBlock_GetEscape(HANDLE_FDK_BITSTREAM bs, const LONG q);
+
+/**
+ * \brief Read scale factor data. See chapter 4.6.2.3.2 of ISO/IEC 14496-3.
+ * The SF_OFFSET = 100 value referenced in chapter 4.6.2.3.3 is already
+ * substracted from the scale factor values. Also includes PNS data reading.
+ * \param bs bit stream handle data source
+ * \param pAacDecoderChannelInfo channel context info were decoded data is
+ * stored into.
+ * \param flags the decoder flags.
+ */
+AAC_DECODER_ERROR CBlock_ReadScaleFactorData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs,
+ const UINT flags);
+
+/**
+ * \brief Read Huffman encoded spectral data.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ * \param flags syntax flags.
+ */
+AAC_DECODER_ERROR CBlock_ReadSpectralData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags);
+
+/**
+ * \brief Read Arithmetic encoded spectral data.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param pAacDecoderStaticChannelInfo static channel context info.
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ * \param frame_length spectral window length.
+ * \param flags syntax flags.
+ * \return error code.
+ */
+AAC_DECODER_ERROR CBlock_ReadAcSpectralData(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT frame_length,
+ const UINT flags);
+
+AAC_DECODER_ERROR CBlock_ReadSectionData(
+ HANDLE_FDK_BITSTREAM bs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags);
+
+/**
+ * \brief find a common exponent (shift factor) for all sfb in each Spectral
+ * window, and store them into CAacDecoderChannelInfo::specScale.
+ * \param pAacDecoderChannelInfo channel context info.
+ * \param UCHAR maxSfbs maximum number of SFBs to be processed (might differ
+ * from pAacDecoderChannelInfo->icsInfo.MaxSfBands)
+ * \param pSamplingRateInfo sampling rate info (sfb offsets).
+ */
+void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR maxSfbs,
+ SamplingRateInfo *pSamplingRateInfo);
+
+/**
+ * \brief Apply TNS and PNS tools.
+ */
+void ApplyTools(CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ const SamplingRateInfo *pSamplingRateInfo, const UINT flags,
+ const UINT elFlags, const int channel, const int maybe_jstereo);
+
+/**
+ * \brief Transform MDCT spectral data into time domain
+ */
+void CBlock_FrequencyToTime(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const SHORT frameLen, const int frameOk, FIXP_DBL *pWorkBuffer1,
+ UINT elFlags, INT elCh);
+
+/**
+ * \brief Transform double lapped MDCT (AAC-ELD) spectral data into time domain.
+ */
+void CBlock_FrequencyToTimeLowDelay(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[],
+ const short frameLen);
+
+AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ SamplingRateInfo *pSamplingRateInfo, UCHAR *band_is_noise,
+ UCHAR active_band_search);
+
+/**
+ * \brief Calculate 2^(lsb/4) * value^(4/3)
+ * \param pValue pointer to quantized value. The inverse quantized result is
+ * stored back here.
+ * \param lsb 2 LSBs of the scale factor (scaleFactor % 4) applied as power 2
+ * factor to the resulting inverse quantized value.
+ * \return the exponent of the result (mantissa) stored into *pValue.
+ */
+FDK_INLINE
+int EvaluatePower43(FIXP_DBL *pValue, UINT lsb) {
+ FIXP_DBL value;
+ UINT freeBits;
+ UINT exponent;
+
+ value = *pValue;
+ freeBits = fNormz(value);
+ exponent = DFRACT_BITS - freeBits;
+ FDK_ASSERT(exponent < 14);
+
+ UINT x = (((int)value << freeBits) >> 19);
+ UINT tableIndex = (x & 0x0FFF) >> 4;
+ FIXP_DBL invQVal;
+
+ x = x & 0x0F;
+
+ UINT r0 = (LONG)InverseQuantTable[tableIndex + 0];
+ UINT r1 = (LONG)InverseQuantTable[tableIndex + 1];
+ USHORT nx = 16 - x;
+ UINT temp = (r0)*nx + (r1)*x;
+ invQVal = (FIXP_DBL)temp;
+
+ FDK_ASSERT(lsb < 4);
+ *pValue = fMultDiv2(invQVal, MantissaTable[lsb][exponent]);
+
+ /* + 1 compensates fMultDiv2(). */
+ return ExponentTable[lsb][exponent] + 1;
+}
+
+/* Recalculate gain */
+FIXP_DBL get_gain(const FIXP_DBL *x, const FIXP_DBL *y, int n);
+
+/**
+ * \brief determine the required shift scale for the given quantized value and
+ * scale (factor % 4) value.
+ */
+FDK_INLINE int GetScaleFromValue(FIXP_DBL value, unsigned int lsb) {
+ if (value != (FIXP_DBL)0) {
+ int scale = EvaluatePower43(&value, lsb);
+ return CntLeadingZeros(value) - scale - 2;
+ } else
+ return 0; /* Return zero, because its useless to scale a zero value, saves
+ workload and avoids scaling overshifts. */
+}
+
+/*!
+ \brief Read huffman codeword
+
+ The function reads the huffman codeword from the bitstream and
+ returns the index value.
+
+ \return index value
+*/
+inline int CBlock_DecodeHuffmanWord(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const CodeBookDescription *hcb) /*!< pointer to codebook description */
+{
+ UINT val;
+ UINT index = 0;
+ const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook;
+
+ while (1) {
+ val = CodeBook[index]
+ [FDKreadBits(bs, HuffmanBits)]; /* Expensive memory access */
+
+ if ((val & 1) == 0) {
+ index = val >> 2;
+ continue;
+ } else {
+ if (val & 2) {
+ FDKpushBackCache(bs, 1);
+ }
+
+ val >>= 2;
+ break;
+ }
+ }
+
+ return val;
+}
+inline int CBlock_DecodeHuffmanWordCB(
+ HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */
+ const USHORT (
+ *CodeBook)[HuffmanEntries]) /*!< pointer to codebook description */
+{
+ UINT index = 0;
+
+ while (1) {
+ index = CodeBook[index][FDKread2Bits(bs)]; /* Expensive memory access */
+ if (index & 1) break;
+ index >>= 2;
+ }
+ if (index & 2) {
+ FDKpushBackCache(bs, 1);
+ }
+ return index >> 2;
+}
+
+#endif /* #ifndef BLOCK_H */
diff --git a/fdk-aac/libAACdec/src/channel.cpp b/fdk-aac/libAACdec/src/channel.cpp
new file mode 100644
index 0000000..a020034
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channel.cpp
@@ -0,0 +1,924 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#include "channel.h"
+#include "aacdecoder.h"
+#include "block.h"
+#include "aacdec_tns.h"
+#include "FDK_bitstream.h"
+
+#include "conceal.h"
+
+#include "rvlc.h"
+
+#include "aacdec_hcr.h"
+
+#include "usacdec_lpd.h"
+#include "usacdec_fac.h"
+
+static void MapMidSideMaskToPnsCorrelation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2]) {
+ int group;
+
+ for (group = 0; group < pAacDecoderChannelInfo[L]->icsInfo.WindowGroups;
+ group++) {
+ UCHAR groupMask = 1 << group;
+
+ for (UCHAR band = 0; band < pAacDecoderChannelInfo[L]->icsInfo.MaxSfBands;
+ band++) {
+ if (pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] &
+ groupMask) { /* channels are correlated */
+ CPns_SetCorrelation(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
+ band, 0);
+
+ if (CPns_IsPnsUsed(&pAacDecoderChannelInfo[L]->data.aac.PnsData, group,
+ band) &&
+ CPns_IsPnsUsed(&pAacDecoderChannelInfo[R]->data.aac.PnsData, group,
+ band))
+ pAacDecoderChannelInfo[L]->pComData->jointStereoData.MsUsed[band] ^=
+ groupMask; /* clear the groupMask-bit */
+ }
+ }
+ }
+}
+
+static void Clean_Complex_Prediction_coefficients(
+ CJointStereoPersistentData *pJointStereoPersistentData, int windowGroups,
+ const int low_limit, const int high_limit) {
+ for (int group = 0; group < windowGroups; group++) {
+ for (int sfb = low_limit; sfb < high_limit; sfb++) {
+ pJointStereoPersistentData->alpha_q_re_prev[group][sfb] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][sfb] = 0;
+ }
+ }
+}
+
+/*!
+ \brief Decode channel pair element
+
+ The function decodes a channel pair element.
+
+ \return none
+*/
+void CChannelElement_Decode(
+ CAacDecoderChannelInfo
+ *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
+ int el_channels) {
+ int ch = 0;
+
+ int maxSfBandsL = 0, maxSfBandsR = 0;
+ int maybe_jstereo = (el_channels > 1);
+
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && el_channels == 2) {
+ if (pAacDecoderChannelInfo[L]->data.usac.core_mode ||
+ pAacDecoderChannelInfo[R]->data.usac.core_mode) {
+ maybe_jstereo = 0;
+ }
+ }
+
+ if (maybe_jstereo) {
+ maxSfBandsL =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo);
+ maxSfBandsR =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo);
+
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive ||
+ pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) {
+ MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo);
+ }
+ }
+ /* if tns_on_lr == 1 run MS */ /* &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active
+ == 1) */
+ if (((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 1)) ||
+ ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) == 0)) {
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ CJointStereo_ApplyMS(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[L]->specScale,
+ pAacDecoderChannelInfo[R]->specScale,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
+ maxSfBandsL, maxSfBandsR,
+ pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev,
+ &(pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev_e),
+ 1);
+
+ } /* if ( ((elFlags & AC_EL_USAC_CP_POSSIBLE).... */
+ } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow)*/
+
+ /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb
+ */
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ if ((pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
+ 1) &&
+ (el_channels == 2)) {
+ CJointStereo_ApplyIS(
+ pAacDecoderChannelInfo,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[L]->icsInfo));
+ }
+ }
+ } /* maybe_stereo */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
+ /* Decode LPD data */
+ CLpdChannelStream_Decode(pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch], flags);
+ } else {
+ UCHAR noSfbs =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[ch]->icsInfo);
+ /* For USAC common window: max_sfb of both channels may differ
+ * (common_max_sfb == 0). */
+ if ((maybe_jstereo == 1) &&
+ (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ==
+ 1)) {
+ noSfbs = fMax(maxSfBandsL, maxSfBandsR);
+ }
+ int CP_active = 0;
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ CP_active = pAacDecoderChannelInfo[ch]
+ ->pComData->jointStereoData.cplx_pred_flag;
+ }
+
+ /* Omit writing of pAacDecoderChannelInfo[ch]->specScale for complex
+ stereo prediction since scaling has already been carried out. */
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ if ((!CP_active) || (CP_active && (max_sfb_ste < noSfbs)) ||
+ ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0))) {
+ CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], noSfbs,
+ pSamplingRateInfo);
+
+ /*Active for the case of TNS applied before MS/CP*/
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0)) {
+ if (IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo)) {
+ for (int i = 0; i < noSfbs; i++) {
+ pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i] =
+ pAacDecoderChannelInfo[ch]->specScale[0];
+ }
+ } else {
+ for (int i = 0; i < 8; i++) {
+ for (int j = 0; j < noSfbs; j++) {
+ pAacDecoderChannelInfo[ch]->pDynData->aSfbScale[i * 16 + j] =
+ pAacDecoderChannelInfo[ch]->specScale[i];
+ }
+ }
+ }
+ }
+ }
+ }
+ } /* End "for (ch = 0; ch < el_channels; ch++)" */
+
+ if (maybe_jstereo) {
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ } /* CommonWindow */
+ else {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ FDKmemclear(
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.alpha_q_re_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
+ FDKmemclear(
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.alpha_q_im_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands * sizeof(SHORT));
+ }
+ }
+
+ } /* if (maybe_jstereo) */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_LPD) {
+ } else {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ /* Use same seed for coupled channels (CPE) */
+ int pnsCh = (ch > 0) ? L : ch;
+ CPns_UpdateNoiseState(
+ &pAacDecoderChannelInfo[ch]->data.aac.PnsData,
+ pAacDecoderChannelInfo[pnsCh]->data.aac.PnsData.currentSeed,
+ pAacDecoderChannelInfo[ch]->pComData->pnsRandomSeed);
+ }
+
+ if ((!(flags & (AC_USAC))) ||
+ ((flags & (AC_USAC)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_active ==
+ 1)) ||
+ (maybe_jstereo == 0)) {
+ ApplyTools(
+ pAacDecoderChannelInfo, pSamplingRateInfo, flags, elFlags, ch,
+ pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow);
+ }
+ } /* End "} else" */
+ } /* End "for (ch = 0; ch < el_channels; ch++)" */
+
+ if (maybe_jstereo) {
+ /* apply ms */
+ if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) {
+ /* if tns_on_lr == 0 run MS */
+ if ((flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) &&
+ (pAacDecoderChannelInfo[L]->pDynData->specificTo.usac.tns_on_lr ==
+ 0)) {
+ int max_sfb_ste = (INT)(pAacDecoderChannelInfo[L]->icsInfo.max_sfb_ste);
+
+ CJointStereo_ApplyMS(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ pAacDecoderChannelInfo[L]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[R]->pDynData->aSfbScale,
+ pAacDecoderChannelInfo[L]->specScale,
+ pAacDecoderChannelInfo[R]->specScale,
+ GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo,
+ pSamplingRateInfo),
+ GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo),
+ GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), max_sfb_ste,
+ maxSfBandsL, maxSfBandsR,
+ pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev,
+ &(pAacDecoderChannelInfo[L]
+ ->pComData->jointStereoData.store_dmx_re_prev_e),
+ 1);
+ }
+
+ } /* if (pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow) */
+
+ } /* if (maybe_jstereo) */
+
+ for (ch = 0; ch < el_channels; ch++) {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.clearSpectralCoeffs = 0;
+ }
+ }
+
+ CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags, el_channels);
+}
+
+void CChannel_CodebookTableInit(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ int b, w, maxBands, maxWindows;
+ int maxSfb = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook;
+
+ if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
+ maxBands = 64;
+ maxWindows = 1;
+ } else {
+ maxBands = 16;
+ maxWindows = 8;
+ }
+
+ for (w = 0; w < maxWindows; w++) {
+ for (b = 0; b < maxSfb; b++) {
+ pCodeBook[b] = ESCBOOK;
+ }
+ for (; b < maxBands; b++) {
+ pCodeBook[b] = ZERO_HCB;
+ }
+ pCodeBook += maxBands;
+ }
+}
+
+/*
+ * Arbitrary order bitstream parser
+ */
+AAC_DECODER_ERROR CChannelElement_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags, const UINT elFlags, const UINT frame_length,
+ const UCHAR numberOfChannels, const SCHAR epConfig,
+ HANDLE_TRANSPORTDEC pTpDec) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ const element_list_t *list;
+ int i, ch, decision_bit;
+ int crcReg1 = -1, crcReg2 = -1;
+ int cplxPred;
+ int ind_sw_cce_flag = 0, num_gain_element_lists = 0;
+
+ FDK_ASSERT((numberOfChannels == 1) || (numberOfChannels == 2));
+
+ /* Get channel element sequence table */
+ list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, elFlags);
+ if (list == NULL) {
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
+ goto bail;
+ }
+
+ CTns_Reset(&pAacDecoderChannelInfo[0]->pDynData->TnsData);
+ /* Set common window to 0 by default. If signalized in the bit stream it will
+ * be overwritten later explicitely */
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active = 0;
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr = 0;
+ }
+ if (numberOfChannels == 2) {
+ CTns_Reset(&pAacDecoderChannelInfo[1]->pDynData->TnsData);
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
+ }
+
+ cplxPred = 0;
+ if (pAacDecoderStaticChannelInfo != NULL) {
+ if (elFlags & AC_EL_USAC_CP_POSSIBLE) {
+ pAacDecoderChannelInfo[0]->pComData->jointStereoData.cplx_pred_flag = 0;
+ cplxPred = 1;
+ }
+ }
+
+ if (0 || (flags & (AC_ELD | AC_SCALABLE))) {
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 1;
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
+ }
+ }
+
+ /* Iterate through sequence table */
+ i = 0;
+ ch = 0;
+ decision_bit = 0;
+ do {
+ switch (list->id[i]) {
+ case element_instance_tag:
+ pAacDecoderChannelInfo[0]->ElementInstanceTag = FDKreadBits(hBs, 4);
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->ElementInstanceTag =
+ pAacDecoderChannelInfo[0]->ElementInstanceTag;
+ }
+ break;
+ case common_window:
+ decision_bit =
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow =
+ FDKreadBits(hBs, 1);
+ if (numberOfChannels == 2) {
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow =
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow;
+ }
+ break;
+ case ics_info:
+ /* store last window sequence (utilized in complex stereo prediction)
+ * before reading new channel-info */
+ if (cplxPred) {
+ if (pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
+ pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData.winSeqPrev =
+ pAacDecoderChannelInfo[0]->icsInfo.WindowSequence;
+ pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData.winShapePrev =
+ pAacDecoderChannelInfo[0]->icsInfo.WindowShape;
+ }
+ }
+ /* Read individual channel info */
+ error = IcsRead(hBs, &pAacDecoderChannelInfo[ch]->icsInfo,
+ pSamplingRateInfo, flags);
+
+ if (elFlags & AC_EL_LFE &&
+ GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) !=
+ BLOCK_LONG) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+
+ if (numberOfChannels == 2 &&
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) {
+ pAacDecoderChannelInfo[1]->icsInfo =
+ pAacDecoderChannelInfo[0]->icsInfo;
+ }
+ break;
+
+ case common_max_sfb:
+ if (FDKreadBit(hBs) == 0) {
+ error = IcsReadMaxSfb(hBs, &pAacDecoderChannelInfo[1]->icsInfo,
+ pSamplingRateInfo);
+ }
+ break;
+
+ case ltp_data_present:
+ if (FDKreadBits(hBs, 1) != 0) {
+ error = AAC_DEC_UNSUPPORTED_PREDICTION;
+ }
+ break;
+
+ case ms:
+
+ INT max_sfb_ste;
+ INT max_sfb_ste_clear;
+
+ max_sfb_ste = GetScaleMaxFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[0]->icsInfo,
+ &pAacDecoderChannelInfo[1]->icsInfo);
+
+ max_sfb_ste_clear = 64;
+
+ pAacDecoderChannelInfo[0]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
+ pAacDecoderChannelInfo[1]->icsInfo.max_sfb_ste = (UCHAR)max_sfb_ste;
+
+ if (flags & (AC_USAC | AC_RSV603DA) &&
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.CommonWindow ==
+ 0) {
+ Clean_Complex_Prediction_coefficients(
+ &pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData,
+ GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo), 0, 64);
+ }
+
+ if (CJointStereo_Read(
+ hBs, &pAacDecoderChannelInfo[0]->pComData->jointStereoData,
+ GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo),
+ max_sfb_ste, max_sfb_ste_clear,
+ /* jointStereoPersistentData and cplxPredictionData are only
+ available/allocated if cplxPred is active. */
+ ((cplxPred == 0) || (pAacDecoderStaticChannelInfo == NULL))
+ ? NULL
+ : &pAacDecoderStaticChannelInfo[0]
+ ->pCpeStaticData->jointStereoPersistentData,
+ ((cplxPred == 0) || (pAacDecoderChannelInfo[0] == NULL))
+ ? NULL
+ : pAacDecoderChannelInfo[0]
+ ->pComStaticData->cplxPredictionData,
+ cplxPred,
+ GetScaleFactorBandsTotal(&pAacDecoderChannelInfo[0]->icsInfo),
+ GetWindowSequence(&pAacDecoderChannelInfo[0]->icsInfo),
+ flags)) {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+
+ break;
+
+ case global_gain:
+ pAacDecoderChannelInfo[ch]->pDynData->RawDataInfo.GlobalGain =
+ (UCHAR)FDKreadBits(hBs, 8);
+ break;
+
+ case section_data:
+ error = CBlock_ReadSectionData(hBs, pAacDecoderChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ break;
+
+ case scale_factor_data_usac:
+ pAacDecoderChannelInfo[ch]->currAliasingSymmetry = 0;
+ /* Set active sfb codebook indexes to HCB_ESC to make them "active" */
+ CChannel_CodebookTableInit(
+ pAacDecoderChannelInfo[ch]); /* equals ReadSectionData(self,
+ bs) in float soft. block.c
+ line: ~599 */
+ /* Note: The missing "break" is intentional here, since we need to call
+ * CBlock_ReadScaleFactorData(). */
+ FDK_FALLTHROUGH;
+
+ case scale_factor_data:
+ if (flags & AC_ER_RVLC) {
+ /* read RVLC data from bitstream (error sens. cat. 1) */
+ CRvlc_Read(pAacDecoderChannelInfo[ch], hBs);
+ } else {
+ error = CBlock_ReadScaleFactorData(pAacDecoderChannelInfo[ch], hBs,
+ flags);
+ }
+ break;
+
+ case pulse:
+ if (CPulseData_Read(
+ hBs,
+ &pAacDecoderChannelInfo[ch]->pDynData->specificTo.aac.PulseData,
+ pSamplingRateInfo->ScaleFactorBands_Long, /* pulse data is only
+ allowed to be
+ present in long
+ blocks! */
+ (void *)&pAacDecoderChannelInfo[ch]->icsInfo,
+ frame_length) != 0) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ break;
+ case tns_data_present:
+ CTns_ReadDataPresentFlag(
+ hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData);
+ if (elFlags & AC_EL_LFE &&
+ pAacDecoderChannelInfo[ch]->pDynData->TnsData.DataPresent) {
+ error = AAC_DEC_PARSE_ERROR;
+ }
+ break;
+ case tns_data:
+ /* tns_data_present is checked inside CTns_Read(). */
+ error = CTns_Read(hBs, &pAacDecoderChannelInfo[ch]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[ch]->icsInfo, flags);
+
+ break;
+
+ case gain_control_data:
+ break;
+
+ case gain_control_data_present:
+ if (FDKreadBits(hBs, 1)) {
+ error = AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA;
+ }
+ break;
+
+ case tw_data:
+ break;
+ case common_tw:
+ break;
+ case tns_data_present_usac:
+ if (pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active) {
+ CTns_ReadDataPresentUsac(
+ hBs, &pAacDecoderChannelInfo[0]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[1]->pDynData->TnsData,
+ &pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr,
+ &pAacDecoderChannelInfo[0]->icsInfo, flags, elFlags,
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow);
+ } else {
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_on_lr =
+ (UCHAR)1;
+ }
+ break;
+ case core_mode:
+ decision_bit = FDKreadBits(hBs, 1);
+ pAacDecoderChannelInfo[ch]->data.usac.core_mode = decision_bit;
+ if ((ch == 1) && (pAacDecoderChannelInfo[0]->data.usac.core_mode !=
+ pAacDecoderChannelInfo[1]->data.usac.core_mode)) {
+ /* StereoCoreToolInfo(core_mode[ch] ) */
+ pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 0;
+ pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = 0;
+ }
+ break;
+ case tns_active:
+ pAacDecoderChannelInfo[0]->pDynData->specificTo.usac.tns_active =
+ FDKreadBit(hBs);
+ break;
+ case noise:
+ if (elFlags & AC_EL_USAC_NOISE) {
+ pAacDecoderChannelInfo[ch]
+ ->pDynData->specificTo.usac.fd_noise_level_and_offset =
+ FDKreadBits(hBs, 3 + 5); /* Noise level */
+ }
+ break;
+ case lpd_channel_stream:
+
+ {
+ error = CLpdChannelStream_Read(/* = lpd_channel_stream() */
+ hBs, pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ }
+
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_LPD;
+ break;
+ case fac_data: {
+ int fFacDatPresent = FDKreadBit(hBs);
+
+ /* Wee need a valid fac_data[0] even if no FAC data is present (as
+ * temporal buffer) */
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data[0] =
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data0;
+
+ if (fFacDatPresent) {
+ if (elFlags & AC_EL_LFE) {
+ error = AAC_DEC_PARSE_ERROR;
+ break;
+ }
+ /* FAC data present, this frame is FD, so the last mode had to be
+ * ACELP. */
+ if (pAacDecoderStaticChannelInfo[ch]->last_core_mode != LPD ||
+ pAacDecoderStaticChannelInfo[ch]->last_lpd_mode != 0) {
+ pAacDecoderChannelInfo[ch]->data.usac.core_mode_last = LPD;
+ pAacDecoderChannelInfo[ch]->data.usac.lpd_mode_last = 0;
+ /* We can't change the past! So look to the future and go ahead! */
+ }
+ CLpd_FAC_Read(hBs, pAacDecoderChannelInfo[ch]->data.usac.fac_data[0],
+ pAacDecoderChannelInfo[ch]->data.usac.fac_data_e,
+ CLpd_FAC_getLength(
+ IsLongBlock(&pAacDecoderChannelInfo[ch]->icsInfo),
+ pAacDecoderChannelInfo[ch]->granuleLength),
+ 1, 0);
+ } else {
+ if (pAacDecoderStaticChannelInfo[ch]->last_core_mode == LPD &&
+ pAacDecoderStaticChannelInfo[ch]->last_lpd_mode == 0) {
+ /* ACELP to FD transitons without FAC are possible. That is why we
+ zero it out (i.e FAC will not be considered in the subsequent
+ calculations */
+ FDKmemclear(pAacDecoderChannelInfo[ch]->data.usac.fac_data0,
+ LFAC * sizeof(FIXP_DBL));
+ }
+ }
+ } break;
+ case esc2_rvlc:
+ if (flags & AC_ER_RVLC) {
+ CRvlc_Decode(pAacDecoderChannelInfo[ch],
+ pAacDecoderStaticChannelInfo[ch], hBs);
+ }
+ break;
+
+ case esc1_hcr:
+ if (flags & AC_ER_HCR) {
+ CHcr_Read(hBs, pAacDecoderChannelInfo[ch],
+ numberOfChannels == 2 ? ID_CPE : ID_SCE);
+ }
+ break;
+
+ case spectral_data:
+ error = CBlock_ReadSpectralData(hBs, pAacDecoderChannelInfo[ch],
+ pSamplingRateInfo, flags);
+ if (flags & AC_ELD) {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_ELDFB;
+ } else {
+ if (flags & AC_HDAAC) {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_INTIMDCT;
+ } else {
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
+ }
+ }
+ break;
+
+ case ac_spectral_data:
+ error = CBlock_ReadAcSpectralData(
+ hBs, pAacDecoderChannelInfo[ch], pAacDecoderStaticChannelInfo[ch],
+ pSamplingRateInfo, frame_length, flags);
+ pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_IMDCT;
+ break;
+
+ case coupled_elements: {
+ int num_coupled_elements, c;
+
+ ind_sw_cce_flag = FDKreadBit(hBs);
+ num_coupled_elements = FDKreadBits(hBs, 3);
+
+ for (c = 0; c < (num_coupled_elements + 1); c++) {
+ int cc_target_is_cpe;
+
+ num_gain_element_lists++;
+ cc_target_is_cpe = FDKreadBit(hBs); /* cc_target_is_cpe[c] */
+ FDKreadBits(hBs, 4); /* cc_target_tag_select[c] */
+
+ if (cc_target_is_cpe) {
+ int cc_l, cc_r;
+
+ cc_l = FDKreadBit(hBs); /* cc_l[c] */
+ cc_r = FDKreadBit(hBs); /* cc_r[c] */
+
+ if (cc_l && cc_r) {
+ num_gain_element_lists++;
+ }
+ }
+ }
+ FDKreadBit(hBs); /* cc_domain */
+ FDKreadBit(hBs); /* gain_element_sign */
+ FDKreadBits(hBs, 2); /* gain_element_scale */
+ } break;
+
+ case gain_element_lists: {
+ const CodeBookDescription *hcb;
+ UCHAR *pCodeBook;
+ int c;
+
+ hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+ pCodeBook = pAacDecoderChannelInfo[ch]->pDynData->aCodeBook;
+
+ for (c = 1; c < num_gain_element_lists; c++) {
+ int cge;
+ if (ind_sw_cce_flag) {
+ cge = 1;
+ } else {
+ cge = FDKreadBits(hBs, 1); /* common_gain_element_present[c] */
+ }
+ if (cge) {
+ /* Huffman */
+ CBlock_DecodeHuffmanWord(
+ hBs, hcb); /* hcod_sf[common_gain_element[c]] 1..19 */
+ } else {
+ int g, sfb;
+ for (g = 0;
+ g < GetWindowGroups(&pAacDecoderChannelInfo[ch]->icsInfo);
+ g++) {
+ for (sfb = 0; sfb < GetScaleFactorBandsTransmitted(
+ &pAacDecoderChannelInfo[ch]->icsInfo);
+ sfb++) {
+ if (pCodeBook[sfb] != ZERO_HCB) {
+ /* Huffman */
+ CBlock_DecodeHuffmanWord(
+ hBs,
+ hcb); /* hcod_sf[dpcm_gain_element[c][g][sfb]] 1..19 */
+ }
+ }
+ }
+ }
+ }
+ } break;
+
+ /* CRC handling */
+ case adtscrc_start_reg1:
+ if (pTpDec != NULL) {
+ crcReg1 = transportDec_CrcStartReg(pTpDec, 192);
+ }
+ break;
+ case adtscrc_start_reg2:
+ if (pTpDec != NULL) {
+ crcReg2 = transportDec_CrcStartReg(pTpDec, 128);
+ }
+ break;
+ case adtscrc_end_reg1:
+ case drmcrc_end_reg:
+ if (pTpDec != NULL) {
+ transportDec_CrcEndReg(pTpDec, crcReg1);
+ crcReg1 = -1;
+ }
+ break;
+ case adtscrc_end_reg2:
+ if (crcReg1 != -1) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ } else if (pTpDec != NULL) {
+ transportDec_CrcEndReg(pTpDec, crcReg2);
+ crcReg2 = -1;
+ }
+ break;
+ case drmcrc_start_reg:
+ if (pTpDec != NULL) {
+ crcReg1 = transportDec_CrcStartReg(pTpDec, 0);
+ }
+ break;
+
+ /* Non data cases */
+ case next_channel:
+ ch = (ch + 1) % numberOfChannels;
+ break;
+ case link_sequence:
+ list = list->next[decision_bit];
+ i = -1;
+ break;
+
+ default:
+ error = AAC_DEC_UNSUPPORTED_FORMAT;
+ break;
+ }
+
+ if (error != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ i++;
+
+ } while (list->id[i] != end_of_sequence);
+
+ for (ch = 0; ch < numberOfChannels; ch++) {
+ if (pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_IMDCT ||
+ pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_ELDFB) {
+ /* Shows which bands are empty. */
+ UCHAR *band_is_noise =
+ pAacDecoderChannelInfo[ch]->pDynData->band_is_noise;
+ FDKmemset(band_is_noise, (UCHAR)1, sizeof(UCHAR) * (8 * 16));
+
+ error = CBlock_InverseQuantizeSpectralData(
+ pAacDecoderChannelInfo[ch], pSamplingRateInfo, band_is_noise, 1);
+ if (error != AAC_DEC_OK) {
+ return error;
+ }
+
+ if (elFlags & AC_EL_USAC_NOISE) {
+ CBlock_ApplyNoise(pAacDecoderChannelInfo[ch], pSamplingRateInfo,
+ &pAacDecoderStaticChannelInfo[ch]->nfRandomSeed,
+ band_is_noise);
+
+ } /* if (elFlags & AC_EL_USAC_NOISE) */
+ }
+ }
+
+bail:
+ if (crcReg1 != -1 || crcReg2 != -1) {
+ if (error == AAC_DEC_OK) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ if (crcReg1 != -1) {
+ transportDec_CrcEndReg(pTpDec, crcReg1);
+ }
+ if (crcReg2 != -1) {
+ transportDec_CrcEndReg(pTpDec, crcReg2);
+ }
+ }
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/channel.h b/fdk-aac/libAACdec/src/channel.h
new file mode 100644
index 0000000..ed46666
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channel.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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef CHANNEL_H
+#define CHANNEL_H
+
+#include "common_fix.h"
+
+#include "FDK_tools_rom.h"
+#include "channelinfo.h"
+#include "tpdec_lib.h"
+
+/**
+ * \brief Init codeBook SFB indices (section data) with HCB_ESC. Useful for
+ * bitstreams which do not have any section data, but still SFB's (scale factor
+ * bands). This has the effect that upto the amount of transmitted SFB are
+ * treated as non-zero.
+ * \param pAacDecoderChannelInfo channel info structure containing a valid
+ * icsInfo struct.
+ */
+void CChannel_CodebookTableInit(CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+/**
+ * \brief decode a channel element. To be called after CChannelElement_Read()
+ * \param pAacDecoderChannelInfo pointer to channel data struct. Depending on
+ * el_channels either one or two.
+ * \param pSamplingRateInfo pointer to sample rate information structure
+ * \param el_channels amount of channels of the element to be decoded.
+ * \param output pointer to time domain output buffer (ACELP)
+ */
+void CChannelElement_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ SamplingRateInfo *pSamplingRateInfo, UINT flags, UINT elFlags,
+ int el_channels);
+
+/**
+ * \brief Read channel element of given type from bitstream.
+ * \param hBs bitstream handle to access bitstream data.
+ * \param pAacDecoderChannelInfo pointer array to store channel information.
+ * \param aot Audio Object Type
+ * \param pSamplingRateInfo sampling rate info table.
+ * \param flags common parser guidance flags
+ * \param elFlags element specific parser guidance flags
+ * \param numberOfChannels amoun of channels contained in the object to be
+ * parsed.
+ * \param epConfig the current epConfig value obtained from the Audio Specific
+ * Config.
+ * \param pTp transport decoder handle required for ADTS CRC checking.
+ * ...
+ * \return an AAC_DECODER_ERROR error code.
+ */
+AAC_DECODER_ERROR CChannelElement_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const AUDIO_OBJECT_TYPE aot, SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags, const UINT elFlags, const UINT frame_length,
+ const UCHAR numberOfChannels, const SCHAR epConfig,
+ HANDLE_TRANSPORTDEC pTpDec);
+
+#endif /* #ifndef CHANNEL_H */
diff --git a/fdk-aac/libAACdec/src/channelinfo.cpp b/fdk-aac/libAACdec/src/channelinfo.cpp
new file mode 100644
index 0000000..79add5b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channelinfo.cpp
@@ -0,0 +1,297 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: individual channel stream info
+
+*******************************************************************************/
+
+#include "channelinfo.h"
+#include "aac_rom.h"
+#include "aac_ram.h"
+#include "FDK_bitstream.h"
+
+AAC_DECODER_ERROR IcsReadMaxSfb(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+ int nbits;
+
+ if (IsLongBlock(pIcsInfo)) {
+ nbits = 6;
+ pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ } else {
+ nbits = 4;
+ pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ }
+ pIcsInfo->MaxSfBands = (UCHAR)FDKreadBits(bs, nbits);
+
+ if (pIcsInfo->MaxSfBands > pIcsInfo->TotalSfBands) {
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ }
+
+ return ErrorStatus;
+}
+
+AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo,
+ const UINT flags) {
+ AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
+
+ pIcsInfo->Valid = 0;
+
+ if (flags & AC_ELD) {
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+ pIcsInfo->WindowShape = 0;
+ } else {
+ if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) {
+ FDKreadBits(bs, 1);
+ }
+ pIcsInfo->WindowSequence = (BLOCK_TYPE)FDKreadBits(bs, 2);
+ pIcsInfo->WindowShape = (UCHAR)FDKreadBits(bs, 1);
+ if (flags & AC_LD) {
+ if (pIcsInfo->WindowShape) {
+ pIcsInfo->WindowShape = 2; /* select low overlap instead of KBD */
+ }
+ }
+ }
+
+ /* Sanity check */
+ if ((flags & (AC_ELD | AC_LD)) && pIcsInfo->WindowSequence != BLOCK_LONG) {
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+ ErrorStatus = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ ErrorStatus = IcsReadMaxSfb(bs, pIcsInfo, pSamplingRateInfo);
+ if (ErrorStatus != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ if (IsLongBlock(pIcsInfo)) {
+ if (!(flags & (AC_ELD | AC_SCALABLE | AC_BSAC | AC_USAC | AC_RSVD50 |
+ AC_RSV603DA))) /* If not ELD nor Scalable nor BSAC nor USAC
+ syntax then ... */
+ {
+ if ((UCHAR)FDKreadBits(bs, 1) != 0) /* UCHAR PredictorDataPresent */
+ {
+ ErrorStatus = AAC_DEC_UNSUPPORTED_PREDICTION;
+ goto bail;
+ }
+ }
+
+ pIcsInfo->WindowGroups = 1;
+ pIcsInfo->WindowGroupLength[0] = 1;
+ } else {
+ INT i;
+ UINT mask;
+
+ pIcsInfo->ScaleFactorGrouping = (UCHAR)FDKreadBits(bs, 7);
+
+ pIcsInfo->WindowGroups = 0;
+
+ for (i = 0; i < (8 - 1); i++) {
+ mask = 1 << (6 - i);
+ pIcsInfo->WindowGroupLength[i] = 1;
+
+ if (pIcsInfo->ScaleFactorGrouping & mask) {
+ pIcsInfo->WindowGroupLength[pIcsInfo->WindowGroups]++;
+ } else {
+ pIcsInfo->WindowGroups++;
+ }
+ }
+
+ /* loop runs to i < 7 only */
+ pIcsInfo->WindowGroupLength[8 - 1] = 1;
+ pIcsInfo->WindowGroups++;
+ }
+
+bail:
+ if (ErrorStatus == AAC_DEC_OK) pIcsInfo->Valid = 1;
+
+ return ErrorStatus;
+}
+
+/*
+ interleave codebooks the following way
+
+ 9 (84w) | 1 (51w)
+ 10 (82w) | 2 (39w)
+ SCL (65w) | 4 (38w)
+ 3 (39w) | 5 (41w)
+ | 6 (40w)
+ | 7 (31w)
+ | 8 (31w)
+ (270w) (271w)
+*/
+
+/*
+ Table entries are sorted as following:
+ | num_swb_long_window | sfbands_long | num_swb_short_window | sfbands_short |
+*/
+AAC_DECODER_ERROR getSamplingRateInfo(SamplingRateInfo *t, UINT samplesPerFrame,
+ UINT samplingRateIndex,
+ UINT samplingRate) {
+ int index = 0;
+
+ /* Search closest samplerate according to ISO/IEC 13818-7:2005(E) 8.2.4 (Table
+ * 38): */
+ if ((samplingRateIndex >= 15) || (samplesPerFrame == 768)) {
+ const UINT borders[] = {(UINT)-1, 92017, 75132, 55426, 46009, 37566,
+ 27713, 23004, 18783, 13856, 11502, 9391};
+ UINT i, samplingRateSearch = samplingRate;
+
+ if (samplesPerFrame == 768) {
+ samplingRateSearch = (samplingRate * 4) / 3;
+ }
+
+ for (i = 0; i < 11; i++) {
+ if (borders[i] > samplingRateSearch &&
+ samplingRateSearch >= borders[i + 1]) {
+ break;
+ }
+ }
+ samplingRateIndex = i;
+ }
+
+ t->samplingRateIndex = samplingRateIndex;
+ t->samplingRate = samplingRate;
+
+ switch (samplesPerFrame) {
+ case 1024:
+ index = 0;
+ break;
+ case 960:
+ index = 1;
+ break;
+ case 768:
+ index = 2;
+ break;
+ case 512:
+ index = 3;
+ break;
+ case 480:
+ index = 4;
+ break;
+
+ default:
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
+
+ t->ScaleFactorBands_Long =
+ sfbOffsetTables[index][samplingRateIndex].sfbOffsetLong;
+ t->ScaleFactorBands_Short =
+ sfbOffsetTables[index][samplingRateIndex].sfbOffsetShort;
+ t->NumberOfScaleFactorBands_Long =
+ sfbOffsetTables[index][samplingRateIndex].numberOfSfbLong;
+ t->NumberOfScaleFactorBands_Short =
+ sfbOffsetTables[index][samplingRateIndex].numberOfSfbShort;
+
+ if (t->ScaleFactorBands_Long == NULL ||
+ t->NumberOfScaleFactorBands_Long == 0) {
+ t->samplingRate = 0;
+ return AAC_DEC_UNSUPPORTED_FORMAT;
+ }
+
+ FDK_ASSERT((UINT)t->ScaleFactorBands_Long[t->NumberOfScaleFactorBands_Long] ==
+ samplesPerFrame);
+ FDK_ASSERT(
+ t->ScaleFactorBands_Short == NULL ||
+ (UINT)t->ScaleFactorBands_Short[t->NumberOfScaleFactorBands_Short] * 8 ==
+ samplesPerFrame);
+
+ return AAC_DEC_OK;
+}
diff --git a/fdk-aac/libAACdec/src/channelinfo.h b/fdk-aac/libAACdec/src/channelinfo.h
new file mode 100644
index 0000000..4523400
--- /dev/null
+++ b/fdk-aac/libAACdec/src/channelinfo.h
@@ -0,0 +1,564 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: individual channel stream info
+
+*******************************************************************************/
+
+#ifndef CHANNELINFO_H
+#define CHANNELINFO_H
+
+#include "common_fix.h"
+
+#include "aac_rom.h"
+#include "aacdecoder_lib.h"
+#include "FDK_bitstream.h"
+#include "overlapadd.h"
+
+#include "mdct.h"
+#include "stereo.h"
+#include "pulsedata.h"
+#include "aacdec_tns.h"
+
+#include "aacdec_pns.h"
+
+#include "aacdec_hcr_types.h"
+#include "rvlc_info.h"
+
+#include "usacdec_acelp.h"
+#include "usacdec_const.h"
+#include "usacdec_rom.h"
+
+#include "ac_arith_coder.h"
+
+#include "conceal_types.h"
+
+#include "aacdec_drc_types.h"
+
+#define WB_SECTION_SIZE (1024 * 2)
+
+#define DRM_BS_BUFFER_SIZE \
+ (512) /* size of the dynamic buffer which is used to reverse the bits of \
+ the DRM SBR payload */
+
+/* Output rendering mode */
+typedef enum {
+ AACDEC_RENDER_INVALID = 0,
+ AACDEC_RENDER_IMDCT,
+ AACDEC_RENDER_ELDFB,
+ AACDEC_RENDER_LPD,
+ AACDEC_RENDER_INTIMDCT
+} AACDEC_RENDER_MODE;
+
+enum { MAX_QUANTIZED_VALUE = 8191 };
+
+typedef enum { FD_LONG, FD_SHORT, LPD } USAC_COREMODE;
+
+typedef struct {
+ const SHORT *ScaleFactorBands_Long;
+ const SHORT *ScaleFactorBands_Short;
+ UCHAR NumberOfScaleFactorBands_Long;
+ UCHAR NumberOfScaleFactorBands_Short;
+ UINT samplingRateIndex;
+ UINT samplingRate;
+} SamplingRateInfo;
+
+typedef struct {
+ UCHAR CommonWindow;
+ UCHAR GlobalGain;
+
+} CRawDataInfo;
+
+typedef struct {
+ UCHAR WindowGroupLength[8];
+ UCHAR WindowGroups;
+ UCHAR Valid;
+
+ UCHAR WindowShape; /* 0: sine window, 1: KBD, 2: low overlap */
+ BLOCK_TYPE WindowSequence; /* mdct.h; 0: long, 1: start, 2: short, 3: stop */
+ UCHAR MaxSfBands;
+ UCHAR max_sfb_ste;
+ UCHAR ScaleFactorGrouping;
+
+ UCHAR TotalSfBands;
+
+} CIcsInfo;
+
+enum {
+ ZERO_HCB = 0,
+ ESCBOOK = 11,
+ NSPECBOOKS = ESCBOOK + 1,
+ BOOKSCL = NSPECBOOKS,
+ NOISE_HCB = 13,
+ INTENSITY_HCB2 = 14,
+ INTENSITY_HCB = 15,
+ LAST_HCB
+};
+
+/* This struct holds the persistent data shared by both channels of a CPE.
+ It needs to be allocated for each CPE. */
+typedef struct {
+ CJointStereoPersistentData jointStereoPersistentData;
+} CpePersistentData;
+
+/*
+ * This struct must be allocated one for every channel and must be persistent.
+ */
+typedef struct {
+ FIXP_DBL *pOverlapBuffer;
+ mdct_t IMdct;
+
+ CArcoData *hArCo;
+
+ INT pnsCurrentSeed;
+
+ /* LPD memory */
+ FIXP_DBL old_synth[PIT_MAX_MAX - L_SUBFR];
+ INT old_T_pf[SYN_SFD];
+ FIXP_DBL old_gain_pf[SYN_SFD];
+ FIXP_DBL mem_bpf[L_FILT + L_SUBFR];
+ UCHAR
+ old_bpf_control_info; /* (1: enable, 0: disable) bpf for past superframe
+ */
+
+ USAC_COREMODE last_core_mode; /* core mode used by the decoder in previous
+ frame. (not signalled by the bitstream, see
+ CAacDecoderChannelInfo::core_mode_last !! )
+ */
+ UCHAR last_lpd_mode; /* LPD mode used by the decoder in last LPD subframe
+ (not signalled by the bitstream, see
+ CAacDecoderChannelInfo::lpd_mode_last !! ) */
+ UCHAR last_last_lpd_mode; /* LPD mode used in second last LPD subframe
+ (not signalled by the bitstream) */
+ UCHAR last_lpc_lost; /* Flag indicating that the previous LPC is lost */
+
+ FIXP_LPC
+ lpc4_lsf[M_LP_FILTER_ORDER]; /* Last LPC4 coefficients in LSF domain. */
+ FIXP_LPC lsf_adaptive_mean[M_LP_FILTER_ORDER]; /* Adaptive mean of LPC
+ coefficients in LSF domain
+ for concealment. */
+ FIXP_LPC lp_coeff_old[2][M_LP_FILTER_ORDER]; /* Last LPC coefficients in LP
+ domain. lp_coeff_old[0] is lpc4 (coeffs for
+ right folding point of last tcx frame),
+ lp_coeff_old[1] are coeffs for left folding
+ point of last tcx frame */
+ INT lp_coeff_old_exp[2];
+
+ FIXP_SGL
+ oldStability; /* LPC coeff stability value from last frame (required for
+ TCX concealment). */
+ UINT numLostLpdFrames; /* Number of consecutive lost subframes. */
+
+ /* TCX memory */
+ FIXP_DBL last_tcx_gain;
+ INT last_tcx_gain_e;
+ FIXP_DBL last_alfd_gains[32]; /* Scaled by one bit. */
+ SHORT last_tcx_pitch;
+ UCHAR last_tcx_noise_factor;
+
+ /* ACELP memory */
+ CAcelpStaticMem acelp;
+
+ ULONG nfRandomSeed; /* seed value for USAC noise filling random generator */
+
+ CDrcChannelData drcData;
+ CConcealmentInfo concealmentInfo;
+
+ CpePersistentData *pCpeStaticData;
+
+} CAacDecoderStaticChannelInfo;
+
+/*
+ * This union must be allocated for every element (up to 2 channels).
+ */
+typedef struct {
+ /* Common bit stream data */
+ SHORT aScaleFactor[(
+ 8 * 16)]; /* Spectral scale factors for each sfb in each window. */
+ SHORT aSfbScale[(8 * 16)]; /* could be free after ApplyTools() */
+ UCHAR
+ aCodeBook[(8 * 16)]; /* section data: codebook for each window and sfb. */
+ UCHAR band_is_noise[(8 * 16)];
+ CTnsData TnsData;
+ CRawDataInfo RawDataInfo;
+
+ shouldBeUnion {
+ struct {
+ CPulseData PulseData;
+ SHORT aNumLineInSec4Hcr[MAX_SFB_HCR]; /* needed once for all channels
+ except for Drm syntax */
+ UCHAR
+ aCodeBooks4Hcr[MAX_SFB_HCR]; /* needed once for all channels except for
+ Drm syntax. Same as "aCodeBook" ? */
+ SHORT lenOfReorderedSpectralData;
+ SCHAR lenOfLongestCodeword;
+ SCHAR numberSection;
+ SCHAR rvlcCurrentScaleFactorOK;
+ SCHAR rvlcIntensityUsed;
+ } aac;
+ struct {
+ UCHAR fd_noise_level_and_offset;
+ UCHAR tns_active;
+ UCHAR tns_on_lr;
+ UCHAR tcx_noise_factor[4];
+ UCHAR tcx_global_gain[4];
+ } usac;
+ }
+ specificTo;
+
+} CAacDecoderDynamicData;
+
+typedef shouldBeUnion {
+ UCHAR DrmBsBuffer[DRM_BS_BUFFER_SIZE];
+
+ /* Common signal data, can be used once the bit stream data from above is not
+ * used anymore. */
+ FIXP_DBL mdctOutTemp[1024];
+
+ FIXP_DBL synth_buf[(PIT_MAX_MAX + SYN_DELAY + L_FRAME_PLUS)];
+
+ FIXP_DBL workBuffer[WB_SECTION_SIZE];
+}
+CWorkBufferCore1;
+
+/* Common data referenced by all channels */
+typedef struct {
+ CAacDecoderDynamicData pAacDecoderDynamicData[2];
+
+ CPnsInterChannelData pnsInterChannelData;
+ INT pnsRandomSeed[(8 * 16)];
+
+ CJointStereoData jointStereoData; /* One for one element */
+
+ shouldBeUnion {
+ struct {
+ CErHcrInfo erHcrInfo;
+ CErRvlcInfo erRvlcInfo;
+ SHORT aRvlcScfEsc[RVLC_MAX_SFB]; /* needed once for all channels */
+ SHORT aRvlcScfFwd[RVLC_MAX_SFB]; /* needed once for all channels */
+ SHORT aRvlcScfBwd[RVLC_MAX_SFB]; /* needed once for all channels */
+ } aac;
+ }
+ overlay;
+
+} CAacDecoderCommonData;
+
+typedef struct {
+ CWorkBufferCore1 *pWorkBufferCore1;
+ CCplxPredictionData *cplxPredictionData;
+} CAacDecoderCommonStaticData;
+
+/*
+ * This struct must be allocated one for every channel of every element and must
+ * be persistent. Among its members, the following memory areas can be
+ * overwritten under the given conditions:
+ * - pSpectralCoefficient The memory pointed to can be overwritten after time
+ * signal rendering.
+ * - data can be overwritten after time signal rendering.
+ * - pDynData memory pointed to can be overwritten after each
+ * CChannelElement_Decode() call.
+ * - pComData->overlay memory pointed to can be overwritten after each
+ * CChannelElement_Decode() call..
+ */
+typedef struct {
+ shouldBeUnion {
+ struct {
+ FIXP_DBL fac_data0[LFAC];
+ SCHAR fac_data_e[4];
+ FIXP_DBL
+ *fac_data[4]; /* Pointers to unused parts of pSpectralCoefficient */
+
+ UCHAR core_mode; /* current core mode */
+ USAC_COREMODE
+ core_mode_last; /* previous core mode, signalled in the bitstream
+ (not done by the decoder, see
+ CAacDecoderStaticChannelInfo::last_core_mode !!)*/
+ UCHAR lpd_mode_last; /* previous LPD mode, signalled in the bitstream
+ (not done by the decoder, see
+ CAacDecoderStaticChannelInfo::last_core_mode !!)*/
+ UCHAR mod[4];
+ UCHAR bpf_control_info; /* (1: enable, 0: disable) bpf for current
+ superframe */
+
+ FIXP_LPC lsp_coeff[5][M_LP_FILTER_ORDER]; /* linear prediction
+ coefficients in LSP domain */
+ FIXP_LPC
+ lp_coeff[5][M_LP_FILTER_ORDER]; /* linear prediction coefficients in
+ LP domain */
+ INT lp_coeff_exp[5];
+ FIXP_LPC lsf_adaptive_mean_cand
+ [M_LP_FILTER_ORDER]; /* concealment: is copied to
+ CAacDecoderStaticChannelInfo->lsf_adaptive_mean once frame is
+ assumed to be correct*/
+ FIXP_SGL aStability[4]; /* LPC coeff stability values required for ACELP
+ and TCX (concealment) */
+
+ CAcelpChannelData acelp[4];
+
+ FIXP_DBL tcx_gain[4];
+ SCHAR tcx_gain_e[4];
+ } usac;
+
+ struct {
+ CPnsData PnsData; /* Not required for USAC */
+ } aac;
+ }
+ data;
+
+ SPECTRAL_PTR pSpectralCoefficient; /* Spectral coefficients of each window */
+ SHORT specScale[8]; /* Scale shift values of each spectrum window */
+ CIcsInfo icsInfo;
+ INT granuleLength; /* Size of smallest spectrum piece */
+ UCHAR ElementInstanceTag;
+
+ AACDEC_RENDER_MODE renderMode; /* Output signal rendering mode */
+
+ CAacDecoderDynamicData *
+ pDynData; /* Data required for one element and discarded after decoding */
+ CAacDecoderCommonData
+ *pComData; /* Data required for one channel at a time during decode */
+ CAacDecoderCommonStaticData *pComStaticData; /* Persistent data required for
+ one channel at a time during
+ decode */
+
+ int currAliasingSymmetry; /* required for RSVD60 MCT */
+
+} CAacDecoderChannelInfo;
+
+/* channelinfo.cpp */
+
+AAC_DECODER_ERROR getSamplingRateInfo(SamplingRateInfo *t, UINT samplesPerFrame,
+ UINT samplingRateIndex,
+ UINT samplingRate);
+
+/**
+ * \brief Read max SFB from bit stream and assign TotalSfBands according
+ * to the window sequence and sample rate.
+ * \param hBs bit stream handle as data source
+ * \param pIcsInfo IcsInfo structure to read the window sequence and store
+ * MaxSfBands and TotalSfBands
+ * \param pSamplingRateInfo read only
+ */
+AAC_DECODER_ERROR IcsReadMaxSfb(HANDLE_FDK_BITSTREAM hBs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *pSamplingRateInfo);
+
+AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo,
+ const SamplingRateInfo *SamplingRateInfoTable,
+ const UINT flags);
+
+/* stereo.cpp, only called from this file */
+
+/*!
+ \brief Applies MS stereo.
+
+ The function applies MS stereo.
+
+ \param pAacDecoderChannelInfo aac channel info.
+ \param pScaleFactorBandOffsets pointer to scalefactor band offsets.
+ \param pWindowGroupLength pointer to window group length array.
+ \param windowGroups number of window groups.
+ \param scaleFactorBandsTransmittedL number of transmitted scalefactor bands in
+ left channel. \param scaleFactorBandsTransmittedR number of transmitted
+ scalefactor bands in right channel. May differ from
+ scaleFactorBandsTransmittedL only for USAC. \return none
+*/
+void CJointStereo_ApplyMS(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale,
+ SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR,
+ const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength,
+ const int windowGroups, const int max_sfb_ste_outside,
+ const int scaleFactorBandsTransmittedL,
+ const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev,
+ SHORT *store_dmx_re_prev_e, const int mainband_flag);
+
+/*!
+ \brief Applies intensity stereo
+
+ The function applies intensity stereo.
+
+ \param pAacDecoderChannelInfo aac channel info.
+ \param pScaleFactorBandOffsets pointer to scalefactor band offsets.
+ \param pWindowGroupLength pointer to window group length array.
+ \param windowGroups number of window groups.
+ \param scaleFactorBandsTransmitted number of transmitted scalefactor bands.
+ \return none
+*/
+void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ const short *pScaleFactorBandOffsets,
+ const UCHAR *pWindowGroupLength,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted);
+
+/* aacdec_pns.cpp */
+int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band);
+
+void CPns_SetCorrelation(CPnsData *pPnsData, const int group, const int band,
+ const int outofphase);
+
+/****************** inline functions ******************/
+
+inline UCHAR IsValid(const CIcsInfo *pIcsInfo) { return pIcsInfo->Valid; }
+
+inline UCHAR IsLongBlock(const CIcsInfo *pIcsInfo) {
+ return (pIcsInfo->WindowSequence != BLOCK_SHORT);
+}
+
+inline UCHAR GetWindowShape(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowShape;
+}
+
+inline BLOCK_TYPE GetWindowSequence(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowSequence;
+}
+
+inline const SHORT *GetScaleFactorBandOffsets(
+ const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) {
+ if (IsLongBlock(pIcsInfo)) {
+ return samplingRateInfo->ScaleFactorBands_Long;
+ } else {
+ return samplingRateInfo->ScaleFactorBands_Short;
+ }
+}
+
+inline UCHAR GetNumberOfScaleFactorBands(
+ const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) {
+ if (IsLongBlock(pIcsInfo)) {
+ return samplingRateInfo->NumberOfScaleFactorBands_Long;
+ } else {
+ return samplingRateInfo->NumberOfScaleFactorBands_Short;
+ }
+}
+
+inline int GetWindowsPerFrame(const CIcsInfo *pIcsInfo) {
+ return (pIcsInfo->WindowSequence == BLOCK_SHORT) ? 8 : 1;
+}
+
+inline UCHAR GetWindowGroups(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowGroups;
+}
+
+inline UCHAR GetWindowGroupLength(const CIcsInfo *pIcsInfo, const INT index) {
+ return pIcsInfo->WindowGroupLength[index];
+}
+
+inline const UCHAR *GetWindowGroupLengthTable(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->WindowGroupLength;
+}
+
+inline UCHAR GetScaleFactorBandsTransmitted(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->MaxSfBands;
+}
+
+inline UCHAR GetScaleMaxFactorBandsTransmitted(const CIcsInfo *pIcsInfo0,
+ const CIcsInfo *pIcsInfo1) {
+ return fMax(pIcsInfo0->MaxSfBands, pIcsInfo1->MaxSfBands);
+}
+
+inline UCHAR GetScaleFactorBandsTotal(const CIcsInfo *pIcsInfo) {
+ return pIcsInfo->TotalSfBands;
+}
+
+/* Note: This function applies to AAC-LC only ! */
+inline UCHAR GetMaximumTnsBands(const CIcsInfo *pIcsInfo,
+ const int samplingRateIndex) {
+ return tns_max_bands_tbl[samplingRateIndex][!IsLongBlock(pIcsInfo)];
+}
+
+#endif /* #ifndef CHANNELINFO_H */
diff --git a/fdk-aac/libAACdec/src/conceal.cpp b/fdk-aac/libAACdec/src/conceal.cpp
new file mode 100644
index 0000000..5895cb8
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal.cpp
@@ -0,0 +1,2095 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: independent channel concealment
+
+*******************************************************************************/
+
+/*!
+ \page concealment AAC core concealment
+
+ This AAC core implementation includes a concealment function, which can be
+ enabled using the several defines during compilation.
+
+ There are various tests inside the core, starting with simple CRC tests and
+ ending in a variety of plausibility checks. If such a check indicates an
+ invalid bitstream, then concealment is applied.
+
+ Concealment is also applied when the calling main program indicates a
+ distorted or missing data frame using the frameOK flag. This is used for error
+ detection on the transport layer. (See below)
+
+ There are three concealment-modes:
+
+ 1) Muting: The spectral data is simply set to zero in case of an detected
+ error.
+
+ 2) Noise substitution: In case of an detected error, concealment copies the
+ last frame and adds attenuates the spectral data. For this mode you have to
+ set the #CONCEAL_NOISE define. Noise substitution adds no additional delay.
+
+ 3) Interpolation: The interpolation routine swaps the spectral data from the
+ previous and the current frame just before the final frequency to time
+ conversion. In case a single frame is corrupted, concealmant interpolates
+ between the last good and the first good frame to create the spectral data for
+ the missing frame. If multiple frames are corrupted, concealment implements
+ first a fade out based on slightly modified spectral values from the last good
+ frame. As soon as good frames are available, concealmant fades in the new
+ spectral data. For this mode you have to set the #CONCEAL_INTER define. Note
+ that in this case, you also need to set #SBR_BS_DELAY_ENABLE, which basically
+ adds approriate delay in the SBR decoder. Note that the
+ Interpolating-Concealment increases the delay of your decoder by one frame and
+ that it does require additional resources such as memory and computational
+ complexity.
+
+ <h2>How concealment can be used with errors on the transport layer</h2>
+
+ Many errors can or have to be detected on the transport layer. For example in
+ IP based systems packet loss can occur. The transport protocol used should
+ indicate such packet loss by inserting an empty frame with frameOK=0.
+*/
+
+#include "conceal.h"
+
+#include "aac_rom.h"
+#include "genericStds.h"
+
+/* PNS (of block) */
+#include "aacdec_pns.h"
+#include "block.h"
+
+#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000)
+
+#define CONCEAL_NOT_DEFINED ((UCHAR)-1)
+
+/* default settings */
+#define CONCEAL_DFLT_FADEOUT_FRAMES (6)
+#define CONCEAL_DFLT_FADEIN_FRAMES (5)
+#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0)
+
+#define CONCEAL_DFLT_FADE_FACTOR (0.707106781186548f) /* 1/sqrt(2) */
+
+/* some often used constants: */
+#define FIXP_ZERO FL2FXCONST_DBL(0.0f)
+#define FIXP_ONE FL2FXCONST_DBL(1.0f)
+#define FIXP_FL_CORRECTION FL2FXCONST_DBL(0.53333333333333333f)
+
+/* For parameter conversion */
+#define CONCEAL_PARAMETER_BITS (8)
+#define CONCEAL_MAX_QUANT_FACTOR ((1 << CONCEAL_PARAMETER_BITS) - 1)
+/*#define CONCEAL_MIN_ATTENUATION_FACTOR_025 ( FL2FXCONST_DBL(0.971627951577106174) )*/ /* -0.25 dB */
+#define CONCEAL_MIN_ATTENUATION_FACTOR_025_LD \
+ FL2FXCONST_DBL(-0.041524101186092029596853445212299)
+/*#define CONCEAL_MIN_ATTENUATION_FACTOR_050 ( FL2FXCONST_DBL(0.944060876285923380) )*/ /* -0.50 dB */
+#define CONCEAL_MIN_ATTENUATION_FACTOR_050_LD \
+ FL2FXCONST_DBL(-0.083048202372184059253597008145293)
+
+typedef enum {
+ CConcealment_NoExpand,
+ CConcealment_Expand,
+ CConcealment_Compress
+} CConcealmentExpandType;
+
+static const FIXP_SGL facMod4Table[4] = {
+ FL2FXCONST_SGL(0.500000000f), /* FIXP_SGL(0x4000), 2^-(1-0,00) */
+ FL2FXCONST_SGL(0.594603558f), /* FIXP_SGL(0x4c1b), 2^-(1-0,25) */
+ FL2FXCONST_SGL(0.707106781f), /* FIXP_SGL(0x5a82), 2^-(1-0,50) */
+ FL2FXCONST_SGL(0.840896415f) /* FIXP_SGL(0x6ba2) 2^-(1-0,75) */
+};
+
+static void CConcealment_CalcBandEnergy(
+ FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
+ const int blockType, CConcealmentExpandType ex, int *sfbEnergy);
+
+static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
+ SHORT *pSpecScalePrev,
+ SHORT *pSpecScaleAct,
+ SHORT *pSpecScaleOut, int *enPrv,
+ int *enAct, int sfbCnt,
+ const SHORT *pSfbOffset);
+
+static int CConcealment_ApplyInter(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const int improveTonal, const int frameOk, const int mute_release_active);
+
+static int CConcealment_ApplyNoise(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UINT flags);
+
+static void CConcealment_UpdateState(
+ CConcealmentInfo *pConcealmentInfo, int frameOk,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+static void CConcealment_ApplyRandomSign(int iRandomPhase, FIXP_DBL *spec,
+ int samplesPerFrame);
+
+/* TimeDomainFading */
+static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
+ FIXP_DBL fadeStop, FIXP_PCM *pcmdata);
+static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
+ int *fadingSteps,
+ FIXP_DBL fadeStop,
+ FIXP_DBL fadeStart,
+ TDfadingType fadingType);
+static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps);
+
+/* Streamline the state machine */
+static int CConcealment_ApplyFadeOut(
+ int mode, CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+static int CConcealment_TDNoise_Random(ULONG *seed);
+static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
+ const int len, FIXP_PCM *const pcmdata);
+
+static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) {
+ BLOCK_TYPE newWinSeq = BLOCK_LONG;
+
+ /* Try to have only long blocks */
+ if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) {
+ newWinSeq = BLOCK_STOP;
+ }
+
+ return (newWinSeq);
+}
+
+/*!
+ \brief Init common concealment information data
+
+ \param pConcealCommonData Pointer to the concealment common data structure.
+*/
+void CConcealment_InitCommonData(CConcealParams *pConcealCommonData) {
+ if (pConcealCommonData != NULL) {
+ int i;
+
+ /* Set default error concealment technique */
+ pConcealCommonData->method = ConcealMethodInter;
+
+ pConcealCommonData->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES;
+ pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES;
+ pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES;
+
+ pConcealCommonData->comfortNoiseLevel =
+ (FIXP_DBL)CONCEAL_DFLT_COMF_NOISE_LEVEL;
+
+ /* Init fade factors (symetric) */
+ pConcealCommonData->fadeOutFactor[0] =
+ FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR);
+ pConcealCommonData->fadeInFactor[0] = pConcealCommonData->fadeOutFactor[0];
+
+ for (i = 1; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ pConcealCommonData->fadeOutFactor[i] =
+ FX_DBL2FX_SGL(fMult(pConcealCommonData->fadeOutFactor[i - 1],
+ FL2FXCONST_SGL(CONCEAL_DFLT_FADE_FACTOR)));
+ pConcealCommonData->fadeInFactor[i] =
+ pConcealCommonData->fadeOutFactor[i];
+ }
+ }
+}
+
+/*!
+ \brief Get current concealment method.
+
+ \param pConcealCommonData Pointer to common concealment data (for all
+ channels)
+*/
+CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) {
+ CConcealmentMethod method = ConcealMethodNone;
+
+ if (pConcealCommonData != NULL) {
+ method = pConcealCommonData->method;
+ }
+
+ return (method);
+}
+
+/*!
+ \brief Init concealment information for each channel
+
+ \param pConcealChannelInfo Pointer to the channel related concealment info
+ structure to be initialized. \param pConcealCommonData Pointer to common
+ concealment data (for all channels) \param initRenderMode Initial render
+ mode to be set for the current channel. \param samplesPerFrame The number
+ of samples per frame.
+*/
+void CConcealment_InitChannelData(CConcealmentInfo *pConcealChannelInfo,
+ CConcealParams *pConcealCommonData,
+ AACDEC_RENDER_MODE initRenderMode,
+ int samplesPerFrame) {
+ int i;
+ pConcealChannelInfo->TDNoiseSeed = 0;
+ FDKmemclear(pConcealChannelInfo->TDNoiseStates,
+ sizeof(pConcealChannelInfo->TDNoiseStates));
+ pConcealChannelInfo->TDNoiseCoef[0] = FL2FXCONST_SGL(0.05f);
+ pConcealChannelInfo->TDNoiseCoef[1] = FL2FXCONST_SGL(0.5f);
+ pConcealChannelInfo->TDNoiseCoef[2] = FL2FXCONST_SGL(0.45f);
+
+ pConcealChannelInfo->pConcealParams = pConcealCommonData;
+
+ pConcealChannelInfo->lastRenderMode = initRenderMode;
+
+ pConcealChannelInfo->windowShape = CONCEAL_NOT_DEFINED;
+ pConcealChannelInfo->windowSequence = BLOCK_LONG; /* default type */
+ pConcealChannelInfo->lastWinGrpLen = 1;
+
+ pConcealChannelInfo->concealState = ConcealState_Ok;
+
+ FDKmemclear(pConcealChannelInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_CNCL));
+
+ for (i = 0; i < 8; i++) {
+ pConcealChannelInfo->specScale[i] = 0;
+ }
+
+ pConcealChannelInfo->iRandomPhase = 0;
+
+ pConcealChannelInfo->prevFrameOk[0] = 1;
+ pConcealChannelInfo->prevFrameOk[1] = 1;
+
+ pConcealChannelInfo->cntFadeFrames = 0;
+ pConcealChannelInfo->cntValidFrames = 0;
+ pConcealChannelInfo->fade_old = (FIXP_DBL)MAXVAL_DBL;
+ pConcealChannelInfo->winGrpOffset[0] = 0;
+ pConcealChannelInfo->winGrpOffset[1] = 0;
+ pConcealChannelInfo->attGrpOffset[0] = 0;
+ pConcealChannelInfo->attGrpOffset[1] = 0;
+}
+
+/*!
+ \brief Set error concealment parameters
+
+ \param concealParams
+ \param method
+ \param fadeOutSlope
+ \param fadeInSlope
+ \param muteRelease
+ \param comfNoiseLevel
+*/
+AAC_DECODER_ERROR
+CConcealment_SetParams(CConcealParams *concealParams, int method,
+ int fadeOutSlope, int fadeInSlope, int muteRelease,
+ FIXP_DBL comfNoiseLevel) {
+ /* set concealment technique */
+ if (method != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ switch ((CConcealmentMethod)method) {
+ case ConcealMethodMute:
+ case ConcealMethodNoise:
+ case ConcealMethodInter:
+ /* Be sure to enable delay adjustment of SBR decoder! */
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->method = (CConcealmentMethod)method;
+ }
+ break;
+
+ default:
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of frames for fade-out slope */
+ if (fadeOutSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numFadeOutFrames = fadeOutSlope;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of frames for fade-in slope */
+ if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numFadeInFrames = fadeInSlope;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set number of error-free frames after which the muting will be released */
+ if (muteRelease != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) &&
+ (muteRelease >= 0)) {
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ /* set param */
+ concealParams->numMuteReleaseFrames = muteRelease;
+ }
+ } else {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+
+ /* set confort noise level which will be inserted while in state 'muting' */
+ if (comfNoiseLevel != (FIXP_DBL)AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) {
+ if ((comfNoiseLevel < (FIXP_DBL)0) ||
+ (comfNoiseLevel > (FIXP_DBL)MAXVAL_DBL)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ } else {
+ concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel;
+ }
+ }
+
+ return (AAC_DEC_OK);
+}
+
+/*!
+ \brief Set fade-out/in attenuation factor vectors
+
+ \param concealParams
+ \param fadeOutAttenuationVector
+ \param fadeInAttenuationVector
+
+ \return 0 if OK all other values indicate errors
+*/
+AAC_DECODER_ERROR
+CConcealment_SetAttenuation(CConcealParams *concealParams,
+ const SHORT *fadeOutAttenuationVector,
+ const SHORT *fadeInAttenuationVector) {
+ if ((fadeOutAttenuationVector == NULL) && (fadeInAttenuationVector == NULL)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+
+ /* Fade-out factors */
+ if (fadeOutAttenuationVector != NULL) {
+ int i;
+
+ /* check quantized factors first */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ if ((fadeOutAttenuationVector[i] < 0) ||
+ (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ /* now dequantize factors */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ concealParams->fadeOutFactor[i] =
+ FX_DBL2FX_SGL(fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
+ (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0 / 2.0) >>
+ (CONCEAL_PARAMETER_BITS - 1)) *
+ (INT)fadeOutAttenuationVector[i]),
+ CONCEAL_PARAMETER_BITS));
+ }
+ }
+
+ /* Fade-in factors */
+ if (fadeInAttenuationVector != NULL) {
+ int i;
+
+ /* check quantized factors first */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ if ((fadeInAttenuationVector[i] < 0) ||
+ (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) {
+ return AAC_DEC_SET_PARAM_FAIL;
+ }
+ }
+ if (concealParams == NULL) {
+ return AAC_DEC_INVALID_HANDLE;
+ }
+
+ /* now dequantize factors */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ concealParams->fadeInFactor[i] = FX_DBL2FX_SGL(
+ fLdPow(CONCEAL_MIN_ATTENUATION_FACTOR_025_LD, 0,
+ (FIXP_DBL)((INT)(FIXP_ONE >> CONCEAL_PARAMETER_BITS) *
+ (INT)fadeInAttenuationVector[i]),
+ CONCEAL_PARAMETER_BITS));
+ }
+ }
+
+ return (AAC_DEC_OK);
+}
+
+/*!
+ \brief Get state of concealment module.
+
+ \param pConcealChannelInfo
+
+ \return Concealment state.
+*/
+CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) {
+ CConcealmentState state = ConcealState_Ok;
+
+ if (pConcealChannelInfo != NULL) {
+ state = pConcealChannelInfo->concealState;
+ }
+
+ return (state);
+}
+
+/*!
+ \brief Store data for concealment techniques applied later
+
+ Interface function to store data for different concealment strategies
+ */
+void CConcealment_Store(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ UCHAR nbDiv = NB_DIV;
+
+ if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderChannelInfo->data.usac.mod[nbDiv - 1] == 0))
+
+ {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+
+ SHORT tSpecScale[8];
+ UCHAR tWindowShape;
+ BLOCK_TYPE tWindowSequence;
+
+ /* store old window infos for swapping */
+ tWindowSequence = hConcealmentInfo->windowSequence;
+ tWindowShape = hConcealmentInfo->windowShape;
+
+ /* store old scale factors for swapping */
+ FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
+
+ /* store new window infos */
+ hConcealmentInfo->windowSequence = GetWindowSequence(pIcsInfo);
+ hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo);
+ hConcealmentInfo->lastWinGrpLen =
+ *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1);
+
+ /* store new scale factors */
+ FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT));
+
+ if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) {
+ /* store new spectral bins */
+#if (CNCL_FRACT_BITS == DFRACT_BITS)
+ FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient,
+ 1024 * sizeof(FIXP_CNCL));
+#else
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ int i;
+ for (i = 1024; i != 0; i--) {
+ *pCncl-- = FX_DBL2FX_CNCL(*pSpec--);
+ }
+#endif
+ } else {
+ /* swap spectral data */
+#if (FIXP_CNCL == FIXP_DBL)
+ C_ALLOC_SCRATCH_START(pSpecTmp, FIXP_DBL, 1024);
+ FDKmemcpy(pSpecTmp, pSpectralCoefficient, 1024 * sizeof(FIXP_DBL));
+ FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_DBL));
+ FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpecTmp,
+ 1024 * sizeof(FIXP_DBL));
+ C_ALLOC_SCRATCH_END(pSpecTmp, FIXP_DBL, 1024);
+#else
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ FIXP_DBL tSpec;
+
+ for (int i = 1024; i != 0; i--) {
+ tSpec = *pSpec;
+ *pSpec-- = FX_CNCL2FX_DBL(*pCncl);
+ *pCncl-- = FX_DBL2FX_CNCL(tSpec);
+ }
+#endif
+
+ /* complete swapping of window infos */
+ pIcsInfo->WindowSequence = tWindowSequence;
+ pIcsInfo->WindowShape = tWindowShape;
+
+ /* complete swapping of scale factors */
+ FDKmemcpy(pSpecScale, tSpecScale, 8 * sizeof(SHORT));
+ }
+ }
+
+ if (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD) {
+ /* Store LSF4 */
+ FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
+ sizeof(hConcealmentInfo->lsf4));
+ /* Store TCX gain */
+ hConcealmentInfo->last_tcx_gain =
+ pAacDecoderStaticChannelInfo->last_tcx_gain;
+ hConcealmentInfo->last_tcx_gain_e =
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ }
+}
+
+/*!
+ \brief Apply concealment
+
+ Interface function to different concealment strategies
+ */
+int CConcealment_Apply(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UCHAR lastLpdMode, const int frameOk, const UINT flags) {
+ int appliedProcessing = 0;
+ const int mute_release_active =
+ frameOk && (hConcealmentInfo->concealState >= ConcealState_Mute) &&
+ (hConcealmentInfo->cntValidFrames + 1 <=
+ hConcealmentInfo->pConcealParams->numMuteReleaseFrames);
+
+ if (hConcealmentInfo->windowShape == CONCEAL_NOT_DEFINED) {
+ /* Initialize window_shape with same value as in the current (parsed) frame.
+ Because section 4.6.11.3.2 (Windowing and block switching) of ISO/IEC
+ 14496-3:2009 says: For the first raw_data_block() to be decoded the
+ window_shape of the left and right half of the window are identical. */
+ hConcealmentInfo->windowShape = pAacDecoderChannelInfo->icsInfo.WindowShape;
+ }
+
+ if (frameOk && !mute_release_active) {
+ /* Update render mode if frameOk except for ongoing mute release state. */
+ hConcealmentInfo->lastRenderMode =
+ (SCHAR)pAacDecoderChannelInfo->renderMode;
+
+ /* Rescue current data for concealment in future frames */
+ CConcealment_Store(hConcealmentInfo, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo);
+ /* Reset index to random sign vector to make sign calculation frame agnostic
+ (only depends on number of subsequently concealed spectral blocks) */
+ hConcealmentInfo->iRandomPhase = 0;
+ } else {
+ if (hConcealmentInfo->lastRenderMode == AACDEC_RENDER_INVALID) {
+ hConcealmentInfo->lastRenderMode = AACDEC_RENDER_IMDCT;
+ }
+ pAacDecoderChannelInfo->renderMode =
+ (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode;
+ }
+
+ /* hand current frame status to the state machine */
+ CConcealment_UpdateState(hConcealmentInfo, frameOk,
+ pAacDecoderStaticChannelInfo, samplesPerFrame,
+ pAacDecoderChannelInfo);
+
+ {
+ if (!frameOk && pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_IMDCT) {
+ /* LPC extrapolation */
+ CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ hConcealmentInfo->lastRenderMode == AACDEC_RENDER_IMDCT);
+ FDKmemcpy(hConcealmentInfo->lsf4, pAacDecoderStaticChannelInfo->lpc4_lsf,
+ sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
+ }
+
+ /* Create data for signal rendering according to the selected concealment
+ * method and decoder operating mode. */
+
+ if ((!frameOk || mute_release_active) &&
+ (pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD)) {
+ /* Restore old LSF4 */
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lpc4_lsf, hConcealmentInfo->lsf4,
+ sizeof(pAacDecoderStaticChannelInfo->lpc4_lsf));
+ /* Restore old TCX gain */
+ pAacDecoderStaticChannelInfo->last_tcx_gain =
+ hConcealmentInfo->last_tcx_gain;
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e =
+ hConcealmentInfo->last_tcx_gain_e;
+ }
+
+ if (!(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD &&
+ pAacDecoderStaticChannelInfo->last_lpd_mode == 0)) {
+ switch (hConcealmentInfo->pConcealParams->method) {
+ default:
+ case ConcealMethodMute:
+ if (!frameOk) {
+ /* Mute spectral data in case of errors */
+ FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient,
+ samplesPerFrame * sizeof(FIXP_DBL));
+ /* Set last window shape */
+ pAacDecoderChannelInfo->icsInfo.WindowShape =
+ hConcealmentInfo->windowShape;
+ appliedProcessing = 1;
+ }
+ break;
+
+ case ConcealMethodNoise:
+ /* Noise substitution error concealment technique */
+ appliedProcessing = CConcealment_ApplyNoise(
+ hConcealmentInfo, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo, pSamplingRateInfo, samplesPerFrame,
+ flags);
+ break;
+
+ case ConcealMethodInter:
+ /* Energy interpolation concealment based on 3GPP */
+ appliedProcessing = CConcealment_ApplyInter(
+ hConcealmentInfo, pAacDecoderChannelInfo, pSamplingRateInfo,
+ samplesPerFrame, 0, /* don't use tonal improvement */
+ frameOk, mute_release_active);
+ break;
+ }
+ } else if (!frameOk || mute_release_active) {
+ /* simply restore the buffer */
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+#if (CNCL_FRACT_BITS != DFRACT_BITS)
+ FIXP_CNCL *RESTRICT pCncl =
+ &hConcealmentInfo->spectralCoefficient[1024 - 1];
+ FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024 - 1];
+ int i;
+#endif
+
+ /* restore window infos (gri) do we need that? */
+ pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence;
+ pIcsInfo->WindowShape = hConcealmentInfo->windowShape;
+
+ if (hConcealmentInfo->concealState != ConcealState_Mute) {
+ /* restore scale factors */
+ FDKmemcpy(pSpecScale, hConcealmentInfo->specScale, 8 * sizeof(SHORT));
+
+ /* restore spectral bins */
+#if (CNCL_FRACT_BITS == DFRACT_BITS)
+ FDKmemcpy(pSpectralCoefficient, hConcealmentInfo->spectralCoefficient,
+ 1024 * sizeof(FIXP_DBL));
+#else
+ for (i = 1024; i != 0; i--) {
+ *pSpec-- = FX_CNCL2FX_DBL(*pCncl--);
+ }
+#endif
+ } else {
+ /* clear scale factors */
+ FDKmemclear(pSpecScale, 8 * sizeof(SHORT));
+
+ /* clear buffer */
+ FDKmemclear(pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL));
+ }
+ }
+ }
+ /* update history */
+ hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1];
+ hConcealmentInfo->prevFrameOk[1] = frameOk;
+
+ return mute_release_active ? -1 : appliedProcessing;
+}
+
+/*!
+\brief Apply concealment noise substitution
+
+ In case of frame lost this function produces a noisy frame with respect to the
+ energies values of past frame.
+ */
+static int CConcealment_ApplyNoise(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UINT flags) {
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+
+ int appliedProcessing = 0;
+
+ FDK_ASSERT(pConcealmentInfo != NULL);
+ FDK_ASSERT((samplesPerFrame >= 120) && (samplesPerFrame <= 1024));
+
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ /* Nothing to do here! */
+ break;
+
+ case ConcealState_Single:
+ case ConcealState_FadeOut:
+ appliedProcessing = CConcealment_ApplyFadeOut(
+ /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ break;
+
+ case ConcealState_Mute: {
+ /* set dummy window parameters */
+ pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
+ pIcsInfo->WindowShape =
+ pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
+ (required for F/T transform) */
+ pIcsInfo->WindowSequence =
+ CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
+ pConcealmentInfo->windowSequence =
+ pIcsInfo->WindowSequence; /* Store for next frame
+ (spectrum in concealment
+ buffer can't be used at
+ all) */
+
+ /* mute spectral data */
+ FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
+ FDKmemclear(pConcealmentInfo->spectralCoefficient,
+ samplesPerFrame * sizeof(FIXP_DBL));
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_FadeIn: {
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ default:
+ /* we shouldn't come here anyway */
+ FDK_ASSERT(0);
+ break;
+ }
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Apply concealment interpolation
+
+ The function swaps the data from the current and the previous frame. If an
+ error has occured, frame interpolation is performed to restore the missing
+ frame. In case of multiple faulty frames, fade-in and fade-out is applied.
+*/
+static int CConcealment_ApplyInter(
+ CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const int improveTonal, const int frameOk, const int mute_release_active) {
+#if defined(FDK_ASSERT_ENABLE)
+ CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
+#endif
+
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ int sfbEnergyPrev[64];
+ int sfbEnergyAct[64];
+
+ int i, appliedProcessing = 0;
+
+ /* clear/init */
+ FDKmemclear(sfbEnergyPrev, 64 * sizeof(int));
+ FDKmemclear(sfbEnergyAct, 64 * sizeof(int));
+
+ if (!frameOk || mute_release_active) {
+ /* Restore last frame from concealment buffer */
+ pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
+ pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
+
+ /* Restore spectral data */
+ for (i = 0; i < samplesPerFrame; i++) {
+ pSpectralCoefficient[i] =
+ FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]);
+ }
+
+ /* Restore scale factors */
+ FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT));
+ }
+
+ /* if previous frame was not ok */
+ if (!pConcealmentInfo->prevFrameOk[1] || mute_release_active) {
+ /* if current frame (f_n) is ok and the last but one frame (f_(n-2))
+ was ok, too, then interpolate both frames in order to generate
+ the current output frame (f_(n-1)). Otherwise, use the last stored
+ frame (f_(n-2) or f_(n-3) or ...). */
+ if (frameOk && pConcealmentInfo->prevFrameOk[0] && !mute_release_active) {
+ appliedProcessing = 1;
+
+ /* Interpolate both frames in order to generate the current output frame
+ * (f_(n-1)). */
+ if (pIcsInfo->WindowSequence == BLOCK_SHORT) {
+ /* f_(n-2) == BLOCK_SHORT */
+ /* short--??????--short, short--??????--long interpolation */
+ /* short--short---short, short---long---long interpolation */
+
+ int wnd;
+
+ if (pConcealmentInfo->windowSequence ==
+ BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
+ /* short--short---short interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+ pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
+ pIcsInfo->WindowSequence = BLOCK_SHORT;
+
+ for (wnd = 0; wnd < 8; wnd++) {
+ CConcealment_CalcBandEnergy(
+ &pSpectralCoefficient[wnd *
+ (samplesPerFrame / 8)], /* spec_(n-2) */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
+ sfbEnergyPrev);
+
+ CConcealment_CalcBandEnergy(
+ &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame /
+ 8)], /* spec_n */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand,
+ sfbEnergyAct);
+
+ CConcealment_InterpolateBuffer(
+ &pSpectralCoefficient[wnd *
+ (samplesPerFrame / 8)], /* spec_(n-1) */
+ &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd],
+ &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct,
+ scaleFactorBandsTotal, pSfbOffset);
+ }
+ } else { /* f_n != BLOCK_SHORT */
+ /* short---long---long interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+ SHORT specScaleOut;
+
+ CConcealment_CalcBandEnergy(
+ &pSpectralCoefficient[samplesPerFrame -
+ (samplesPerFrame /
+ 8)], /* [wnd] spec_(n-2) */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand,
+ sfbEnergyAct);
+
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
+ sfbEnergyPrev);
+
+ pIcsInfo->WindowShape = 0;
+ pIcsInfo->WindowSequence = BLOCK_STOP;
+
+ for (i = 0; i < samplesPerFrame; i++) {
+ pSpectralCoefficient[i] =
+ pConcealmentInfo->spectralCoefficient[i]; /* spec_n */
+ }
+
+ for (i = 0; i < 8; i++) { /* search for max(specScale) */
+ if (pSpecScale[i] > pSpecScale[0]) {
+ pSpecScale[0] = pSpecScale[i];
+ }
+ }
+
+ CConcealment_InterpolateBuffer(
+ pSpectralCoefficient, /* spec_(n-1) */
+ &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut,
+ sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
+
+ pSpecScale[0] = specScaleOut;
+ }
+ } else {
+ /* long--??????--short, long--??????--long interpolation */
+ /* long---long---short, long---long---long interpolation */
+
+ int scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+ SHORT specScaleAct = pConcealmentInfo->specScale[0];
+
+ CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */
+ pSamplingRateInfo, BLOCK_LONG,
+ CConcealment_NoExpand, sfbEnergyPrev);
+
+ if (pConcealmentInfo->windowSequence ==
+ BLOCK_SHORT) { /* f_n == BLOCK_SHORT */
+ /* long---long---short interpolation */
+
+ pIcsInfo->WindowShape = (samplesPerFrame <= 512) ? 2 : 1;
+ pIcsInfo->WindowSequence = BLOCK_START;
+
+ for (i = 1; i < 8; i++) { /* search for max(specScale) */
+ if (pConcealmentInfo->specScale[i] > specScaleAct) {
+ specScaleAct = pConcealmentInfo->specScale[i];
+ }
+ }
+
+ /* Expand first short spectrum */
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */
+ sfbEnergyAct);
+ } else {
+ /* long---long---long interpolation */
+
+ pIcsInfo->WindowShape = 0;
+ pIcsInfo->WindowSequence = BLOCK_LONG;
+
+ CConcealment_CalcBandEnergy(
+ pConcealmentInfo->spectralCoefficient, /* spec_n */
+ pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand,
+ sfbEnergyAct);
+ }
+
+ CConcealment_InterpolateBuffer(
+ pSpectralCoefficient, /* spec_(n-1) */
+ &pSpecScale[0], &specScaleAct, &pSpecScale[0], sfbEnergyPrev,
+ sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset);
+ }
+ }
+
+ /* Noise substitution of sign of the output spectral coefficients */
+ CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase,
+ pSpectralCoefficient, samplesPerFrame);
+ /* Increment random phase index to avoid repetition artifacts. */
+ pConcealmentInfo->iRandomPhase =
+ (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+ }
+
+ /* scale spectrum according to concealment state */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Single:
+ appliedProcessing = 1;
+ break;
+
+ case ConcealState_FadeOut: {
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ CONCEAL_MAX_NUM_FADE_FACTORS);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ pConcealCommonData->numFadeOutFrames);
+
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_FadeIn: {
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ CONCEAL_MAX_NUM_FADE_FACTORS);
+ FDK_ASSERT(pConcealmentInfo->cntFadeFrames <
+ pConcealCommonData->numFadeInFrames);
+
+ /* TimeDomainFading: */
+ /* Attenuation of signal is done in CConcealment_TDFading() */
+
+ appliedProcessing = 1;
+ } break;
+
+ case ConcealState_Mute: {
+ /* set dummy window parameters */
+ pIcsInfo->Valid = 0; /* Trigger the generation of a consitent IcsInfo */
+ pIcsInfo->WindowShape =
+ pConcealmentInfo->windowShape; /* Prevent an invalid WindowShape
+ (required for F/T transform) */
+ pIcsInfo->WindowSequence =
+ CConcealment_GetWinSeq(pConcealmentInfo->windowSequence);
+ pConcealmentInfo->windowSequence =
+ pIcsInfo->WindowSequence; /* Store for next frame
+ (spectrum in concealment
+ buffer can't be used at
+ all) */
+
+ /* mute spectral data */
+ FDKmemclear(pSpectralCoefficient, samplesPerFrame * sizeof(FIXP_DBL));
+
+ appliedProcessing = 1;
+ } break;
+
+ default:
+ /* nothing to do here */
+ break;
+ }
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Calculate the spectral energy
+
+ The function calculates band-wise the spectral energy. This is used for
+ frame interpolation.
+*/
+static void CConcealment_CalcBandEnergy(
+ FIXP_DBL *spectrum, const SamplingRateInfo *pSamplingRateInfo,
+ const int blockType, CConcealmentExpandType expandType, int *sfbEnergy) {
+ const SHORT *pSfbOffset;
+ int line, sfb, scaleFactorBandsTotal = 0;
+
+ /* In the following calculations, enAccu is initialized with LSB-value in
+ * order to avoid zero energy-level */
+
+ line = 0;
+
+ switch (blockType) {
+ case BLOCK_LONG:
+ case BLOCK_START:
+ case BLOCK_STOP:
+
+ if (expandType == CConcealment_NoExpand) {
+ /* standard long calculation */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ } else {
+ /* compress long to short */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1] << 3; line++) {
+ enAccu +=
+ (enAccu + (fPow2Div2(*(spectrum + line)) >> sfbScale)) >> 3;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ }
+ break;
+
+ case BLOCK_SHORT:
+
+ if (expandType == CConcealment_NoExpand) {
+ /* standard short calculation */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Short;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + line)) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ } else {
+ /* expand short to long spectrum */
+ scaleFactorBandsTotal =
+ pSamplingRateInfo->NumberOfScaleFactorBands_Long;
+ pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long;
+
+ for (sfb = 0; sfb < scaleFactorBandsTotal; sfb++) {
+ FIXP_DBL enAccu = (FIXP_DBL)(LONG)1;
+ int sfbScale =
+ (sizeof(LONG) << 3) -
+ CntLeadingZeros(pSfbOffset[sfb + 1] - pSfbOffset[sfb]) - 1;
+ /* scaling depends on sfb width. */
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ enAccu += fPow2Div2(*(spectrum + (line >> 3))) >> sfbScale;
+ }
+ *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1;
+ }
+ }
+ break;
+ }
+}
+
+/*!
+ \brief Interpolate buffer
+
+ The function creates the interpolated spectral data according to the
+ energy of the last good frame and the current (good) frame.
+*/
+static void CConcealment_InterpolateBuffer(FIXP_DBL *spectrum,
+ SHORT *pSpecScalePrv,
+ SHORT *pSpecScaleAct,
+ SHORT *pSpecScaleOut, int *enPrv,
+ int *enAct, int sfbCnt,
+ const SHORT *pSfbOffset) {
+ int sfb, line = 0;
+ int fac_shift;
+ int fac_mod;
+ FIXP_DBL accu;
+
+ for (sfb = 0; sfb < sfbCnt; sfb++) {
+ fac_shift =
+ enPrv[sfb] - enAct[sfb] + ((*pSpecScaleAct - *pSpecScalePrv) << 1);
+ fac_mod = fac_shift & 3;
+ fac_shift = (fac_shift >> 2) + 1;
+ fac_shift += *pSpecScalePrv - fixMax(*pSpecScalePrv, *pSpecScaleAct);
+
+ for (; line < pSfbOffset[sfb + 1]; line++) {
+ accu = fMult(*(spectrum + line), facMod4Table[fac_mod]);
+ if (fac_shift < 0) {
+ accu >>= -fac_shift;
+ } else {
+ accu <<= fac_shift;
+ }
+ *(spectrum + line) = accu;
+ }
+ }
+ *pSpecScaleOut = fixMax(*pSpecScalePrv, *pSpecScaleAct);
+}
+
+/*!
+ \brief Find next fading frame in case of changing fading direction
+
+ \param pConcealCommonData Pointer to the concealment common data structure.
+ \param actFadeIndex Last index used for fading
+ \param direction Direction of change: 0 : change from FADE-OUT to FADE-IN, 1
+ : change from FADE-IN to FADE-OUT
+
+ This function determines the next fading index to be used for the fading
+ direction to be changed to.
+*/
+
+static INT findEquiFadeFrame(CConcealParams *pConcealCommonData,
+ INT actFadeIndex, int direction) {
+ FIXP_SGL *pFactor;
+ FIXP_SGL referenceVal;
+ FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL;
+
+ INT nextFadeIndex = 0;
+
+ int i;
+
+ /* init depending on direction */
+ if (direction == 0) { /* FADE-OUT => FADE-IN */
+ if (actFadeIndex < 0) {
+ referenceVal = (FIXP_SGL)MAXVAL_SGL;
+ } else {
+ referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1;
+ }
+ pFactor = pConcealCommonData->fadeInFactor;
+ } else { /* FADE-IN => FADE-OUT */
+ if (actFadeIndex < 0) {
+ referenceVal = (FIXP_SGL)MAXVAL_SGL;
+ } else {
+ referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1;
+ }
+ pFactor = pConcealCommonData->fadeOutFactor;
+ }
+
+ /* search for minimum difference */
+ for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) {
+ FIXP_SGL diff = fixp_abs((pFactor[i] >> 1) - referenceVal);
+ if (diff < minDiff) {
+ minDiff = diff;
+ nextFadeIndex = i;
+ }
+ }
+
+ /* check and adjust depending on direction */
+ if (direction == 0) { /* FADE-OUT => FADE-IN */
+ if (nextFadeIndex > pConcealCommonData->numFadeInFrames) {
+ nextFadeIndex = fMax(pConcealCommonData->numFadeInFrames - 1, 0);
+ }
+ if (((pFactor[nextFadeIndex] >> 1) <= referenceVal) &&
+ (nextFadeIndex > 0)) {
+ nextFadeIndex -= 1;
+ }
+ } else { /* FADE-IN => FADE-OUT */
+ if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) &&
+ (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) {
+ nextFadeIndex += 1;
+ }
+ }
+
+ return (nextFadeIndex);
+}
+
+/*!
+ \brief Update the concealment state
+
+ The function updates the state of the concealment state-machine. The
+ states are: mute, fade-in, fade-out, interpolate and frame-ok.
+*/
+static void CConcealment_UpdateState(
+ CConcealmentInfo *pConcealmentInfo, int frameOk,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams;
+
+ switch (pConcealCommonData->method) {
+ case ConcealMethodNoise: {
+ if (pConcealmentInfo->concealState != ConcealState_Ok) {
+ /* count the valid frames during concealment process */
+ if (frameOk) {
+ pConcealmentInfo->cntValidFrames += 1;
+ } else {
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ }
+
+ /* -- STATE MACHINE for Noise Substitution -- */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ if (!frameOk) {
+ pConcealmentInfo->cntFadeFrames = 0;
+ pConcealmentInfo->cntValidFrames = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state SINGLE-FRAME-LOSS */
+ pConcealmentInfo->concealState = ConcealState_Single;
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ case ConcealState_Single: /* Just a pre-stage before fade-out begins.
+ Stay here only one frame! */
+ if (frameOk) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ } else {
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ } else {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ }
+ }
+ break;
+
+ case ConcealState_FadeOut:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames,
+ 0 /* FadeOut -> FadeIn */);
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (frameOk) {
+ /* we have good frame information but stay fully in concealment -
+ * reset winGrpOffset/attGrpOffset */
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ }
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ } else /* Stay in FADE-OUT */
+ {
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ }
+ }
+ break;
+
+ case ConcealState_Mute:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames =
+ pConcealCommonData->numFadeInFrames - 1;
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (frameOk) {
+ /* we have good frame information but stay fully in concealment -
+ * reset winGrpOffset/attGrpOffset */
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+ }
+ }
+ break;
+
+ case ConcealState_FadeIn:
+ pConcealmentInfo->cntFadeFrames -= 1;
+ if (frameOk) {
+ if (pConcealmentInfo->cntFadeFrames < 0) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
+ 1 /* FadeIn -> FadeOut */);
+ pConcealmentInfo->winGrpOffset[0] = 0;
+ pConcealmentInfo->winGrpOffset[1] = 0;
+ pConcealmentInfo->attGrpOffset[0] = 0;
+ pConcealmentInfo->attGrpOffset[1] = 0;
+
+ pConcealmentInfo
+ ->cntFadeFrames--; /* decrease because
+ CConcealment_ApplyFadeOut() will
+ increase, accordingly */
+ /* mode 0 just updates the Fading counter */
+ CConcealment_ApplyFadeOut(
+ /*mode =*/0, pConcealmentInfo, pAacDecoderStaticChannelInfo,
+ samplesPerFrame, pAacDecoderChannelInfo);
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ default:
+ FDK_ASSERT(0);
+ break;
+ }
+ } break;
+
+ case ConcealMethodInter:
+ case ConcealMethodTonal: {
+ if (pConcealmentInfo->concealState != ConcealState_Ok) {
+ /* count the valid frames during concealment process */
+ if (pConcealmentInfo->prevFrameOk[1] ||
+ (pConcealmentInfo->prevFrameOk[0] &&
+ !pConcealmentInfo->prevFrameOk[1] && frameOk)) {
+ /* The frame is OK even if it can be estimated by the energy
+ * interpolation algorithm */
+ pConcealmentInfo->cntValidFrames += 1;
+ } else {
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ }
+
+ /* -- STATE MACHINE for energy interpolation -- */
+ switch (pConcealmentInfo->concealState) {
+ case ConcealState_Ok:
+ if (!(pConcealmentInfo->prevFrameOk[1] ||
+ (pConcealmentInfo->prevFrameOk[0] &&
+ !pConcealmentInfo->prevFrameOk[1] && frameOk))) {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* Fade out only if the energy interpolation algorithm can not be
+ * applied! */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ pConcealmentInfo->cntFadeFrames = 0;
+ pConcealmentInfo->cntValidFrames = 0;
+ }
+ break;
+
+ case ConcealState_Single:
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ break;
+
+ case ConcealState_FadeOut:
+ pConcealmentInfo->cntFadeFrames += 1;
+
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames - 1,
+ 0 /* FadeOut -> FadeIn */);
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealmentInfo->cntFadeFrames >=
+ pConcealCommonData->numFadeOutFrames) {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+
+ case ConcealState_Mute:
+ if (pConcealmentInfo->cntValidFrames >
+ pConcealCommonData->numMuteReleaseFrames) {
+ if (pConcealCommonData->numFadeInFrames > 0) {
+ /* change to state FADE-IN */
+ pConcealmentInfo->concealState = ConcealState_FadeIn;
+ pConcealmentInfo->cntFadeFrames =
+ pConcealCommonData->numFadeInFrames - 1;
+ } else {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ }
+ break;
+
+ case ConcealState_FadeIn:
+ pConcealmentInfo->cntFadeFrames -=
+ 1; /* used to address the fade-in factors */
+
+ if (frameOk || pConcealmentInfo->prevFrameOk[1]) {
+ if (pConcealmentInfo->cntFadeFrames < 0) {
+ /* change to state OK */
+ pConcealmentInfo->concealState = ConcealState_Ok;
+ }
+ } else {
+ if (pConcealCommonData->numFadeOutFrames > 0) {
+ /* change to state FADE-OUT */
+ pConcealmentInfo->concealState = ConcealState_FadeOut;
+ pConcealmentInfo->cntFadeFrames = findEquiFadeFrame(
+ pConcealCommonData, pConcealmentInfo->cntFadeFrames + 1,
+ 1 /* FadeIn -> FadeOut */);
+ } else {
+ /* change to state MUTE */
+ pConcealmentInfo->concealState = ConcealState_Mute;
+ }
+ }
+ break;
+ } /* End switch(pConcealmentInfo->concealState) */
+ } break;
+
+ default:
+ /* Don't need a state machine for other concealment methods. */
+ break;
+ }
+}
+
+/*!
+\brief Randomizes the sign of the spectral data
+
+ The function toggles the sign of the spectral data randomly. This is
+ useful to ensure the quality of the concealed frames.
+ */
+static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec,
+ int samplesPerFrame) {
+ int i;
+ USHORT packedSign = 0;
+
+ /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit
+ */
+
+ /* read current packed sign word */
+ packedSign = AacDec_randomSign[randomPhase >> 4];
+ packedSign >>= (randomPhase & 0xf);
+
+ for (i = 0; i < samplesPerFrame; i++) {
+ if ((randomPhase & 0xf) == 0) {
+ packedSign = AacDec_randomSign[randomPhase >> 4];
+ }
+
+ if (packedSign & 0x1) {
+ spec[i] = -spec[i];
+ }
+ packedSign >>= 1;
+
+ randomPhase = (randomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+ }
+}
+
+/*!
+ \brief Get fadeing factor for current concealment state.
+
+ The function returns the state (ok or not) of the previous frame.
+ If called before the function CConcealment_Apply() set the fBeforeApply
+ flag to get the correct value.
+
+ \return Frame OK flag of previous frame.
+ */
+int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
+ const int fBeforeApply) {
+ int prevFrameOk = 1;
+
+ if (hConcealmentInfo != NULL) {
+ prevFrameOk = hConcealmentInfo->prevFrameOk[fBeforeApply & 0x1];
+ }
+
+ return prevFrameOk;
+}
+
+/*!
+ \brief Get the number of delay frames introduced by concealment technique.
+
+ \return Number of delay frames.
+ */
+UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) {
+ UINT frameDelay = 0;
+
+ if (pConcealCommonData != NULL) {
+ switch (pConcealCommonData->method) {
+ case ConcealMethodTonal:
+ case ConcealMethodInter:
+ frameDelay = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return frameDelay;
+}
+
+static int CConcealment_ApplyFadeOut(
+ int mode, CConcealmentInfo *pConcealmentInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ /* mode 1 = apply RandomSign and mute spectral coefficients if necessary, *
+ * mode 0 = Update cntFadeFrames */
+
+ /* restore frequency coefficients from buffer with a specific muting */
+ int srcWin, dstWin, numWindows = 1;
+ int windowLen = samplesPerFrame;
+ int srcGrpStart = 0;
+ int winIdxStride = 1;
+ int numWinGrpPerFac, attIdx, attIdxStride;
+ int i;
+ int appliedProcessing = 0;
+
+ CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
+ FIXP_DBL *pSpectralCoefficient =
+ SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
+ SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
+
+ /* set old window parameters */
+ if (pConcealmentInfo->lastRenderMode == AACDEC_RENDER_LPD) {
+ switch (pAacDecoderStaticChannelInfo->last_lpd_mode) {
+ case 1:
+ numWindows = 4;
+ srcGrpStart = 3;
+ windowLen = samplesPerFrame >> 2;
+ break;
+ case 2:
+ numWindows = 2;
+ srcGrpStart = 1;
+ windowLen = samplesPerFrame >> 1;
+ winIdxStride = 2;
+ break;
+ case 3:
+ numWindows = 1;
+ srcGrpStart = 0;
+ windowLen = samplesPerFrame;
+ winIdxStride = 4;
+ break;
+ }
+ pConcealmentInfo->lastWinGrpLen = 1;
+ } else {
+ pIcsInfo->WindowShape = pConcealmentInfo->windowShape;
+ pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence;
+
+ if (pConcealmentInfo->windowSequence == BLOCK_SHORT) {
+ /* short block handling */
+ numWindows = 8;
+ windowLen = samplesPerFrame >> 3;
+ srcGrpStart = numWindows - pConcealmentInfo->lastWinGrpLen;
+ }
+ }
+
+ attIdxStride =
+ fMax(1, (int)(numWindows / (pConcealmentInfo->lastWinGrpLen + 1)));
+
+ /* load last state */
+ attIdx = pConcealmentInfo->cntFadeFrames;
+ numWinGrpPerFac = pConcealmentInfo->attGrpOffset[mode];
+ srcWin = srcGrpStart + pConcealmentInfo->winGrpOffset[mode];
+
+ FDK_ASSERT((srcGrpStart * windowLen + windowLen) <= samplesPerFrame);
+ FDK_ASSERT((srcWin * windowLen + windowLen) <= 1024);
+
+ for (dstWin = 0; dstWin < numWindows; dstWin += 1) {
+ FIXP_CNCL *pCncl =
+ pConcealmentInfo->spectralCoefficient + (srcWin * windowLen);
+ FIXP_DBL *pOut = pSpectralCoefficient + (dstWin * windowLen);
+
+ if (mode == 1) {
+ /* mute if attIdx gets large enaugh */
+ if (attIdx > pConcealmentInfo->pConcealParams->numFadeOutFrames) {
+ FDKmemclear(pCncl, sizeof(FIXP_DBL) * windowLen);
+ }
+
+ /* restore frequency coefficients from buffer - attenuation is done later
+ */
+ for (i = 0; i < windowLen; i++) {
+ pOut[i] = pCncl[i];
+ }
+
+ /* apply random change of sign for spectral coefficients */
+ CConcealment_ApplyRandomSign(pConcealmentInfo->iRandomPhase, pOut,
+ windowLen);
+
+ /* Increment random phase index to avoid repetition artifacts. */
+ pConcealmentInfo->iRandomPhase =
+ (pConcealmentInfo->iRandomPhase + 1) & (AAC_NF_NO_RANDOM_VAL - 1);
+
+ /* set old scale factors */
+ pSpecScale[dstWin * winIdxStride] =
+ pConcealmentInfo->specScale[srcWin * winIdxStride];
+ }
+
+ srcWin += 1;
+
+ if (srcWin >= numWindows) {
+ /* end of sequence -> rewind to first window of group */
+ srcWin = srcGrpStart;
+ numWinGrpPerFac += 1;
+ if (numWinGrpPerFac >= attIdxStride) {
+ numWinGrpPerFac = 0;
+ attIdx += 1;
+ }
+ }
+ }
+
+ /* store current state */
+
+ pConcealmentInfo->winGrpOffset[mode] = srcWin - srcGrpStart;
+ FDK_ASSERT((pConcealmentInfo->winGrpOffset[mode] >= 0) &&
+ (pConcealmentInfo->winGrpOffset[mode] < 8));
+ pConcealmentInfo->attGrpOffset[mode] = numWinGrpPerFac;
+ FDK_ASSERT((pConcealmentInfo->attGrpOffset[mode] >= 0) &&
+ (pConcealmentInfo->attGrpOffset[mode] < attIdxStride));
+
+ if (mode == 0) {
+ pConcealmentInfo->cntFadeFrames = attIdx;
+ }
+
+ appliedProcessing = 1;
+
+ return appliedProcessing;
+}
+
+/*!
+ \brief Do Time domain fading (TDFading) in concealment case
+
+ In case of concealment, this function takes care of the fading, after time
+domain signal has been rendered by the respective signal rendering functions.
+ The fading out in case of ACELP decoding is not done by this function but by
+the ACELP decoder for the first concealed frame if CONCEAL_CORE_IGNORANT_FADE is
+not set.
+
+ TimeDomain fading never creates jumps in energy / discontinuities, it always
+does a continuous fading. To achieve this, fading is always done from a starting
+point to a target point, while the starting point is always determined to be the
+last target point. By varying the target point of a fading, the fading slope can
+be controlled.
+
+ This principle is applied to the fading within a frame and the fading from
+frame to frame.
+
+ One frame is divided into 8 subframes to obtain 8 parts of fading slopes
+within a frame, each maybe with its own gradient.
+
+ Workflow:
+ 1.) Determine Fading behavior and end-of-frame target fading level, based on
+concealmentState (determined by CConcealment_UpdateState()) and the core mode.
+ - By _DEFAULT_,
+ The target fading level is determined by fadeOutFactor[cntFadeFrames]
+in case of fadeOut, or fadeInFactor[cntFadeFrames] in case of fadeIn.
+ --> fading type is FADE_TIMEDOMAIN in this case. Target fading level
+is determined by fading index cntFadeFrames.
+
+ - If concealmentState is signalling a _MUTED SIGNAL_,
+ TDFading decays to 0 within 1/8th of a frame if numFadeOutFrames == 0.
+ --> fading type is FADE_TIMEDOMAIN_TOSPECTRALMUTE in this case.
+
+ - If concealmentState is signalling the _END OF MUTING_,
+ TDFading fades to target fading level within 1/8th of a frame if
+numFadeInFrames == 0.
+ --> fading type is FADE_TIMEDOMAIN_FROMSPECTRALMUTE in this case.
+Target fading level is determined by fading index cntFadeFrames.
+
+#ifndef CONCEAL_CORE_IGNORANT_FADE
+ - In case of an _ACELP FADEOUT_,
+ TDFading leaves fading control to ACELP decoder for 1/2 frame.
+ --> fading type is FADE_ACELPDOMAIN in this case.
+#endif
+
+ 2.) Render fading levels within current frame and do the final fading:
+ Map Fading slopes to fading levels and apply to time domain signal.
+
+
+*/
+
+INT CConcealment_TDFading(
+ int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
+ FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1) {
+ /*
+ Do the fading in Time domain based on concealment states and core mode
+ */
+ FIXP_DBL fadeStop, attMute = (FIXP_DBL)0;
+ int idx = 0, ii;
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo =
+ *ppAacDecoderStaticChannelInfo;
+ CConcealmentInfo *pConcealmentInfo =
+ &pAacDecoderStaticChannelInfo->concealmentInfo;
+ CConcealParams *pConcealParams = pConcealmentInfo->pConcealParams;
+ const CConcealmentState concealState = pConcealmentInfo->concealState;
+ TDfadingType fadingType;
+ FIXP_DBL fadingStations[9] = {0};
+ int fadingSteps[8] = {0};
+ const FIXP_DBL fadeStart =
+ pConcealmentInfo
+ ->fade_old; /* start fading at last end-of-frame attenuation */
+ FIXP_SGL *fadeFactor = pConcealParams->fadeOutFactor;
+ const INT cntFadeFrames = pConcealmentInfo->cntFadeFrames;
+ int TDFadeOutStopBeforeMute = 1;
+ int TDFadeInStopBeforeFullLevel = 1;
+
+ /*
+ determine Fading behaviour (end-of-frame attenuation and fading type) (1.)
+ */
+
+ switch (concealState) {
+ case ConcealState_Single:
+ case ConcealState_Mute:
+ case ConcealState_FadeOut:
+ idx = (pConcealParams->method == ConcealMethodNoise) ? cntFadeFrames - 1
+ : cntFadeFrames;
+ fadingType = FADE_TIMEDOMAIN;
+
+ if (concealState == ConcealState_Mute ||
+ (cntFadeFrames + TDFadeOutStopBeforeMute) >
+ pConcealmentInfo->pConcealParams->numFadeOutFrames) {
+ fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
+ }
+
+ break;
+ case ConcealState_FadeIn:
+ idx = cntFadeFrames;
+ idx -= TDFadeInStopBeforeFullLevel;
+ FDK_FALLTHROUGH;
+ case ConcealState_Ok:
+ fadeFactor = pConcealParams->fadeInFactor;
+ idx = (concealState == ConcealState_Ok) ? -1 : idx;
+ fadingType = (pConcealmentInfo->concealState_old == ConcealState_Mute)
+ ? FADE_TIMEDOMAIN_FROMSPECTRALMUTE
+ : FADE_TIMEDOMAIN;
+ break;
+ default:
+ FDK_ASSERT(0);
+ fadingType = FADE_TIMEDOMAIN_TOSPECTRALMUTE;
+ break;
+ }
+
+ /* determine Target end-of-frame fading level and fading slope */
+ switch (fadingType) {
+ case FADE_TIMEDOMAIN_FROMSPECTRALMUTE:
+ fadeStop =
+ (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
+ if (pConcealmentInfo->pConcealParams->numFadeInFrames == 0) {
+ /* do step as fast as possible */
+ fadingSteps[0] = 1;
+ break;
+ }
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ case FADE_TIMEDOMAIN:
+ fadeStop =
+ (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(fadeFactor[idx]);
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ case FADE_TIMEDOMAIN_TOSPECTRALMUTE:
+ fadeStop = attMute;
+ if (pConcealmentInfo->pConcealParams->numFadeOutFrames == 0) {
+ /* do step as fast as possible */
+ fadingSteps[0] = 1;
+ break;
+ }
+ CConcealment_TDFading_doLinearFadingSteps(&fadingSteps[0]);
+ break;
+ }
+
+ /*
+ Render fading levels within current frame and do the final fading (2.)
+ */
+
+ len >>= 3;
+ CConcealment_TDFadeFillFadingStations(fadingStations, fadingSteps, fadeStop,
+ fadeStart, fadingType);
+
+ if ((fadingStations[8] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[7] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[6] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[5] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[4] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[3] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[2] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[1] != (FIXP_DBL)MAXVAL_DBL) ||
+ (fadingStations[0] !=
+ (FIXP_DBL)MAXVAL_DBL)) /* if there's something to fade */
+ {
+ int start = 0;
+ for (ii = 0; ii < 8; ii++) {
+ CConcealment_TDFadePcmAtt(start, len, fadingStations[ii],
+ fadingStations[ii + 1], pcmdata);
+ start += len;
+ }
+ }
+ CConcealment_TDNoise_Apply(pConcealmentInfo, len, pcmdata);
+
+ /* Save end-of-frame attenuation and fading type */
+ pConcealmentInfo->lastFadingType = fadingType;
+ pConcealmentInfo->fade_old = fadeStop;
+ pConcealmentInfo->concealState_old = concealState;
+
+ return 1;
+}
+
+/* attenuate pcmdata in Time Domain Fading process */
+static void CConcealment_TDFadePcmAtt(int start, int len, FIXP_DBL fadeStart,
+ FIXP_DBL fadeStop, FIXP_PCM *pcmdata) {
+ int i;
+ FIXP_DBL dStep;
+ FIXP_DBL dGain;
+ FIXP_DBL dGain_apply;
+ int bitshift = (DFRACT_BITS - SAMPLE_BITS);
+
+ /* set start energy */
+ dGain = fadeStart;
+ /* determine energy steps from sample to sample */
+ dStep = (FIXP_DBL)((int)((fadeStart >> 1) - (fadeStop >> 1)) / len) << 1;
+
+ for (i = start; i < (start + len); i++) {
+ dGain -= dStep;
+ /* prevent gain from getting negative due to possible fixpoint inaccuracies
+ */
+ dGain_apply = fMax((FIXP_DBL)0, dGain);
+ /* finally, attenuate samples */
+ pcmdata[i] = (FIXP_PCM)((fMult(pcmdata[i], (dGain_apply))) >> bitshift);
+ }
+}
+
+/*
+\brief Fill FadingStations
+
+The fadingstations are the attenuation factors, being applied to its dedicated
+portions of pcm data. They are calculated using the fadingsteps. One fadingstep
+is the weighted contribution to the fading slope within its dedicated portion of
+pcm data.
+
+*Fadingsteps : 0 0 0 1 0 1 2 0
+
+ |<- 1 Frame pcm data ->|
+ fadeStart-->|__________ |
+ ^ ^ ^ ^ \____ |
+ Attenuation : | | | | ^ ^\__ |
+ | | | | | | ^\ |
+ | | | | | | | \___|<-- fadeStop
+ | | | | | | | ^ ^
+ | | | | | | | | |
+Fadingstations: [0][1][2][3][4][5][6][7][8]
+
+(Fadingstations "[0]" is "[8] from previous frame", therefore its not meaningful
+to be edited)
+
+*/
+static void CConcealment_TDFadeFillFadingStations(FIXP_DBL *fadingStations,
+ int *fadingSteps,
+ FIXP_DBL fadeStop,
+ FIXP_DBL fadeStart,
+ TDfadingType fadingType) {
+ int i;
+ INT fadingSteps_sum = 0;
+ INT fadeDiff;
+
+ fadingSteps_sum = fadingSteps[0] + fadingSteps[1] + fadingSteps[2] +
+ fadingSteps[3] + fadingSteps[4] + fadingSteps[5] +
+ fadingSteps[6] + fadingSteps[7];
+ fadeDiff = ((INT)(fadeStop - fadeStart) / fMax(fadingSteps_sum, (INT)1));
+ fadingStations[0] = fadeStart;
+ for (i = 1; i < 8; i++) {
+ fadingStations[i] =
+ fadingStations[i - 1] + (FIXP_DBL)(fadeDiff * fadingSteps[i - 1]);
+ }
+ fadingStations[8] = fadeStop;
+}
+
+static void CConcealment_TDFading_doLinearFadingSteps(int *fadingSteps) {
+ fadingSteps[0] = fadingSteps[1] = fadingSteps[2] = fadingSteps[3] =
+ fadingSteps[4] = fadingSteps[5] = fadingSteps[6] = fadingSteps[7] = 1;
+}
+
+/* end of TimeDomainFading functions */
+
+/* derived from int UsacRandomSign() */
+static int CConcealment_TDNoise_Random(ULONG *seed) {
+ *seed = (ULONG)(((UINT64)(*seed) * 69069) + 5);
+ return (int)(*seed);
+}
+
+static void CConcealment_TDNoise_Apply(CConcealmentInfo *const pConcealmentInfo,
+ const int len, FIXP_PCM *const pcmdata) {
+ FIXP_PCM *states = pConcealmentInfo->TDNoiseStates;
+ FIXP_PCM noiseVal;
+ FIXP_DBL noiseValLong;
+ FIXP_SGL *coef = pConcealmentInfo->TDNoiseCoef;
+ FIXP_DBL TDNoiseAtt;
+ ULONG seed = pConcealmentInfo->TDNoiseSeed =
+ (ULONG)CConcealment_TDNoise_Random(&pConcealmentInfo->TDNoiseSeed) + 1;
+
+ TDNoiseAtt = pConcealmentInfo->pConcealParams->comfortNoiseLevel;
+
+ int ii;
+
+ if ((pConcealmentInfo->concealState != ConcealState_Ok ||
+ pConcealmentInfo->concealState_old != ConcealState_Ok) &&
+ TDNoiseAtt != (FIXP_DBL)0) {
+ for (ii = 0; ii < (len << 3); ii++) {
+ /* create filtered noise */
+ states[2] = states[1];
+ states[1] = states[0];
+ states[0] = ((FIXP_PCM)CConcealment_TDNoise_Random(&seed));
+ noiseValLong = fMult(states[0], coef[0]) + fMult(states[1], coef[1]) +
+ fMult(states[2], coef[2]);
+ noiseVal = FX_DBL2FX_PCM(fMult(noiseValLong, TDNoiseAtt));
+
+ /* add filtered noise - check for clipping, before */
+ if (noiseVal > (FIXP_PCM)0 &&
+ pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal) {
+ noiseVal = noiseVal * (FIXP_PCM)-1;
+ } else if (noiseVal < (FIXP_PCM)0 &&
+ pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal) {
+ noiseVal = noiseVal * (FIXP_PCM)-1;
+ }
+
+ pcmdata[ii] += noiseVal;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/conceal.h b/fdk-aac/libAACdec/src/conceal.h
new file mode 100644
index 0000000..e01a796
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal.h
@@ -0,0 +1,152 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: independent channel concealment
+
+*******************************************************************************/
+
+#ifndef CONCEAL_H
+#define CONCEAL_H
+
+#include "channelinfo.h"
+
+#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED (0xFFFE)
+
+void CConcealment_InitCommonData(CConcealParams *pConcealCommonData);
+
+void CConcealment_InitChannelData(CConcealmentInfo *hConcealmentInfo,
+ CConcealParams *pConcealCommonData,
+ AACDEC_RENDER_MODE initRenderMode,
+ int samplesPerFrame);
+
+CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData);
+
+UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData);
+
+AAC_DECODER_ERROR
+CConcealment_SetParams(CConcealParams *concealParams, int method,
+ int fadeOutSlope, int fadeInSlope, int muteRelease,
+ FIXP_DBL comfNoiseLevel);
+
+CConcealmentState CConcealment_GetState(CConcealmentInfo *hConcealmentInfo);
+
+AAC_DECODER_ERROR
+CConcealment_SetAttenuation(CConcealParams *concealParams,
+ const SHORT *fadeOutAttenuationVector,
+ const SHORT *fadeInAttenuationVector);
+
+void CConcealment_Store(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+int CConcealment_Apply(
+ CConcealmentInfo *hConcealmentInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame,
+ const UCHAR lastLpdMode, const int FrameOk, const UINT flags);
+
+int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo,
+ const int fBeforeApply);
+
+INT CConcealment_TDFading(
+ int len, CAacDecoderStaticChannelInfo **ppAacDecoderStaticChannelInfo,
+ FIXP_PCM *pcmdata, FIXP_PCM *pcmdata_1);
+
+#endif /* #ifndef CONCEAL_H */
diff --git a/fdk-aac/libAACdec/src/conceal_types.h b/fdk-aac/libAACdec/src/conceal_types.h
new file mode 100644
index 0000000..d90374e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/conceal_types.h
@@ -0,0 +1,203 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Christian Griebel
+
+ Description: Error concealment structs and types
+
+*******************************************************************************/
+
+#ifndef CONCEAL_TYPES_H
+#define CONCEAL_TYPES_H
+
+#include "machine_type.h"
+#include "common_fix.h"
+
+#include "rvlc_info.h"
+
+#include "usacdec_lpc.h"
+
+#define CONCEAL_MAX_NUM_FADE_FACTORS (32)
+
+#define FIXP_CNCL FIXP_DBL
+#define FL2FXCONST_CNCL FL2FXCONST_DBL
+#define FX_DBL2FX_CNCL
+#define FX_CNCL2FX_DBL
+#define CNCL_FRACT_BITS DFRACT_BITS
+
+/* Warning: Do not ever change these values. */
+typedef enum {
+ ConcealMethodNone = -1,
+ ConcealMethodMute = 0,
+ ConcealMethodNoise = 1,
+ ConcealMethodInter = 2,
+ ConcealMethodTonal = 3
+
+} CConcealmentMethod;
+
+typedef enum {
+ ConcealState_Ok,
+ ConcealState_Single,
+ ConcealState_FadeIn,
+ ConcealState_Mute,
+ ConcealState_FadeOut
+
+} CConcealmentState;
+
+typedef struct {
+ FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
+ FIXP_SGL fadeInFactor[CONCEAL_MAX_NUM_FADE_FACTORS];
+
+ CConcealmentMethod method;
+
+ int numFadeOutFrames;
+ int numFadeInFrames;
+ int numMuteReleaseFrames;
+ FIXP_DBL comfortNoiseLevel;
+
+} CConcealParams;
+
+typedef enum {
+ FADE_TIMEDOMAIN_TOSPECTRALMUTE = 1,
+ FADE_TIMEDOMAIN_FROMSPECTRALMUTE,
+ FADE_TIMEDOMAIN
+} TDfadingType;
+
+typedef struct {
+ CConcealParams *pConcealParams;
+
+ FIXP_CNCL spectralCoefficient[1024];
+ SHORT specScale[8];
+
+ INT iRandomPhase;
+ INT prevFrameOk[2];
+ INT cntValidFrames;
+ INT cntFadeFrames; /* State for signal fade-in/out */
+ /* States for signal fade-out of frames with more than one window/subframe -
+ [0] used by Update CntFadeFrames mode of CConcealment_ApplyFadeOut, [1] used
+ by FadeOut mode */
+ int winGrpOffset[2]; /* State for signal fade-out of frames with more than one
+ window/subframe */
+ int attGrpOffset[2]; /* State for faster signal fade-out of frames with
+ transient signal parts */
+
+ SCHAR lastRenderMode;
+
+ UCHAR windowShape;
+ BLOCK_TYPE windowSequence;
+ UCHAR lastWinGrpLen;
+
+ CConcealmentState concealState;
+ CConcealmentState concealState_old;
+ FIXP_DBL fade_old; /* last fading factor */
+ TDfadingType lastFadingType; /* last fading type */
+
+ SHORT aRvlcPreviousScaleFactor[RVLC_MAX_SFB]; /* needed once per channel */
+ UCHAR aRvlcPreviousCodebook[RVLC_MAX_SFB]; /* needed once per channel */
+ SCHAR rvlcPreviousScaleFactorOK;
+ SCHAR rvlcPreviousBlockType;
+
+ FIXP_LPC lsf4[M_LP_FILTER_ORDER];
+ FIXP_DBL last_tcx_gain;
+ INT last_tcx_gain_e;
+ ULONG TDNoiseSeed;
+ FIXP_PCM TDNoiseStates[3];
+ FIXP_SGL TDNoiseCoef[3];
+ FIXP_SGL TDNoiseAtt;
+
+} CConcealmentInfo;
+
+#endif /* #ifndef CONCEAL_TYPES_H */
diff --git a/fdk-aac/libAACdec/src/ldfiltbank.cpp b/fdk-aac/libAACdec/src/ldfiltbank.cpp
new file mode 100644
index 0000000..c7d2928
--- /dev/null
+++ b/fdk-aac/libAACdec/src/ldfiltbank.cpp
@@ -0,0 +1,276 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description: low delay filterbank
+
+*******************************************************************************/
+
+#include "ldfiltbank.h"
+
+#include "aac_rom.h"
+#include "dct.h"
+#include "FDK_tools_rom.h"
+#include "mdct.h"
+
+#define LDFB_HEADROOM 2
+
+#if defined(__arm__)
+#endif
+
+static void multE2_DinvF_fdk(FIXP_PCM *output, FIXP_DBL *x, const FIXP_WTB *fb,
+ FIXP_DBL *z, const int N) {
+ int i;
+
+ /* scale for FIXP_DBL -> INT_PCM conversion. */
+ const int scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM;
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FIXP_DBL rnd_val_wts0 = (FIXP_DBL)0;
+ FIXP_DBL rnd_val_wts1 = (FIXP_DBL)0;
+ if (-WTS0 - 1 + scale)
+ rnd_val_wts0 = (FIXP_DBL)(1 << (-WTS0 - 1 + scale - 1));
+ if (-WTS1 - 1 + scale)
+ rnd_val_wts1 = (FIXP_DBL)(1 << (-WTS1 - 1 + scale - 1));
+#endif
+
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL z0, z2, tmp;
+
+ z2 = x[N / 2 + i];
+ z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
+
+ z[N / 2 + i] = x[N / 2 - 1 - i] +
+ (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
+
+ tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N + N / 2 + i]));
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS1 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts1)); /* rounding must not cause overflow */
+ output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS1 + 1 - scale) >= 0);
+ output[(N * 3 / 4 - 1 - i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1 + 1 - scale, PCM_OUT_BITS);
+#endif
+
+ z[i] = z0;
+ z[N + i] = z2;
+ }
+
+ for (i = N / 4; i < N / 2; i++) {
+ FIXP_DBL z0, z2, tmp0, tmp1;
+
+ z2 = x[N / 2 + i];
+ z0 = z2 + (fMultDiv2(z[N / 2 + i], fb[2 * N + i]) >> (-WTS2 - 1));
+
+ z[N / 2 + i] = x[N / 2 - 1 - i] +
+ (fMultDiv2(z[N + i], fb[2 * N + N / 2 + i]) >> (-WTS2 - 1));
+
+ tmp0 = (fMultDiv2(z[N / 2 + i], fb[N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N / 2 + i]));
+ tmp1 = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) +
+ fMultDiv2(z[i], fb[N + N / 2 + i]));
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts0)); /* rounding must not cause overflow */
+ FDK_ASSERT(tmp1 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts1)); /* rounding must not cause overflow */
+ output[(i - N / 4)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
+ output[(N * 3 / 4 - 1 - i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp1 + rnd_val_wts1, -WTS1 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS0 + 1 - scale) >= 0);
+ output[(i - N / 4)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
+ output[(N * 3 / 4 - 1 - i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1 + 1 - scale, PCM_OUT_BITS);
+#endif
+ z[i] = z0;
+ z[N + i] = z2;
+ }
+
+ /* Exchange quarter parts of x to bring them in the "right" order */
+ for (i = 0; i < N / 4; i++) {
+ FIXP_DBL tmp0 = fMultDiv2(z[i], fb[N / 2 + i]);
+
+#if ((DFRACT_BITS - SAMPLE_BITS - LDFB_HEADROOM) > 0)
+ FDK_ASSERT((-WTS0 - 1 + scale) >= 0);
+ FDK_ASSERT(tmp0 <= ((FIXP_DBL)0x7FFFFFFF -
+ rnd_val_wts0)); /* rounding must not cause overflow */
+ output[(N * 3 / 4 + i)] = (FIXP_PCM)SATURATE_RIGHT_SHIFT(
+ tmp0 + rnd_val_wts0, -WTS0 - 1 + scale, PCM_OUT_BITS);
+#else
+ FDK_ASSERT((WTS0 + 1 - scale) >= 0);
+ output[(N * 3 / 4 + i)] =
+ (FIXP_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0 + 1 - scale, PCM_OUT_BITS);
+#endif
+ }
+}
+
+int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctData, const int mdctData_e,
+ FIXP_PCM *output, FIXP_DBL *fs_buffer,
+ const int N) {
+ const FIXP_WTB *coef;
+ FIXP_DBL gain = (FIXP_DBL)0;
+ int scale = mdctData_e + MDCT_OUT_HEADROOM -
+ LDFB_HEADROOM; /* The LDFB_HEADROOM is compensated inside
+ multE2_DinvF_fdk() below */
+ int i;
+
+ /* Select LD window slope */
+ switch (N) {
+ case 256:
+ coef = LowDelaySynthesis256;
+ break;
+ case 240:
+ coef = LowDelaySynthesis240;
+ break;
+ case 160:
+ coef = LowDelaySynthesis160;
+ break;
+ case 128:
+ coef = LowDelaySynthesis128;
+ break;
+ case 120:
+ coef = LowDelaySynthesis120;
+ break;
+ case 512:
+ coef = LowDelaySynthesis512;
+ break;
+ case 480:
+ default:
+ coef = LowDelaySynthesis480;
+ break;
+ }
+
+ /*
+ Apply exponent and 1/N factor.
+ Note: "scale" is off by one because for LD_MDCT the window length is twice
+ the window length of a regular MDCT. This is corrected inside
+ multE2_DinvF_fdk(). Refer to ISO/IEC 14496-3:2009 page 277,
+ chapter 4.6.20.2 "Low Delay Window".
+ */
+ imdct_gain(&gain, &scale, N);
+
+ dct_IV(mdctData, N, &scale);
+
+ if (N == 256 || N == 240 || N == 160) {
+ scale -= 1;
+ } else if (N == 128 || N == 120) {
+ scale -= 2;
+ }
+
+ if (gain != (FIXP_DBL)0) {
+ for (i = 0; i < N; i++) {
+ mdctData[i] = fMult(mdctData[i], gain);
+ }
+ }
+ scaleValuesSaturate(mdctData, N, scale);
+
+ /* Since all exponent and factors have been applied, current exponent is zero.
+ */
+ multE2_DinvF_fdk(output, mdctData, coef, fs_buffer, N);
+
+ return (1);
+}
diff --git a/fdk-aac/libAACdec/src/ldfiltbank.h b/fdk-aac/libAACdec/src/ldfiltbank.h
new file mode 100644
index 0000000..b63da6b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/ldfiltbank.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 decoder library ******************************
+
+ Author(s):
+
+ Description: low delay filterbank interface
+
+*******************************************************************************/
+
+#ifndef LDFILTBANK_H
+#define LDFILTBANK_H
+
+#include "common_fix.h"
+
+int InvMdctTransformLowDelay_fdk(FIXP_DBL *mdctdata_m, const int mdctdata_e,
+ FIXP_PCM *mdctOut, FIXP_DBL *fs_buffer,
+ const int frameLength);
+
+#endif
diff --git a/fdk-aac/libAACdec/src/overlapadd.h b/fdk-aac/libAACdec/src/overlapadd.h
new file mode 100644
index 0000000..49eecd8
--- /dev/null
+++ b/fdk-aac/libAACdec/src/overlapadd.h
@@ -0,0 +1,120 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description:
+
+*******************************************************************************/
+
+#ifndef OVERLAPADD_H
+#define OVERLAPADD_H
+
+#include "common_fix.h"
+
+/* ELD uses different overlap which is twice the frame size: */
+#define OverlapBufferSize (768)
+
+typedef FIXP_DBL SPECTRUM[1024];
+typedef FIXP_DBL* SPECTRAL_PTR;
+
+#define SPEC_LONG(ptr) (ptr)
+#define SPEC(ptr, w, gl) ((ptr) + ((w) * (gl)))
+
+#define SPEC_TCX(ptr, f, gl, fb) \
+ ((ptr) + ((f) * (gl * 2) * (((fb) == 0) ? 1 : 2)))
+
+#endif /* #ifndef OVERLAPADD_H */
diff --git a/fdk-aac/libAACdec/src/pulsedata.cpp b/fdk-aac/libAACdec/src/pulsedata.cpp
new file mode 100644
index 0000000..eb6d5bc
--- /dev/null
+++ b/fdk-aac/libAACdec/src/pulsedata.cpp
@@ -0,0 +1,164 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: pulse data tool
+
+*******************************************************************************/
+
+#include "pulsedata.h"
+
+#include "channelinfo.h"
+
+INT CPulseData_Read(HANDLE_FDK_BITSTREAM bs, CPulseData *const PulseData,
+ const SHORT *sfb_startlines, const void *pIcsInfo,
+ const SHORT frame_length) {
+ int i, k = 0;
+ const UINT MaxSfBands =
+ GetScaleFactorBandsTransmitted((const CIcsInfo *)pIcsInfo);
+
+ /* reset pulse data flag */
+ PulseData->PulseDataPresent = 0;
+
+ if ((PulseData->PulseDataPresent = (UCHAR)FDKreadBit(bs)) != 0) {
+ if (!IsLongBlock((const CIcsInfo *)pIcsInfo)) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ PulseData->NumberPulse = (UCHAR)FDKreadBits(bs, 2);
+ PulseData->PulseStartBand = (UCHAR)FDKreadBits(bs, 6);
+
+ if (PulseData->PulseStartBand >= MaxSfBands) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+
+ k = sfb_startlines[PulseData->PulseStartBand];
+
+ for (i = 0; i <= PulseData->NumberPulse; i++) {
+ PulseData->PulseOffset[i] = (UCHAR)FDKreadBits(bs, 5);
+ PulseData->PulseAmp[i] = (UCHAR)FDKreadBits(bs, 4);
+ k += PulseData->PulseOffset[i];
+ }
+
+ if (k >= frame_length) {
+ return AAC_DEC_DECODE_FRAME_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+void CPulseData_Apply(
+ CPulseData *PulseData, /*!< pointer to pulse data side info */
+ const short
+ *pScaleFactorBandOffsets, /*!< pointer to scalefactor band offsets */
+ FIXP_DBL *coef) /*!< pointer to spectrum */
+{
+ int i, k;
+
+ if (PulseData->PulseDataPresent) {
+ k = pScaleFactorBandOffsets[PulseData->PulseStartBand];
+
+ for (i = 0; i <= PulseData->NumberPulse; i++) {
+ k += PulseData->PulseOffset[i];
+ if (coef[k] > (FIXP_DBL)0)
+ coef[k] += (FIXP_DBL)(int)PulseData->PulseAmp[i];
+ else
+ coef[k] -= (FIXP_DBL)(int)PulseData->PulseAmp[i];
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/pulsedata.h b/fdk-aac/libAACdec/src/pulsedata.h
new file mode 100644
index 0000000..15ae11c
--- /dev/null
+++ b/fdk-aac/libAACdec/src/pulsedata.h
@@ -0,0 +1,150 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: pulse data tool
+
+*******************************************************************************/
+
+#ifndef PULSEDATA_H
+#define PULSEDATA_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+
+#define N_MAX_LINES 4
+
+typedef struct {
+ UCHAR PulseDataPresent;
+ UCHAR NumberPulse;
+ UCHAR PulseStartBand;
+ UCHAR PulseOffset[N_MAX_LINES];
+ UCHAR PulseAmp[N_MAX_LINES];
+} CPulseData;
+
+/**
+ * \brief Read pulse data from bitstream
+ *
+ * The function reads the elements for pulse data from
+ * the bitstream.
+ *
+ * \param bs bit stream handle data source.
+ * \param PulseData pointer to a CPulseData were the decoded data is stored
+ * into.
+ * \param MaxSfBands max number of scale factor bands.
+ * \return 0 on success, != 0 on parse error.
+ */
+INT CPulseData_Read(const HANDLE_FDK_BITSTREAM bs, CPulseData *const PulseData,
+ const SHORT *sfb_startlines, const void *pIcsInfo,
+ const SHORT frame_length);
+
+/**
+ * \brief Apply pulse data to spectral lines
+ *
+ * The function applies the pulse data to the
+ * specified spectral lines.
+ *
+ * \param PulseData pointer to the previously decoded pulse data.
+ * \param pScaleFactorBandOffsets scale factor band line offset table.
+ * \param coef pointer to the spectral data were pulse data should be applied
+ * to.
+ * \return none
+ */
+void CPulseData_Apply(CPulseData *PulseData,
+ const short *pScaleFactorBandOffsets, FIXP_DBL *coef);
+
+#endif /* #ifndef PULSEDATA_H */
diff --git a/fdk-aac/libAACdec/src/rvlc.cpp b/fdk-aac/libAACdec/src/rvlc.cpp
new file mode 100644
index 0000000..b7a9be1
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc.cpp
@@ -0,0 +1,1217 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief RVLC Decoder
+ \author Robert Weidner
+*/
+
+#include "rvlc.h"
+
+#include "block.h"
+
+#include "aac_rom.h"
+#include "rvlcbit.h"
+#include "rvlcconceal.h"
+#include "aacdec_hcr.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcInit
+
+ description: init RVLC by data from channelinfo, which was decoded
+previously and set up pointers
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcInit(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ /* RVLC common initialization part 2 of 2 */
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
+ SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
+ SHORT *pScaleFactor = pAacDecoderChannelInfo->pDynData->aScaleFactor;
+ int bnds;
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = 0;
+
+ pRvlc->numDecodedEscapeWordsEsc = 0;
+ pRvlc->numDecodedEscapeWordsFwd = 0;
+ pRvlc->numDecodedEscapeWordsBwd = 0;
+
+ pRvlc->intensity_used = 0;
+ pRvlc->errorLogRvlc = 0;
+
+ pRvlc->conceal_max = CONCEAL_MAX_INIT;
+ pRvlc->conceal_min = CONCEAL_MIN_INIT;
+
+ pRvlc->conceal_max_esc = CONCEAL_MAX_INIT;
+ pRvlc->conceal_min_esc = CONCEAL_MIN_INIT;
+
+ pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape;
+ pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds;
+
+ /* init scf arrays (for savety (in case of there are only zero codebooks)) */
+ for (bnds = 0; bnds < RVLC_MAX_SFB; bnds++) {
+ pScfFwd[bnds] = 0;
+ pScfBwd[bnds] = 0;
+ pScfEsc[bnds] = 0;
+ pScaleFactor[bnds] = 0;
+ }
+
+ /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2))
+ */
+ FDKsyncCache(bs);
+ pRvlc->bsAnchor = (INT)FDKgetValidBits(bs);
+
+ pRvlc->bitstreamIndexRvlFwd =
+ 0; /* first bit within RVL coded block as start address for forward
+ decoding */
+ pRvlc->bitstreamIndexRvlBwd =
+ pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start
+ address for backward decoding */
+
+ /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS
+ * data (if present) */
+ FDKpushFor(bs, pRvlc->length_of_rvlc_sf);
+
+ if (pRvlc->sf_escapes_present != 0) {
+ /* locate internal bitstream ptr at escapes (which is the second part) */
+ FDKsyncCache(bs);
+ pRvlc->bitstreamIndexEsc = pRvlc->bsAnchor - (INT)FDKgetValidBits(bs);
+
+ /* skip escapeRVLC-bitstream-part -- pointing to TNS data (if present) to
+ * make decoder continue */
+ /* decoding of RVLC should work despite this second pushFor during
+ * initialization because */
+ /* bitstream initialization is valid for both ESC2 data parts (RVL-coded
+ * values and ESC-coded values) */
+ FDKpushFor(bs, pRvlc->length_of_rvlc_escapes);
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcCheckIntensityCb
+
+ description: Check if a intensity codebook is used in the current channel.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+-----------------------------------------------------------------------------------------------
+ output: - intensity_used: 0 no intensity codebook is used
+ 1 intensity codebook is used
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcCheckIntensityCb(
+ CErRvlcInfo *pRvlc, CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ int group, band, bnds;
+
+ pRvlc->intensity_used = 0;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ if ((pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
+ INTENSITY_HCB) ||
+ (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds] ==
+ INTENSITY_HCB2)) {
+ pRvlc->intensity_used = 1;
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeEscapeWord
+
+ description: Decode a huffman coded RVLC Escape-word. This value is part
+of a DPCM coded scalefactor.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+-----------------------------------------------------------------------------------------------
+ return: - a single RVLC-Escape value which had to be applied to a
+DPCM value (which has a absolute value of 7)
+--------------------------------------------------------------------------------------------
+*/
+
+static SCHAR rvlcDecodeEscapeWord(CErRvlcInfo *pRvlc, HANDLE_FDK_BITSTREAM bs) {
+ int i;
+ SCHAR value;
+ UCHAR carryBit;
+ UINT treeNode;
+ UINT branchValue;
+ UINT branchNode;
+
+ INT *pBitstreamIndexEsc;
+ const UINT *pEscTree;
+
+ pEscTree = pRvlc->pHuffTreeRvlcEscape;
+ pBitstreamIndexEsc = &(pRvlc->bitstreamIndexEsc);
+ treeNode = *pEscTree; /* init at starting node */
+
+ for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) {
+ carryBit =
+ rvlcReadBitFromBitstream(bs, /* get next bit */
+ pRvlc->bsAnchor, pBitstreamIndexEsc, FWD);
+
+ CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
+ huffman decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> a RVLC-escape-word is
+ completely decoded */
+ value = (SCHAR)branchNode & CLR_BIT_10;
+ pRvlc->length_of_rvlc_escapes -= (MAX_LEN_RVLC_ESCAPE_WORD - i);
+
+ if (pRvlc->length_of_rvlc_escapes < 0) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+ value = -1;
+ }
+
+ return value;
+ } else {
+ treeNode = *(
+ pEscTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+
+ return -1; /* should not be reached */
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeEscapes
+
+ description: Decodes all huffman coded RVLC Escape Words.
+ Here a difference to the pseudo-code-implementation from
+standard can be found. A while loop (and not two nested for loops) is used for
+two reasons:
+
+ 1. The plain huffman encoded escapes are decoded before the
+RVL-coded scalefactors. Therefore the escapes are present in the second step
+ when decoding the RVL-coded-scalefactor values in forward
+and backward direction.
+
+ When the RVL-coded scalefactors are decoded and there a
+escape is needed, then it is just taken out of the array in ascending order.
+
+ 2. It's faster.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - handle to FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: - 0 ok the decoded escapes seem to be valid
+ - 1 error there was a error detected during decoding escapes
+ --> all escapes are invalid
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeEscapes(CErRvlcInfo *pRvlc, SHORT *pEsc,
+ HANDLE_FDK_BITSTREAM bs) {
+ SCHAR escWord;
+ SCHAR escCnt = 0;
+ SHORT *pEscBitCntSum;
+
+ pEscBitCntSum = &(pRvlc->length_of_rvlc_escapes);
+
+ /* Decode all RVLC-Escape words with a plain Huffman-Decoder */
+ while (*pEscBitCntSum > 0) {
+ escWord = rvlcDecodeEscapeWord(pRvlc, bs);
+
+ if (escWord >= 0) {
+ pEsc[escCnt] = escWord;
+ escCnt++;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID;
+ pRvlc->numDecodedEscapeWordsEsc = escCnt;
+
+ return;
+ }
+ } /* all RVLC escapes decoded */
+
+ pRvlc->numDecodedEscapeWordsEsc = escCnt;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: decodeRVLCodeword
+
+ description: Decodes a RVL-coded dpcm-word (-part).
+-----------------------------------------------------------------------------------------------
+ input: - FDK bitstream handle
+ - pointer rvlc structure
+-----------------------------------------------------------------------------------------------
+ return: - a dpcm value which is within range [0,1,..,14] in case of
+no errors. The offset of 7 must be subtracted to get a valid dpcm scalefactor
+value. In case of errors a forbidden codeword is detected --> returning -1
+--------------------------------------------------------------------------------------------
+*/
+
+SCHAR decodeRVLCodeword(HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) {
+ int i;
+ SCHAR value;
+ UCHAR carryBit;
+ UINT branchValue;
+ UINT branchNode;
+
+ const UINT *pRvlCodeTree = pRvlc->pHuffTreeRvlCodewds;
+ UCHAR direction = pRvlc->direction;
+ INT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL;
+ UINT treeNode = *pRvlCodeTree;
+
+ for (i = MAX_LEN_RVLC_CODE_WORD - 1; i >= 0; i--) {
+ carryBit =
+ rvlcReadBitFromBitstream(bs, /* get next bit */
+ pRvlc->bsAnchor, pBitstrIndxRvl, direction);
+
+ CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in
+ huffman decoding tree */
+ treeNode, &branchValue, &branchNode);
+
+ if ((branchNode & TEST_BIT_10) ==
+ TEST_BIT_10) { /* test bit 10 ; if set --> a
+ RVLC-codeword is completely decoded
+ */
+ value = (SCHAR)(branchNode & CLR_BIT_10);
+ *pRvlc->pRvlBitCnt_RVL -= (MAX_LEN_RVLC_CODE_WORD - i);
+
+ /* check available bits for decoding */
+ if (*pRvlc->pRvlBitCnt_RVL < 0) {
+ if (direction == FWD) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD;
+ }
+ value = -1; /* signalize an error in return value, because too many bits
+ was decoded */
+ }
+
+ /* check max value of dpcm value */
+ if (value > MAX_ALLOWED_DPCM_INDEX) {
+ if (direction == FWD) {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD;
+ } else {
+ pRvlc->errorLogRvlc |= RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD;
+ }
+ value = -1; /* signalize an error in return value, because a forbidden
+ cw was detected*/
+ }
+
+ return value; /* return a dpcm value with offset +7 or an error status */
+ } else {
+ treeNode = *(
+ pRvlCodeTree +
+ branchValue); /* update treeNode for further step in decoding tree */
+ }
+ }
+
+ return -1;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeForward
+
+ description: Decode RVL-coded codewords in forward direction.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - handle to FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeForward(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ int band = 0;
+ int group = 0;
+ int bnds = 0;
+
+ SHORT dpcm;
+
+ SHORT factor =
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
+ SHORT position = -SF_OFFSET;
+ SHORT noisenrg = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+
+ SHORT *pScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd;
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ UCHAR *pEscFwdCnt = &(pRvlc->numDecodedEscapeWordsFwd);
+
+ pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_fwd);
+ pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlFwd);
+
+ *pEscFwdCnt = 0;
+ pRvlc->direction = FWD;
+ pRvlc->noise_used = 0;
+ pRvlc->sf_used = 0;
+ pRvlc->lastScf = 0;
+ pRvlc->lastNrg = 0;
+ pRvlc->lastIs = 0;
+
+ rvlcCheckIntensityCb(pRvlc, pAacDecoderChannelInfo);
+
+ /* main loop fwd long */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pScfFwd[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB2:
+ case INTENSITY_HCB:
+ /* store dpcm_is_position */
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ position += dpcm;
+ pScfFwd[bnds] = position;
+ pRvlc->lastIs = position;
+ break;
+
+ case NOISE_HCB:
+ if (pRvlc->noise_used == 0) {
+ pRvlc->noise_used = 1;
+ pRvlc->first_noise_band = bnds;
+ noisenrg += pRvlc->dpcm_noise_nrg;
+ pScfFwd[bnds] = 100 + noisenrg;
+ pRvlc->lastNrg = noisenrg;
+ } else {
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ noisenrg += dpcm;
+ pScfFwd[bnds] = 100 + noisenrg;
+ pRvlc->lastNrg = noisenrg;
+ }
+ pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1;
+ break;
+
+ default:
+ pRvlc->sf_used = 1;
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ factor += dpcm;
+ pScfFwd[bnds] = factor;
+ pRvlc->lastScf = factor;
+ break;
+ }
+ }
+ }
+
+ /* postfetch fwd long */
+ if (pRvlc->intensity_used) {
+ dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
+ if (dpcm < 0) {
+ pRvlc->conceal_max = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_max = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc++;
+ } else {
+ dpcm += *pScfEsc++;
+ }
+ (*pEscFwdCnt)++;
+ if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) {
+ pRvlc->conceal_max_esc = bnds;
+ }
+ }
+ }
+ pRvlc->dpcm_is_last_position = dpcm;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcDecodeBackward
+
+ description: Decode RVL-coded codewords in backward direction.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - handle FDK bitstream
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcDecodeBackward(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ SHORT band, group, dpcm, offset;
+ SHORT bnds = pRvlc->maxSfbTransmitted - 1;
+
+ SHORT factor = pRvlc->rev_global_gain - SF_OFFSET;
+ SHORT position = pRvlc->dpcm_is_last_position - SF_OFFSET;
+ SHORT noisenrg = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
+ SF_OFFSET - 90 - 256;
+
+ SHORT *pScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd;
+ SHORT *pScfEsc = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc;
+ UCHAR *pEscEscCnt = &(pRvlc->numDecodedEscapeWordsEsc);
+ UCHAR *pEscBwdCnt = &(pRvlc->numDecodedEscapeWordsBwd);
+
+ pRvlc->pRvlBitCnt_RVL = &(pRvlc->length_of_rvlc_sf_bwd);
+ pRvlc->pBitstrIndxRvl_RVL = &(pRvlc->bitstreamIndexRvlBwd);
+
+ *pEscBwdCnt = 0;
+ pRvlc->direction = BWD;
+ pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */
+ pRvlc->firstScf = 0;
+ pRvlc->firstNrg = 0;
+ pRvlc->firstIs = 0;
+
+ /* prefetch long BWD */
+ if (pRvlc->intensity_used) {
+ dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */
+ if (dpcm < 0) {
+ pRvlc->dpcm_is_last_position = 0;
+ pRvlc->conceal_min = bnds;
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pRvlc->conceal_min = bnds;
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = bnds;
+ }
+ }
+ }
+ pRvlc->dpcm_is_last_position = dpcm;
+ }
+
+ /* main loop long BWD */
+ for (group = pRvlc->numWindowGroups - 1; group >= 0; group--) {
+ for (band = pRvlc->maxSfbTransmitted - 1; band >= 0; band--) {
+ bnds = 16 * group + band;
+ if ((band == 0) && (pRvlc->numWindowGroups != 1))
+ offset = 16 - pRvlc->maxSfbTransmitted + 1;
+ else
+ offset = 1;
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pScfBwd[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB2:
+ case INTENSITY_HCB:
+ /* store dpcm_is_position */
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = position;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = position;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = position;
+ position -= dpcm;
+ pRvlc->firstIs = position;
+ break;
+
+ case NOISE_HCB:
+ if (bnds == pRvlc->first_noise_band) {
+ pScfBwd[bnds] =
+ pRvlc->dpcm_noise_nrg +
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+ pRvlc->firstNrg = pScfBwd[bnds];
+ } else {
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = noisenrg;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = noisenrg;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = noisenrg;
+ noisenrg -= dpcm;
+ pRvlc->firstNrg = noisenrg;
+ }
+ break;
+
+ default:
+ dpcm = decodeRVLCodeword(bs, pRvlc);
+ if (dpcm < 0) {
+ pScfBwd[bnds] = factor;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ }
+ dpcm -= TABLE_OFFSET;
+ if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) {
+ if (pRvlc->length_of_rvlc_escapes) {
+ pScfBwd[bnds] = factor;
+ pRvlc->conceal_min = fMax(0, bnds - offset);
+ return;
+ } else {
+ if (dpcm == MIN_RVL) {
+ dpcm -= *pScfEsc--;
+ } else {
+ dpcm += *pScfEsc--;
+ }
+ (*pEscBwdCnt)++;
+ if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) {
+ pRvlc->conceal_min_esc = fMax(0, bnds - offset);
+ }
+ }
+ }
+ pScfBwd[bnds] = factor;
+ factor -= dpcm;
+ pRvlc->firstScf = factor;
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcFinalErrorDetection
+
+ description: Call RVLC concealment if error was detected in decoding
+process
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void rvlcFinalErrorDetection(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ UCHAR ErrorStatusComplete = 0;
+ UCHAR ErrorStatusLengthFwd = 0;
+ UCHAR ErrorStatusLengthBwd = 0;
+ UCHAR ErrorStatusLengthEscapes = 0;
+ UCHAR ErrorStatusFirstScf = 0;
+ UCHAR ErrorStatusLastScf = 0;
+ UCHAR ErrorStatusFirstNrg = 0;
+ UCHAR ErrorStatusLastNrg = 0;
+ UCHAR ErrorStatusFirstIs = 0;
+ UCHAR ErrorStatusLastIs = 0;
+ UCHAR ErrorStatusForbiddenCwFwd = 0;
+ UCHAR ErrorStatusForbiddenCwBwd = 0;
+ UCHAR ErrorStatusNumEscapesFwd = 0;
+ UCHAR ErrorStatusNumEscapesBwd = 0;
+ UCHAR ConcealStatus = 1;
+ UCHAR currentBlockType; /* short: 0, not short: 1*/
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 1;
+
+ /* invalid escape words, bit counter unequal zero, forbidden codeword detected
+ */
+ if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD)
+ ErrorStatusForbiddenCwFwd = 1;
+
+ if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD)
+ ErrorStatusForbiddenCwBwd = 1;
+
+ /* bit counter forward unequal zero */
+ if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1;
+
+ /* bit counter backward unequal zero */
+ if (pRvlc->length_of_rvlc_sf_bwd) ErrorStatusLengthBwd = 1;
+
+ /* bit counter escape sequences unequal zero */
+ if (pRvlc->sf_escapes_present)
+ if (pRvlc->length_of_rvlc_escapes) ErrorStatusLengthEscapes = 1;
+
+ if (pRvlc->sf_used) {
+ /* first decoded scf does not match to global gain in backward direction */
+ if (pRvlc->firstScf !=
+ (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET))
+ ErrorStatusFirstScf = 1;
+
+ /* last decoded scf does not match to rev global gain in forward direction
+ */
+ if (pRvlc->lastScf != (pRvlc->rev_global_gain - SF_OFFSET))
+ ErrorStatusLastScf = 1;
+ }
+
+ if (pRvlc->noise_used) {
+ /* first decoded nrg does not match to dpcm_noise_nrg in backward direction
+ */
+ if (pRvlc->firstNrg !=
+ (pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain +
+ pRvlc->dpcm_noise_nrg - SF_OFFSET - 90 - 256))
+ ErrorStatusFirstNrg = 1;
+
+ /* last decoded nrg does not match to dpcm_noise_last_position in forward
+ * direction */
+ if (pRvlc->lastNrg !=
+ (pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position - SF_OFFSET -
+ 90 - 256))
+ ErrorStatusLastNrg = 1;
+ }
+
+ if (pRvlc->intensity_used) {
+ /* first decoded is position does not match in backward direction */
+ if (pRvlc->firstIs != (-SF_OFFSET)) ErrorStatusFirstIs = 1;
+
+ /* last decoded is position does not match in forward direction */
+ if (pRvlc->lastIs != (pRvlc->dpcm_is_last_position - SF_OFFSET))
+ ErrorStatusLastIs = 1;
+ }
+
+ /* decoded escapes and used escapes in forward direction do not fit */
+ if ((pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (pRvlc->conceal_max == CONCEAL_MAX_INIT)) {
+ ErrorStatusNumEscapesFwd = 1;
+ }
+
+ /* decoded escapes and used escapes in backward direction do not fit */
+ if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
+ ErrorStatusNumEscapesBwd = 1;
+ }
+
+ if (ErrorStatusLengthEscapes ||
+ (((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
+ (pRvlc->numDecodedEscapeWordsFwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (ErrorStatusLastScf || ErrorStatusLastNrg || ErrorStatusLastIs))
+
+ &&
+
+ ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
+ (pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) &&
+ (ErrorStatusFirstScf || ErrorStatusFirstNrg || ErrorStatusFirstIs))) ||
+ ((pRvlc->conceal_max == CONCEAL_MAX_INIT) &&
+ ((pRvlc->rev_global_gain - SF_OFFSET - pRvlc->lastScf) < -15)) ||
+ ((pRvlc->conceal_min == CONCEAL_MIN_INIT) &&
+ ((pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET -
+ pRvlc->firstScf) < -15))) {
+ if ((pRvlc->conceal_max == CONCEAL_MAX_INIT) ||
+ (pRvlc->conceal_min == CONCEAL_MIN_INIT)) {
+ pRvlc->conceal_max = 0;
+ pRvlc->conceal_min = fMax(
+ 0, (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1);
+ } else {
+ pRvlc->conceal_max = fMin(pRvlc->conceal_max, pRvlc->conceal_max_esc);
+ pRvlc->conceal_min = fMax(pRvlc->conceal_min, pRvlc->conceal_min_esc);
+ }
+ }
+
+ ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf ||
+ ErrorStatusLastNrg || ErrorStatusFirstNrg ||
+ ErrorStatusLastIs || ErrorStatusFirstIs ||
+ ErrorStatusForbiddenCwFwd ||
+ ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd ||
+ ErrorStatusLengthBwd || ErrorStatusLengthEscapes ||
+ ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd;
+
+ currentBlockType =
+ (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0
+ : 1;
+
+ if (!ErrorStatusComplete) {
+ int band;
+ int group;
+ int bnds;
+ int lastSfbIndex;
+
+ lastSfbIndex = (pRvlc->numWindowGroups > 1) ? 16 : 64;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ }
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] =
+ pAacDecoderChannelInfo->pDynData->aCodeBook[bnds];
+ }
+ for (; band < lastSfbIndex; band++) {
+ bnds = 16 * group + band;
+ FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB);
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] = ZERO_HCB;
+ }
+ }
+ } else {
+ int band;
+ int group;
+
+ /* A single bit error was detected in decoding of dpcm values. It also could
+ be an error with more bits in decoding of escapes and dpcm values whereby
+ an illegal codeword followed not directly after the corrupted bits but
+ just after decoding some more (wrong) scalefactors. Use the smaller
+ scalefactor from forward decoding, backward decoding and previous frame.
+ */
+ if (((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
+ (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
+ (pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
+ currentBlockType) &&
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment && ConcealStatus) {
+ BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* A single bit error was detected in decoding of dpcm values. It also could
+ be an error with more bits in decoding of escapes and dpcm values whereby
+ an illegal codeword followed not directly after the corrupted bits but
+ just after decoding some more (wrong) scalefactors. Use the smaller
+ scalefactor from forward and backward decoding. */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ ((pRvlc->conceal_min != CONCEAL_MIN_INIT) ||
+ (pRvlc->conceal_max != CONCEAL_MAX_INIT)) &&
+ !(pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousBlockType == currentBlockType)) &&
+ ConcealStatus) {
+ BidirectionalEstimation_UseLowerScfOfCurrentFrame(pAacDecoderChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* No errors were detected in decoding of escapes and dpcm values however
+ the first and last value of a group (is,nrg,sf) is incorrect */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ ((ErrorStatusLastScf && ErrorStatusFirstScf) ||
+ (ErrorStatusLastNrg && ErrorStatusFirstNrg) ||
+ (ErrorStatusLastIs && ErrorStatusFirstIs)) &&
+ !(ErrorStatusForbiddenCwFwd || ErrorStatusForbiddenCwBwd ||
+ ErrorStatusLengthEscapes) &&
+ ConcealStatus) {
+ StatisticalEstimation(pAacDecoderChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* A error with more bits in decoding of escapes and dpcm values was
+ detected. Use the smaller scalefactor from forward decoding, backward
+ decoding and previous frame. */
+ if ((pRvlc->conceal_min <= pRvlc->conceal_max) &&
+ pAacDecoderStaticChannelInfo->concealmentInfo
+ .rvlcPreviousScaleFactorOK &&
+ pRvlc->sf_concealment &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo.rvlcPreviousBlockType ==
+ currentBlockType) &&
+ ConcealStatus) {
+ PredictiveInterpolation(pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo);
+ ConcealStatus = 0;
+ }
+
+ /* Call frame concealment, because no better strategy was found. Setting the
+ scalefactors to zero is done for debugging purposes */
+ if (ConcealStatus) {
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[16 * group + band] = 0;
+ }
+ }
+ pAacDecoderChannelInfo->pDynData->specificTo.aac
+ .rvlcCurrentScaleFactorOK = 0;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: CRvlc_Read
+
+ description: Read RVLC ESC1 data (side info) from bitstream.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+
+ int group, band;
+
+ /* RVLC long specific initialization Init part 1 of 2 */
+ pRvlc->numWindowGroups = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
+ pRvlc->maxSfbTransmitted =
+ GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
+ pRvlc->noise_used = 0; /* noise detection */
+ pRvlc->dpcm_noise_nrg = 0; /* only for debugging */
+ pRvlc->dpcm_noise_last_position = 0; /* only for debugging */
+ pRvlc->length_of_rvlc_escapes =
+ -1; /* default value is used for error detection and concealment */
+
+ /* read only error sensitivity class 1 data (ESC 1 - data) */
+ pRvlc->sf_concealment = FDKreadBits(bs, 1); /* #1 */
+ pRvlc->rev_global_gain = FDKreadBits(bs, 8); /* #2 */
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 11); /* #3 */
+ } else {
+ pRvlc->length_of_rvlc_sf = FDKreadBits(bs, 9); /* #3 */
+ }
+
+ /* check if noise codebook is used */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] ==
+ NOISE_HCB) {
+ pRvlc->noise_used = 1;
+ break;
+ }
+ }
+ }
+
+ if (pRvlc->noise_used)
+ pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */
+
+ pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */
+
+ if (pRvlc->sf_escapes_present) {
+ pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6 */
+ }
+
+ if (pRvlc->noise_used) {
+ pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7 PNS */
+ pRvlc->length_of_rvlc_sf -= 9;
+ }
+
+ pRvlc->length_of_rvlc_sf_fwd = pRvlc->length_of_rvlc_sf;
+ pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf;
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: CRvlc_Decode
+
+ description: Decode rvlc data
+ The function reads both the escape sequences and the
+scalefactors in forward and backward direction. If an error occured during
+decoding process which can not be concealed with the rvlc concealment frame
+concealment will be initiated. Then the element "rvlcCurrentScaleFactorOK" in
+the decoder channel info is set to 0 otherwise it is set to 1.
+-----------------------------------------------------------------------------------------------
+ input: - pointer rvlc structure
+ - pointer channel info structure
+ - pointer to persistent channel info structure
+ - pointer bitstream structure
+-----------------------------------------------------------------------------------------------
+ return: ErrorStatus = AAC_DEC_OK
+--------------------------------------------------------------------------------------------
+*/
+
+void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ HANDLE_FDK_BITSTREAM bs) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ INT bitCntOffst;
+ INT saveBitCnt;
+
+ rvlcInit(pRvlc, pAacDecoderChannelInfo, bs);
+
+ /* save bitstream position */
+ saveBitCnt = (INT)FDKgetValidBits(bs);
+
+ if (pRvlc->sf_escapes_present)
+ rvlcDecodeEscapes(
+ pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs);
+
+ rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs);
+ rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs);
+ rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo);
+
+ pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed =
+ pRvlc->intensity_used;
+ pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used;
+
+ /* restore bitstream position */
+ bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
+ if (bitCntOffst) {
+ FDKpushBiDirectional(bs, bitCntOffst);
+ }
+}
+
+void CRvlc_ElementCheck(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const UINT flags, const INT elChannels) {
+ int ch;
+
+ /* Required for MPS residuals. */
+ if (pAacDecoderStaticChannelInfo == NULL) {
+ return;
+ }
+
+ /* RVLC specific sanity checks */
+ if ((flags & AC_ER_RVLC) && (elChannels == 2)) { /* to be reviewed */
+ if (((pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) ||
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0)) &&
+ pAacDecoderChannelInfo[0]->pComData->jointStereoData.MsMaskPresent) {
+ pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ }
+
+ if ((pAacDecoderChannelInfo[0]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 0) &&
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK == 1) &&
+ (pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcIntensityUsed == 1)) {
+ pAacDecoderChannelInfo[1]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK = 0;
+ }
+ }
+
+ for (ch = 0; ch < elChannels; ch++) {
+ pAacDecoderStaticChannelInfo[ch]->concealmentInfo.rvlcPreviousBlockType =
+ (GetWindowSequence(&pAacDecoderChannelInfo[ch]->icsInfo) == BLOCK_SHORT)
+ ? 0
+ : 1;
+ if (flags & AC_ER_RVLC) {
+ pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.rvlcPreviousScaleFactorOK =
+ pAacDecoderChannelInfo[ch]
+ ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK;
+ } else {
+ pAacDecoderStaticChannelInfo[ch]
+ ->concealmentInfo.rvlcPreviousScaleFactorOK = 0;
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/rvlc.h b/fdk-aac/libAACdec/src/rvlc.h
new file mode 100644
index 0000000..9c60d51
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc.h
@@ -0,0 +1,153 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Defines structures and prototypes for RVLC
+ \author Robert Weidner
+*/
+
+#ifndef RVLC_H
+#define RVLC_H
+
+#include "aacdecoder.h"
+#include "channel.h"
+#include "rvlc_info.h"
+
+/* ------------------------------------------------------------------- */
+/* errorLogRvlc: A word of 32 bits used for logging possible errors */
+/* within RVLC in case of distorted bitstreams. */
+/* ------------------------------------------------------------------- */
+#define RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID \
+ 0x80000000 /* ESC-Dec During RVLC-Escape-decoding there have been more \
+ bits decoded as there are available */
+#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_FWD \
+ 0x40000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
+ (long+shrt) */
+#define RVLC_ERROR_RVL_SUM_BIT_COUNTER_BELOW_ZERO_BWD \
+ 0x20000000 /* RVL-Dec negative sum-bitcounter during RVL-fwd-decoding \
+ (long+shrt) */
+#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD \
+ 0x08000000 /* RVL-Dec forbidden codeword detected fwd (long+shrt) */
+#define RVLC_ERROR_FORBIDDEN_CW_DETECTED_BWD \
+ 0x04000000 /* RVL-Dec forbidden codeword detected bwd (long+shrt) */
+
+void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ HANDLE_FDK_BITSTREAM bs);
+
+void CRvlc_Decode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ HANDLE_FDK_BITSTREAM bs);
+
+/**
+ * \brief performe sanity checks to the channel data corresponding to one
+ * channel element.
+ * \param pAacDecoderChannelInfo
+ * \param pAacDecoderStaticChannelInfo
+ * \param elChannels amount of channels of the channel element.
+ */
+void CRvlc_ElementCheck(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
+ const UINT flags, const INT elChannels);
+
+#endif /* RVLC_H */
diff --git a/fdk-aac/libAACdec/src/rvlc_info.h b/fdk-aac/libAACdec/src/rvlc_info.h
new file mode 100644
index 0000000..e7b3b99
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlc_info.h
@@ -0,0 +1,204 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief Defines structures for RVLC
+ \author Robert Weidner
+*/
+#ifndef RVLC_INFO_H
+#define RVLC_INFO_H
+
+#define FWD 0 /* bitstream decoding direction forward (RVL coded part) */
+#define BWD 1 /* bitstream decoding direction backward (RVL coded part) */
+
+#define MAX_RVL 7 /* positive RVLC escape */
+#define MIN_RVL -7 /* negative RVLC escape */
+#define MAX_ALLOWED_DPCM_INDEX \
+ 14 /* the maximum allowed index of a decoded dpcm value (offset \
+ 'TABLE_OFFSET' incl --> must be subtracted) */
+#define TABLE_OFFSET \
+ 7 /* dpcm offset of valid output values of rvl table decoding, the rvl table \
+ ouly returns positive values, therefore the offset */
+#define MAX_LEN_RVLC_CODE_WORD 9 /* max length of a RVL codeword in bits */
+#define MAX_LEN_RVLC_ESCAPE_WORD \
+ 20 /* max length of huffman coded RVLC escape word in bits */
+
+#define DPCM_NOISE_NRG_BITS 9
+#define SF_OFFSET 100 /* offset for correcting scf value */
+
+#define CONCEAL_MAX_INIT 1311 /* arbitrary value */
+#define CONCEAL_MIN_INIT -1311 /* arbitrary value */
+
+#define RVLC_MAX_SFB ((8) * (16))
+
+/* sideinfo of RVLC */
+typedef struct {
+ /* ------- ESC 1 Data: --------- */ /* order of RVLC-bitstream components in
+ bitstream (RVLC-initialization), every
+ component appears only once in
+ bitstream */
+ INT sf_concealment; /* 1 */
+ INT rev_global_gain; /* 2 */
+ SHORT length_of_rvlc_sf; /* 3 */ /* original value, gets modified
+ (subtract 9) in case of noise
+ (PNS); is kept for later use */
+ INT dpcm_noise_nrg; /* 4 optional */
+ INT sf_escapes_present; /* 5 */
+ SHORT length_of_rvlc_escapes; /* 6 optional */
+ INT dpcm_noise_last_position; /* 7 optional */
+
+ INT dpcm_is_last_position;
+
+ SHORT length_of_rvlc_sf_fwd; /* length_of_rvlc_sf used for forward decoding */
+ SHORT
+ length_of_rvlc_sf_bwd; /* length_of_rvlc_sf used for backward decoding */
+
+ /* for RVL-Codeword decoder to distinguish between fwd and bwd decoding */
+ SHORT *pRvlBitCnt_RVL;
+ INT *pBitstrIndxRvl_RVL;
+
+ UCHAR numWindowGroups;
+ UCHAR maxSfbTransmitted;
+ UCHAR first_noise_group;
+ UCHAR first_noise_band;
+ UCHAR direction;
+
+ /* bitstream indices */
+ INT bsAnchor; /* hcr bit buffer reference index */
+ INT bitstreamIndexRvlFwd; /* base address of RVL-coded-scalefactor data (ESC
+ 2) for forward decoding */
+ INT bitstreamIndexRvlBwd; /* base address of RVL-coded-scalefactor data (ESC
+ 2) for backward decoding */
+ INT bitstreamIndexEsc; /* base address where RVLC-escapes start (ESC 2) */
+
+ /* decoding trees */
+ const UINT *pHuffTreeRvlCodewds;
+ const UINT *pHuffTreeRvlcEscape;
+
+ /* escape counters */
+ UCHAR numDecodedEscapeWordsFwd; /* when decoding RVL-codes forward */
+ UCHAR numDecodedEscapeWordsBwd; /* when decoding RVL-codes backward */
+ UCHAR numDecodedEscapeWordsEsc; /* when decoding the escape-Words */
+
+ SCHAR noise_used;
+ SCHAR intensity_used;
+ SCHAR sf_used;
+
+ SHORT firstScf;
+ SHORT lastScf;
+ SHORT firstNrg;
+ SHORT lastNrg;
+ SHORT firstIs;
+ SHORT lastIs;
+
+ /* ------ RVLC error detection ------ */
+ UINT errorLogRvlc; /* store RVLC errors */
+ SHORT conceal_min; /* is set at backward decoding */
+ SHORT conceal_max; /* is set at forward decoding */
+ SHORT conceal_min_esc; /* is set at backward decoding */
+ SHORT conceal_max_esc; /* is set at forward decoding */
+} CErRvlcInfo;
+
+typedef CErRvlcInfo RVLC_INFO; /* temp */
+
+#endif /* RVLC_INFO_H */
diff --git a/fdk-aac/libAACdec/src/rvlcbit.cpp b/fdk-aac/libAACdec/src/rvlcbit.cpp
new file mode 100644
index 0000000..b0c4596
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcbit.cpp
@@ -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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief RVLC bitstream reading
+ \author Robert Weidner
+*/
+
+#include "rvlcbit.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: rvlcReadBitFromBitstream
+
+ description: This function returns a bit from the bitstream according to
+read direction. It is called very often, therefore it makes sense to inline it
+(runtime).
+-----------------------------------------------------------------------------------------------
+ input: - bitstream
+ - pPosition
+ - readDirection
+-----------------------------------------------------------------------------------------------
+ return: - bit from bitstream
+--------------------------------------------------------------------------------------------
+*/
+
+UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pPosition, UCHAR readDirection) {
+ UINT bit;
+ INT readBitOffset = (INT)FDKgetValidBits(bs) - bsAnchor + *pPosition;
+
+ if (readBitOffset) {
+ FDKpushBiDirectional(bs, readBitOffset);
+ }
+
+ if (readDirection == FWD) {
+ bit = FDKreadBits(bs, 1);
+
+ *pPosition += 1;
+ } else {
+ /* to be replaced with a brother function of FDKreadBits() */
+ bit = FDKreadBits(bs, 1);
+ FDKpushBack(bs, 2);
+
+ *pPosition -= 1;
+ }
+
+ return (bit);
+}
diff --git a/fdk-aac/libAACdec/src/rvlcbit.h b/fdk-aac/libAACdec/src/rvlcbit.h
new file mode 100644
index 0000000..2578453
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcbit.h
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Robert Weidner (DSP Solutions)
+
+ Description: RVLC Decoder: Bitstream reading
+
+*******************************************************************************/
+
+#ifndef RVLCBIT_H
+#define RVLCBIT_H
+
+#include "rvlc.h"
+
+UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
+ INT *pPosition, UCHAR readDirection);
+
+#endif /* RVLCBIT_H */
diff --git a/fdk-aac/libAACdec/src/rvlcconceal.cpp b/fdk-aac/libAACdec/src/rvlcconceal.cpp
new file mode 100644
index 0000000..77fda68
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcconceal.cpp
@@ -0,0 +1,787 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief rvlc concealment
+ \author Josef Hoepfl
+*/
+
+#include "rvlcconceal.h"
+
+#include "block.h"
+#include "rvlc.h"
+
+/*---------------------------------------------------------------------------------------------
+ function: calcRefValFwd
+
+ description: The function determines the scalefactor which is closed to the
+scalefactorband conceal_min. The same is done for intensity data and noise
+energies.
+-----------------------------------------------------------------------------------------------
+ output: - reference value scf
+ - reference value internsity data
+ - reference value noise energy
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void calcRefValFwd(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ int *refIsFwd, int *refNrgFwd, int *refScfFwd) {
+ int band, bnds, group, startBand;
+ int idIs, idNrg, idScf;
+ int conceal_min, conceal_group_min;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ MaximumScaleFactorBands = 16;
+ else
+ MaximumScaleFactorBands = 64;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+
+ /* calculate first reference value for approach in forward direction */
+ idIs = idNrg = idScf = 1;
+
+ /* set reference values */
+ *refIsFwd = -SF_OFFSET;
+ *refNrgFwd = pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain -
+ SF_OFFSET - 90 - 256;
+ *refScfFwd =
+ pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain - SF_OFFSET;
+
+ startBand = conceal_min - 1;
+ for (group = conceal_group_min; group >= 0; group--) {
+ for (band = startBand; band >= 0; band--) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (idIs) {
+ *refIsFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idIs = 0; /* reference value has been set */
+ }
+ break;
+ case NOISE_HCB:
+ if (idNrg) {
+ *refNrgFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idNrg = 0; /* reference value has been set */
+ }
+ break;
+ default:
+ if (idScf) {
+ *refScfFwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ idScf = 0; /* reference value has been set */
+ }
+ break;
+ }
+ }
+ startBand = pRvlc->maxSfbTransmitted - 1;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: calcRefValBwd
+
+ description: The function determines the scalefactor which is closed to the
+scalefactorband conceal_max. The same is done for intensity data and noise
+energies.
+-----------------------------------------------------------------------------------------------
+ output: - reference value scf
+ - reference value internsity data
+ - reference value noise energy
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+static void calcRefValBwd(CErRvlcInfo *pRvlc,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ int *refIsBwd, int *refNrgBwd, int *refScfBwd) {
+ int band, bnds, group, startBand;
+ int idIs, idNrg, idScf;
+ int conceal_max, conceal_group_max;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT)
+ MaximumScaleFactorBands = 16;
+ else
+ MaximumScaleFactorBands = 64;
+
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ /* calculate first reference value for approach in backward direction */
+ idIs = idNrg = idScf = 1;
+
+ /* set reference values */
+ *refIsBwd = pRvlc->dpcm_is_last_position - SF_OFFSET;
+ *refNrgBwd = pRvlc->rev_global_gain + pRvlc->dpcm_noise_last_position -
+ SF_OFFSET - 90 - 256 + pRvlc->dpcm_noise_nrg;
+ *refScfBwd = pRvlc->rev_global_gain - SF_OFFSET;
+
+ startBand = conceal_max + 1;
+
+ /* if needed, re-set reference values */
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (idIs) {
+ *refIsBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idIs = 0; /* reference value has been set */
+ }
+ break;
+ case NOISE_HCB:
+ if (idNrg) {
+ *refNrgBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idNrg = 0; /* reference value has been set */
+ }
+ break;
+ default:
+ if (idScf) {
+ *refScfBwd =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ idScf = 0; /* reference value has been set */
+ }
+ break;
+ }
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: BidirectionalEstimation_UseLowerScfOfCurrentFrame
+
+ description: This approach by means of bidirectional estimation is generally
+performed when a single bit error has been detected, the bit error can be
+isolated between 'conceal_min' and 'conceal_max' and the 'sf_concealment' flag
+is not set. The sets of scalefactors decoded in forward and backward direction
+are compared with each other. The smaller scalefactor will be considered as the
+correct one respectively. The reconstruction of the scalefactors with this
+approach archieve good results in audio quality. The strategy must be applied to
+scalefactors, intensity data and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data between
+conceal_min and conceal_max
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, startBand, endBand, group;
+ int conceal_min, conceal_max;
+ int conceal_group_min, conceal_group_max;
+ int MaximumScaleFactorBands;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ MaximumScaleFactorBands = 16;
+ } else {
+ MaximumScaleFactorBands = 64;
+ }
+
+ /* If an error was detected just in forward or backward direction, set the
+ corresponding border for concealment to a appropriate scalefactor band. The
+ border is set to first or last sfb respectively, because the error will
+ possibly not follow directly after the corrupt bit but just after decoding
+ some more (wrong) scalefactors. */
+ if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
+
+ if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
+ pRvlc->conceal_max =
+ (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ if (pRvlc->conceal_min == pRvlc->conceal_max) {
+ int refIsFwd, refNrgFwd, refScfFwd;
+ int refIsBwd, refNrgBwd, refScfBwd;
+
+ bnds = pRvlc->conceal_min;
+ calcRefValFwd(pRvlc, pAacDecoderChannelInfo, &refIsFwd, &refNrgFwd,
+ &refScfFwd);
+ calcRefValBwd(pRvlc, pAacDecoderChannelInfo, &refIsBwd, &refNrgBwd,
+ &refScfBwd);
+
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (refIsFwd < refIsBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd;
+ break;
+ case NOISE_HCB:
+ if (refNrgFwd < refNrgBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refNrgBwd;
+ break;
+ default:
+ if (refScfFwd < refScfBwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd;
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfBwd;
+ break;
+ }
+ } else {
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_max] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_max];
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_min] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_min];
+
+ /* consider the smaller of the forward and backward decoded value as the
+ * correct one */
+ startBand = conceal_min;
+ if (conceal_group_min == conceal_group_max)
+ endBand = conceal_max;
+ else
+ endBand = pRvlc->maxSfbTransmitted - 1;
+
+ for (group = conceal_group_min; group <= conceal_group_max; group++) {
+ for (band = startBand; band <= endBand; band++) {
+ bnds = 16 * group + band;
+ if (pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds] <
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds])
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ if ((group + 1) == conceal_group_max) endBand = conceal_max;
+ }
+ }
+
+ /* now copy all data to the output buffer which needs not to be concealed */
+ if (conceal_group_min == 0)
+ endBand = conceal_min;
+ else
+ endBand = pRvlc->maxSfbTransmitted;
+ for (group = 0; group <= conceal_group_min; group++) {
+ for (band = 0; band < endBand; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ if ((group + 1) == conceal_group_min) endBand = conceal_min;
+ }
+
+ startBand = conceal_max + 1;
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: BidirectionalEstimation_UseScfOfPrevFrameAsReference
+
+ description: This approach by means of bidirectional estimation is generally
+performed when a single bit error has been detected, the bit error can be
+isolated between 'conceal_min' and 'conceal_max', the 'sf_concealment' flag is
+set and the previous frame has the same block type as the current frame. The
+scalefactor decoded in forward and backward direction and the scalefactor of the
+previous frame are compared with each other. The smaller scalefactor will be
+considered as the correct one. At this the codebook of the previous and current
+frame must be of the same set (scf, nrg, is) in each scalefactorband. Otherwise
+the scalefactor of the previous frame is not considered in the minimum
+calculation. The reconstruction of the scalefactors with this approach archieve
+good results in audio quality. The strategy must be applied to scalefactors,
+intensity data and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data between
+conceal_min and conceal_max
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, startBand, endBand, group;
+ int conceal_min, conceal_max;
+ int conceal_group_min, conceal_group_max;
+ int MaximumScaleFactorBands;
+ SHORT commonMin;
+
+ if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) {
+ MaximumScaleFactorBands = 16;
+ } else {
+ MaximumScaleFactorBands = 64;
+ }
+
+ /* If an error was detected just in forward or backward direction, set the
+ corresponding border for concealment to a appropriate scalefactor band. The
+ border is set to first or last sfb respectively, because the error will
+ possibly not follow directly after the corrupt bit but just after decoding
+ some more (wrong) scalefactors. */
+ if (pRvlc->conceal_min == CONCEAL_MIN_INIT) pRvlc->conceal_min = 0;
+
+ if (pRvlc->conceal_max == CONCEAL_MAX_INIT)
+ pRvlc->conceal_max =
+ (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1;
+
+ conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands;
+ conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands;
+ conceal_max = pRvlc->conceal_max % MaximumScaleFactorBands;
+ conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands;
+
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_max] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_max];
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[pRvlc->conceal_min] =
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfFwd[pRvlc->conceal_min];
+
+ /* consider the smaller of the forward and backward decoded value as the
+ * correct one */
+ startBand = conceal_min;
+ if (conceal_group_min == conceal_group_max)
+ endBand = conceal_max;
+ else
+ endBand = pRvlc->maxSfbTransmitted - 1;
+
+ for (group = conceal_group_min; group <= conceal_group_max; group++) {
+ for (band = startBand; band <= endBand; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+
+ case NOISE_HCB:
+ if (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+
+ default:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ }
+ break;
+ }
+ }
+ startBand = 0;
+ if ((group + 1) == conceal_group_max) endBand = conceal_max;
+ }
+
+ /* now copy all data to the output buffer which needs not to be concealed */
+ if (conceal_group_min == 0)
+ endBand = conceal_min;
+ else
+ endBand = pRvlc->maxSfbTransmitted;
+ for (group = 0; group <= conceal_group_min; group++) {
+ for (band = 0; band < endBand; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ }
+ if ((group + 1) == conceal_group_min) endBand = conceal_min;
+ }
+
+ startBand = conceal_max + 1;
+ for (group = conceal_group_max; group < pRvlc->numWindowGroups; group++) {
+ for (band = startBand; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ }
+ startBand = 0;
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ function: StatisticalEstimation
+
+ description: This approach by means of statistical estimation is generally
+performed when both the start value and the end value are different and no
+further errors have been detected. Considering the forward and backward decoded
+scalefactors, the set with the lower scalefactors in sum will be considered as
+the correct one. The scalefactors are differentially encoded. Normally it would
+reach to compare one pair of the forward and backward decoded scalefactors to
+specify the lower set. But having detected no further errors does not
+necessarily mean the absence of errors. Therefore all scalefactors decoded in
+forward and backward direction are summed up seperately. The set with the lower
+sum will be used. The strategy must be applied to scalefactors, intensity data
+and noise energy seperately.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, group;
+ int sumIsFwd, sumIsBwd; /* sum of intensity data forward/backward */
+ int sumNrgFwd, sumNrgBwd; /* sum of noise energy data forward/backward */
+ int sumScfFwd, sumScfBwd; /* sum of scalefactor data forward/backward */
+ int useIsFwd, useNrgFwd, useScfFwd; /* the flags signals the elements which
+ are used for the final result */
+
+ sumIsFwd = sumIsBwd = sumNrgFwd = sumNrgBwd = sumScfFwd = sumScfBwd = 0;
+ useIsFwd = useNrgFwd = useScfFwd = 0;
+
+ /* calculate sum of each group (scf,nrg,is) of forward and backward direction
+ */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ sumIsFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumIsBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ case NOISE_HCB:
+ sumNrgFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumNrgBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ default:
+ sumScfFwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ sumScfBwd +=
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+ }
+ }
+ }
+
+ /* find for each group (scf,nrg,is) the correct direction */
+ if (sumIsFwd < sumIsBwd) useIsFwd = 1;
+
+ if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1;
+
+ if (sumScfFwd < sumScfBwd) useScfFwd = 1;
+
+ /* conceal each group (scf,nrg,is) */
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if (useIsFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ case NOISE_HCB:
+ if (useNrgFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+
+ default:
+ if (useScfFwd)
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds];
+ else
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds];
+ break;
+ }
+ }
+ }
+}
+
+/*---------------------------------------------------------------------------------------------
+ description: Approach by means of predictive interpolation
+ This approach by means of predictive estimation is generally
+performed when the error cannot be isolated between 'conceal_min' and
+'conceal_max', the 'sf_concealment' flag is set and the previous frame has the
+same block type as the current frame. Check for each scalefactorband if the same
+type of data (scalefactor, internsity data, noise energies) is transmitted. If
+so use the scalefactor (intensity data, noise energy) in the current frame.
+Otherwise set the scalefactor (intensity data, noise energy) for this
+scalefactorband to zero.
+-----------------------------------------------------------------------------------------------
+ output: Concealed scalefactor, noise energy and intensity data
+-----------------------------------------------------------------------------------------------
+ return: -
+--------------------------------------------------------------------------------------------
+*/
+
+void PredictiveInterpolation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo) {
+ CErRvlcInfo *pRvlc =
+ &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo;
+ int band, bnds, group;
+ SHORT commonMin;
+
+ for (group = 0; group < pRvlc->numWindowGroups; group++) {
+ for (band = 0; band < pRvlc->maxSfbTransmitted; band++) {
+ bnds = 16 * group + band;
+ switch (pAacDecoderChannelInfo->pDynData->aCodeBook[bnds]) {
+ case ZERO_HCB:
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ break;
+
+ case INTENSITY_HCB:
+ case INTENSITY_HCB2:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB) ||
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
+ }
+ break;
+
+ case NOISE_HCB:
+ if (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] == NOISE_HCB) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = -110;
+ }
+ break;
+
+ default:
+ if ((pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != ZERO_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != NOISE_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB) &&
+ (pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousCodebook[bnds] != INTENSITY_HCB2)) {
+ commonMin = fMin(
+ pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],
+ pAacDecoderChannelInfo->pComData->overlay.aac
+ .aRvlcScfBwd[bnds]);
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] =
+ fMin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo
+ .aRvlcPreviousScaleFactor[bnds]);
+ } else {
+ pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = 0;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/rvlcconceal.h b/fdk-aac/libAACdec/src/rvlcconceal.h
new file mode 100644
index 0000000..8e2062e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/rvlcconceal.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 decoder library ******************************
+
+ Author(s):
+
+ Description:
+
+*******************************************************************************/
+
+/*!
+ \file
+ \brief rvlc concealment
+ \author Josef Hoepfl
+*/
+
+#ifndef RVLCCONCEAL_H
+#define RVLCCONCEAL_H
+
+#include "rvlc.h"
+
+void BidirectionalEstimation_UseLowerScfOfCurrentFrame(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+void BidirectionalEstimation_UseScfOfPrevFrameAsReference(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo);
+
+void PredictiveInterpolation(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+#endif /* RVLCCONCEAL_H */
diff --git a/fdk-aac/libAACdec/src/stereo.cpp b/fdk-aac/libAACdec/src/stereo.cpp
new file mode 100644
index 0000000..eed826b
--- /dev/null
+++ b/fdk-aac/libAACdec/src/stereo.cpp
@@ -0,0 +1,1250 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: joint stereo processing
+
+*******************************************************************************/
+
+#include "stereo.h"
+
+#include "aac_rom.h"
+#include "FDK_bitstream.h"
+#include "channelinfo.h"
+#include "FDK_audio.h"
+
+enum { L = 0, R = 1 };
+
+#include "block.h"
+
+int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
+ CJointStereoData *pJointStereoData,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted,
+ const int max_sfb_ste_clear,
+ CJointStereoPersistentData *pJointStereoPersistentData,
+ CCplxPredictionData *cplxPredictionData,
+ int cplxPredictionActiv, int scaleFactorBandsTotal,
+ int windowSequence, const UINT flags) {
+ int group, band;
+
+ pJointStereoData->MsMaskPresent = (UCHAR)FDKreadBits(bs, 2);
+
+ FDKmemclear(pJointStereoData->MsUsed,
+ scaleFactorBandsTransmitted * sizeof(UCHAR));
+
+ pJointStereoData->cplx_pred_flag = 0;
+ if (cplxPredictionActiv) {
+ cplxPredictionData->pred_dir = 0;
+ cplxPredictionData->complex_coef = 0;
+ cplxPredictionData->use_prev_frame = 0;
+ cplxPredictionData->igf_pred_dir = 0;
+ }
+
+ switch (pJointStereoData->MsMaskPresent) {
+ case 0: /* no M/S */
+ /* all flags are already cleared */
+ break;
+
+ case 1: /* read ms_used */
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
+ }
+ }
+ break;
+
+ case 2: /* full spectrum M/S */
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */
+ }
+ break;
+
+ case 3:
+ /* M/S coding is disabled, complex stereo prediction is enabled */
+ if (flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA)) {
+ if (cplxPredictionActiv) { /* 'if (stereoConfigIndex == 0)' */
+
+ pJointStereoData->cplx_pred_flag = 1;
+
+ /* cplx_pred_data() cp. ISO/IEC FDIS 23003-3:2011(E) Table 26 */
+ int cplx_pred_all = 0; /* local use only */
+ cplx_pred_all = FDKreadBits(bs, 1);
+
+ if (cplx_pred_all) {
+ for (group = 0; group < windowGroups; group++) {
+ UCHAR groupmask = ((UCHAR)1 << group);
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ pJointStereoData->MsUsed[band] |= groupmask;
+ }
+ }
+ } else {
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted;
+ band += SFB_PER_PRED_BAND) {
+ pJointStereoData->MsUsed[band] |= (FDKreadBits(bs, 1) << group);
+ if ((band + 1) < scaleFactorBandsTotal) {
+ pJointStereoData->MsUsed[band + 1] |=
+ (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group));
+ }
+ }
+ }
+ }
+ } else {
+ return -1;
+ }
+ }
+ break;
+ }
+
+ if (cplxPredictionActiv) {
+ /* If all sfb are MS-ed then no complex prediction */
+ if (pJointStereoData->MsMaskPresent == 3) {
+ if (pJointStereoData->cplx_pred_flag) {
+ int delta_code_time = 0;
+
+ /* set pointer to Huffman codebooks */
+ const CodeBookDescription *hcb = &AACcodeBookDescriptionTable[BOOKSCL];
+ /* set predictors to zero in case of a transition from long to short
+ * window sequences and vice versa */
+ if (((windowSequence == BLOCK_SHORT) &&
+ (pJointStereoPersistentData->winSeqPrev != BLOCK_SHORT)) ||
+ ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) &&
+ (windowSequence != BLOCK_SHORT))) {
+ FDKmemclear(pJointStereoPersistentData->alpha_q_re_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ FDKmemclear(pJointStereoPersistentData->alpha_q_im_prev,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ }
+ {
+ FDKmemclear(cplxPredictionData->alpha_q_re,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ FDKmemclear(cplxPredictionData->alpha_q_im,
+ JointStereoMaximumGroups * JointStereoMaximumBands *
+ sizeof(SHORT));
+ }
+
+ /* 0 = mid->side prediction, 1 = side->mid prediction */
+ cplxPredictionData->pred_dir = FDKreadBits(bs, 1);
+ cplxPredictionData->complex_coef = FDKreadBits(bs, 1);
+
+ if (cplxPredictionData->complex_coef) {
+ if (flags & AC_INDEP) {
+ cplxPredictionData->use_prev_frame = 0;
+ } else {
+ cplxPredictionData->use_prev_frame = FDKreadBits(bs, 1);
+ }
+ }
+
+ if (flags & AC_INDEP) {
+ delta_code_time = 0;
+ } else {
+ delta_code_time = FDKreadBits(bs, 1);
+ }
+
+ {
+ int last_alpha_q_re = 0, last_alpha_q_im = 0;
+
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < scaleFactorBandsTransmitted;
+ band += SFB_PER_PRED_BAND) {
+ if (delta_code_time == 1) {
+ if (group > 0) {
+ last_alpha_q_re =
+ cplxPredictionData->alpha_q_re[group - 1][band];
+ last_alpha_q_im =
+ cplxPredictionData->alpha_q_im[group - 1][band];
+ } else if ((windowSequence == BLOCK_SHORT) &&
+ (pJointStereoPersistentData->winSeqPrev ==
+ BLOCK_SHORT)) {
+ /* Included for error-robustness */
+ if (pJointStereoPersistentData->winGroupsPrev == 0) return -1;
+
+ last_alpha_q_re =
+ pJointStereoPersistentData->alpha_q_re_prev
+ [pJointStereoPersistentData->winGroupsPrev - 1][band];
+ last_alpha_q_im =
+ pJointStereoPersistentData->alpha_q_im_prev
+ [pJointStereoPersistentData->winGroupsPrev - 1][band];
+ } else {
+ last_alpha_q_re =
+ pJointStereoPersistentData->alpha_q_re_prev[group][band];
+ last_alpha_q_im =
+ pJointStereoPersistentData->alpha_q_im_prev[group][band];
+ }
+
+ } else {
+ if (band > 0) {
+ last_alpha_q_re =
+ cplxPredictionData->alpha_q_re[group][band - 1];
+ last_alpha_q_im =
+ cplxPredictionData->alpha_q_im[group][band - 1];
+ } else {
+ last_alpha_q_re = 0;
+ last_alpha_q_im = 0;
+ }
+
+ } /* if (delta_code_time == 1) */
+
+ if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) {
+ int dpcm_alpha_re, dpcm_alpha_im;
+
+ dpcm_alpha_re = CBlock_DecodeHuffmanWord(bs, hcb);
+ dpcm_alpha_re -= 60;
+ dpcm_alpha_re *= -1;
+
+ cplxPredictionData->alpha_q_re[group][band] =
+ dpcm_alpha_re + last_alpha_q_re;
+
+ if (cplxPredictionData->complex_coef) {
+ dpcm_alpha_im = CBlock_DecodeHuffmanWord(bs, hcb);
+ dpcm_alpha_im -= 60;
+ dpcm_alpha_im *= -1;
+
+ cplxPredictionData->alpha_q_im[group][band] =
+ dpcm_alpha_im + last_alpha_q_im;
+ } else {
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ }
+
+ } else {
+ cplxPredictionData->alpha_q_re[group][band] = 0;
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ } /* if (pJointStereoData->MsUsed[band] & ((UCHAR)1 << group)) */
+
+ if ((band + 1) <
+ scaleFactorBandsTransmitted) { /* <= this should be the
+ correct way (cp.
+ ISO_IEC_FDIS_23003-0(E) */
+ /* 7.7.2.3.2 Decoding of prediction coefficients) */
+ cplxPredictionData->alpha_q_re[group][band + 1] =
+ cplxPredictionData->alpha_q_re[group][band];
+ cplxPredictionData->alpha_q_im[group][band + 1] =
+ cplxPredictionData->alpha_q_im[group][band];
+ } /* if ((band+1)<scaleFactorBandsTotal) */
+
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] =
+ cplxPredictionData->alpha_q_re[group][band];
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] =
+ cplxPredictionData->alpha_q_im[group][band];
+ }
+
+ for (band = scaleFactorBandsTransmitted; band < max_sfb_ste_clear;
+ band++) {
+ cplxPredictionData->alpha_q_re[group][band] = 0;
+ cplxPredictionData->alpha_q_im[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
+ }
+ }
+ }
+ }
+ } else {
+ for (group = 0; group < windowGroups; group++) {
+ for (band = 0; band < max_sfb_ste_clear; band++) {
+ pJointStereoPersistentData->alpha_q_re_prev[group][band] = 0;
+ pJointStereoPersistentData->alpha_q_im_prev[group][band] = 0;
+ }
+ }
+ }
+
+ pJointStereoPersistentData->winGroupsPrev = windowGroups;
+ }
+
+ return 0;
+}
+
+static void CJointStereo_filterAndAdd(
+ FIXP_DBL *in, int len, int windowLen, const FIXP_FILT *coeff, FIXP_DBL *out,
+ UCHAR isCurrent /* output values with even index get a
+ positve addon (=1) or a negative addon
+ (=0) */
+) {
+ int i, j;
+
+ int indices_1[] = {2, 1, 0, 1, 2, 3};
+ int indices_2[] = {1, 0, 0, 2, 3, 4};
+ int indices_3[] = {0, 0, 1, 3, 4, 5};
+
+ int subtr_1[] = {6, 5, 4, 2, 1, 1};
+ int subtr_2[] = {5, 4, 3, 1, 1, 2};
+ int subtr_3[] = {4, 3, 2, 1, 2, 3};
+
+ if (isCurrent == 1) {
+ /* exploit the symmetry of the table: coeff[6] = - coeff[0],
+ coeff[5] = - coeff[1],
+ coeff[4] = - coeff[2],
+ coeff[3] = 0
+ */
+
+ for (i = 0; i < 3; i++) {
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]]) >> SR_FNA_OUT;
+ out[0] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[1] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]]) >> SR_FNA_OUT;
+ out[1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]]) >> SR_FNA_OUT;
+ out[2] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (j = 3; j < (len - 3); j++) {
+ for (i = 0; i < 3; i++) {
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i]) >> SR_FNA_OUT;
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i]) >> SR_FNA_OUT;
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 3] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]]) >> SR_FNA_OUT;
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]]) >> SR_FNA_OUT;
+ out[len - 2] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 1] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]]) >> SR_FNA_OUT;
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]]) >> SR_FNA_OUT;
+ }
+
+ } else {
+ /* exploit the symmetry of the table: coeff[6] = coeff[0],
+ coeff[5] = coeff[1],
+ coeff[4] = coeff[2]
+ */
+
+ for (i = 0; i < 3; i++) {
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[i]] >> SR_FNA_OUT);
+ out[0] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_1[5 - i]] >> SR_FNA_OUT);
+ }
+ out[0] -= (FIXP_DBL)fMultDiv2(coeff[3], in[0] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[1] += (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[i]] >> SR_FNA_OUT);
+ out[1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_2[5 - i]] >> SR_FNA_OUT);
+ }
+ out[1] += (FIXP_DBL)fMultDiv2(coeff[3], in[1] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[i]] >> SR_FNA_OUT);
+ out[2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[indices_3[5 - i]] >> SR_FNA_OUT);
+ }
+ out[2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[2] >> SR_FNA_OUT);
+
+ for (j = 3; j < (len - 4); j++) {
+ for (i = 0; i < 3; i++) {
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
+ }
+ out[j] += (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
+
+ j++;
+
+ for (i = 0; i < 3; i++) {
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j - 3 + i] >> SR_FNA_OUT);
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[i], in[j + 3 - i] >> SR_FNA_OUT);
+ }
+ out[j] -= (FIXP_DBL)fMultDiv2(coeff[3], in[j] >> SR_FNA_OUT);
+ }
+
+ for (i = 0; i < 3; i++) {
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[i]] >> SR_FNA_OUT);
+ out[len - 3] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_1[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 3] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 3] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[i]] >> SR_FNA_OUT);
+ out[len - 2] -=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_2[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 2] -= (FIXP_DBL)fMultDiv2(coeff[3], in[len - 2] >> SR_FNA_OUT);
+
+ for (i = 0; i < 3; i++) {
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[i]] >> SR_FNA_OUT);
+ out[len - 1] +=
+ (FIXP_DBL)fMultDiv2(coeff[i], in[len - subtr_3[5 - i]] >> SR_FNA_OUT);
+ }
+ out[len - 1] += (FIXP_DBL)fMultDiv2(coeff[3], in[len - 1] >> SR_FNA_OUT);
+ }
+}
+
+static inline void CJointStereo_GenerateMSOutput(FIXP_DBL *pSpecLCurrBand,
+ FIXP_DBL *pSpecRCurrBand,
+ UINT leftScale,
+ UINT rightScale,
+ UINT nSfbBands) {
+ unsigned int i;
+
+ FIXP_DBL leftCoefficient0;
+ FIXP_DBL leftCoefficient1;
+ FIXP_DBL leftCoefficient2;
+ FIXP_DBL leftCoefficient3;
+
+ FIXP_DBL rightCoefficient0;
+ FIXP_DBL rightCoefficient1;
+ FIXP_DBL rightCoefficient2;
+ FIXP_DBL rightCoefficient3;
+
+ for (i = nSfbBands; i > 0; i -= 4) {
+ leftCoefficient0 = pSpecLCurrBand[i - 4];
+ leftCoefficient1 = pSpecLCurrBand[i - 3];
+ leftCoefficient2 = pSpecLCurrBand[i - 2];
+ leftCoefficient3 = pSpecLCurrBand[i - 1];
+
+ rightCoefficient0 = pSpecRCurrBand[i - 4];
+ rightCoefficient1 = pSpecRCurrBand[i - 3];
+ rightCoefficient2 = pSpecRCurrBand[i - 2];
+ rightCoefficient3 = pSpecRCurrBand[i - 1];
+
+ /* MS output generation */
+ leftCoefficient0 >>= leftScale;
+ leftCoefficient1 >>= leftScale;
+ leftCoefficient2 >>= leftScale;
+ leftCoefficient3 >>= leftScale;
+
+ rightCoefficient0 >>= rightScale;
+ rightCoefficient1 >>= rightScale;
+ rightCoefficient2 >>= rightScale;
+ rightCoefficient3 >>= rightScale;
+
+ pSpecLCurrBand[i - 4] = leftCoefficient0 + rightCoefficient0;
+ pSpecLCurrBand[i - 3] = leftCoefficient1 + rightCoefficient1;
+ pSpecLCurrBand[i - 2] = leftCoefficient2 + rightCoefficient2;
+ pSpecLCurrBand[i - 1] = leftCoefficient3 + rightCoefficient3;
+
+ pSpecRCurrBand[i - 4] = leftCoefficient0 - rightCoefficient0;
+ pSpecRCurrBand[i - 3] = leftCoefficient1 - rightCoefficient1;
+ pSpecRCurrBand[i - 2] = leftCoefficient2 - rightCoefficient2;
+ pSpecRCurrBand[i - 1] = leftCoefficient3 - rightCoefficient3;
+ }
+}
+
+void CJointStereo_ApplyMS(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2],
+ FIXP_DBL *spectrumL, FIXP_DBL *spectrumR, SHORT *SFBleftScale,
+ SHORT *SFBrightScale, SHORT *specScaleL, SHORT *specScaleR,
+ const SHORT *pScaleFactorBandOffsets, const UCHAR *pWindowGroupLength,
+ const int windowGroups, const int max_sfb_ste_outside,
+ const int scaleFactorBandsTransmittedL,
+ const int scaleFactorBandsTransmittedR, FIXP_DBL *store_dmx_re_prev,
+ SHORT *store_dmx_re_prev_e, const int mainband_flag) {
+ int window, group, band;
+ UCHAR groupMask;
+ CJointStereoData *pJointStereoData =
+ &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
+ CCplxPredictionData *cplxPredictionData =
+ pAacDecoderChannelInfo[L]->pComStaticData->cplxPredictionData;
+
+ int max_sfb_ste =
+ fMax(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
+ int min_sfb_ste =
+ fMin(scaleFactorBandsTransmittedL, scaleFactorBandsTransmittedR);
+ int scaleFactorBandsTransmitted = min_sfb_ste;
+
+ if (pJointStereoData->cplx_pred_flag) {
+ int windowLen, groupwin, frameMaxScale;
+ CJointStereoPersistentData *pJointStereoPersistentData =
+ &pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData;
+ FIXP_DBL *const staticSpectralCoeffsL =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[L];
+ FIXP_DBL *const staticSpectralCoeffsR =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.spectralCoeffs[R];
+ SHORT *const staticSpecScaleL =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[L];
+ SHORT *const staticSpecScaleR =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.specScale[R];
+
+ FIXP_DBL *dmx_re =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer;
+ FIXP_DBL *dmx_re_prev =
+ pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData.scratchBuffer +
+ 1024;
+
+ /* When MS is applied over the main band this value gets computed. Otherwise
+ * (for the tiles) it uses the assigned value */
+ SHORT dmx_re_prev_e = *store_dmx_re_prev_e;
+
+ const FIXP_FILT *pCoeff;
+ const FIXP_FILT *pCoeffPrev;
+ int coeffPointerOffset;
+
+ int previousShape = (int)pJointStereoPersistentData->winShapePrev;
+ int currentShape = (int)pAacDecoderChannelInfo[L]->icsInfo.WindowShape;
+
+ /* complex stereo prediction */
+
+ /* 0. preparations */
+
+ /* 0.0. get scratch buffer for downmix MDST */
+ C_AALLOC_SCRATCH_START(dmx_im, FIXP_DBL, 1024);
+
+ /* 0.1. window lengths */
+
+ /* get length of short window for current configuration */
+ windowLen =
+ pAacDecoderChannelInfo[L]->granuleLength; /* framelength 768 => 96,
+ framelength 1024 => 128 */
+
+ /* if this is no short-block set length for long-block */
+ if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence != BLOCK_SHORT) {
+ windowLen *= 8;
+ }
+
+ /* 0.2. set pointer to filter-coefficients for MDST excitation including
+ * previous frame portions */
+ /* cp. ISO/IEC FDIS 23003-3:2011(E) table 125 */
+
+ /* set pointer to default-position */
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+
+ if (cplxPredictionData->complex_coef == 1) {
+ switch (pAacDecoderChannelInfo[L]
+ ->icsInfo.WindowSequence) { /* current window sequence */
+ case BLOCK_SHORT:
+ case BLOCK_LONG:
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ break;
+
+ case BLOCK_START:
+ if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
+ (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
+ /* a stop-start-sequence can only follow on an eight-short-sequence
+ * or a start-sequence */
+ pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
+ } else {
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ }
+ break;
+
+ case BLOCK_STOP:
+ pCoeffPrev = mdst_filt_coef_prev[2 + previousShape];
+ break;
+
+ default:
+ pCoeffPrev = mdst_filt_coef_prev[previousShape];
+ break;
+ }
+ }
+
+ /* 0.3. set pointer to filter-coefficients for MDST excitation */
+
+ /* define offset of pointer to filter-coefficients for MDST exitation
+ * employing only the current frame */
+ if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_SINE)) {
+ coeffPointerOffset = 0;
+ } else if ((previousShape == SHAPE_SINE) && (currentShape == SHAPE_KBD)) {
+ coeffPointerOffset = 2;
+ } else if ((previousShape == SHAPE_KBD) && (currentShape == SHAPE_KBD)) {
+ coeffPointerOffset = 1;
+ } else /* if ( (previousShape == SHAPE_KBD) && (currentShape == SHAPE_SINE)
+ ) */
+ {
+ coeffPointerOffset = 3;
+ }
+
+ /* set pointer to filter-coefficient table cp. ISO/IEC FDIS 23003-3:2011(E)
+ * table 124 */
+ switch (pAacDecoderChannelInfo[L]
+ ->icsInfo.WindowSequence) { /* current window sequence */
+ case BLOCK_SHORT:
+ case BLOCK_LONG:
+ pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
+ break;
+
+ case BLOCK_START:
+ if ((pJointStereoPersistentData->winSeqPrev == BLOCK_SHORT) ||
+ (pJointStereoPersistentData->winSeqPrev == BLOCK_START)) {
+ /* a stop-start-sequence can only follow on an eight-short-sequence or
+ * a start-sequence */
+ pCoeff = mdst_filt_coef_curr[12 + coeffPointerOffset];
+ } else {
+ pCoeff = mdst_filt_coef_curr[4 + coeffPointerOffset];
+ }
+ break;
+
+ case BLOCK_STOP:
+ pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset];
+ break;
+
+ default:
+ pCoeff = mdst_filt_coef_curr[coeffPointerOffset];
+ }
+
+ /* 0.4. find maximum common (l/r) band-scaling-factor for whole sequence
+ * (all windows) */
+ frameMaxScale = 0;
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ for (groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+ int windowMaxScale = 0;
+
+ /* find maximum scaling factor of all bands in this window */
+ for (band = 0; band < min_sfb_ste; band++) {
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+ int commonScale = ((lScale > rScale) ? lScale : rScale);
+ windowMaxScale =
+ (windowMaxScale < commonScale) ? commonScale : windowMaxScale;
+ }
+ if (scaleFactorBandsTransmittedL >
+ min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedL == max_sfb_ste
+ */
+ for (; band < max_sfb_ste; band++) {
+ int lScale = leftScale[band];
+ windowMaxScale =
+ (windowMaxScale < lScale) ? lScale : windowMaxScale;
+ }
+ } else {
+ if (scaleFactorBandsTransmittedR >
+ min_sfb_ste) { /* i.e. scaleFactorBandsTransmittedR == max_sfb_ste
+ */
+ for (; band < max_sfb_ste; band++) {
+ int rScale = rightScale[band];
+ windowMaxScale =
+ (windowMaxScale < rScale) ? rScale : windowMaxScale;
+ }
+ }
+ }
+
+ /* find maximum common SF of all windows */
+ frameMaxScale =
+ (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale;
+ }
+ }
+
+ /* add some headroom for overflow protection during filter and add operation
+ */
+ frameMaxScale += 2;
+
+ /* process on window-basis (i.e. iterate over all groups and corresponding
+ * windows) */
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ groupMask = 1 << group;
+
+ for (groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ /* initialize the MDST with zeros */
+ FDKmemclear(&dmx_im[windowLen * window], windowLen * sizeof(FIXP_DBL));
+
+ /* 1. calculate the previous downmix MDCT. We do this once just for the
+ * Main band. */
+ if (cplxPredictionData->complex_coef == 1) {
+ if ((cplxPredictionData->use_prev_frame == 1) && (mainband_flag)) {
+ /* if this is a long-block or the first window of a short-block
+ calculate the downmix MDCT of the previous frame.
+ use_prev_frame is assumed not to change during a frame!
+ */
+
+ /* first determine shiftfactors to scale left and right channel */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
+ BLOCK_SHORT) ||
+ (window == 0)) {
+ int index_offset = 0;
+ int srLeftChan = 0;
+ int srRightChan = 0;
+ if (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) {
+ /* use the last window of the previous frame for MDCT
+ * calculation if this is a short-block. */
+ index_offset = windowLen * 7;
+ if (staticSpecScaleL[7] > staticSpecScaleR[7]) {
+ srRightChan = staticSpecScaleL[7] - staticSpecScaleR[7];
+ dmx_re_prev_e = staticSpecScaleL[7];
+ } else {
+ srLeftChan = staticSpecScaleR[7] - staticSpecScaleL[7];
+ dmx_re_prev_e = staticSpecScaleR[7];
+ }
+ } else {
+ if (staticSpecScaleL[0] > staticSpecScaleR[0]) {
+ srRightChan = staticSpecScaleL[0] - staticSpecScaleR[0];
+ dmx_re_prev_e = staticSpecScaleL[0];
+ } else {
+ srLeftChan = staticSpecScaleR[0] - staticSpecScaleL[0];
+ dmx_re_prev_e = staticSpecScaleR[0];
+ }
+ }
+
+ /* now scale channels and determine downmix MDCT of previous frame
+ */
+ if (pAacDecoderStaticChannelInfo[L]
+ ->pCpeStaticData->jointStereoPersistentData
+ .clearSpectralCoeffs == 1) {
+ FDKmemclear(dmx_re_prev, windowLen * sizeof(FIXP_DBL));
+ dmx_re_prev_e = 0;
+ } else {
+ if (cplxPredictionData->pred_dir == 0) {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] =
+ ((staticSpectralCoeffsL[index_offset + i] >>
+ srLeftChan) +
+ (staticSpectralCoeffsR[index_offset + i] >>
+ srRightChan)) >>
+ 1;
+ }
+ } else {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] =
+ ((staticSpectralCoeffsL[index_offset + i] >>
+ srLeftChan) -
+ (staticSpectralCoeffsR[index_offset + i] >>
+ srRightChan)) >>
+ 1;
+ }
+ }
+ }
+
+ /* In case that we use INF we have to preserve the state of the
+ "dmx_re_prev" (original or computed). This is necessary because we
+ have to apply MS over the separate IGF tiles. */
+ FDKmemcpy(store_dmx_re_prev, &dmx_re_prev[0],
+ windowLen * sizeof(FIXP_DBL));
+
+ /* Particular exponent of the computed/original "dmx_re_prev" must
+ * be kept for the tile MS calculations if necessary.*/
+ *store_dmx_re_prev_e = dmx_re_prev_e;
+
+ } /* if ( (pAacDecoderChannelInfo[L]->icsInfo.WindowSequence !=
+ BLOCK_SHORT) || (window == 0) ) */
+
+ } /* if ( pJointStereoData->use_prev_frame == 1 ) */
+
+ } /* if ( pJointStereoData->complex_coef == 1 ) */
+
+ /* 2. calculate downmix MDCT of current frame */
+
+ /* set pointer to scale-factor-bands of current window */
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+
+ specScaleL[window] = specScaleR[window] = frameMaxScale;
+
+ /* adapt scaling-factors to previous frame */
+ if (cplxPredictionData->use_prev_frame == 1) {
+ if (window == 0) {
+ if (dmx_re_prev_e < frameMaxScale) {
+ if (mainband_flag == 0) {
+ scaleValues(dmx_re_prev, store_dmx_re_prev, windowLen,
+ -(frameMaxScale - dmx_re_prev_e));
+ } else {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re_prev[i] >>= (frameMaxScale - dmx_re_prev_e);
+ }
+ }
+ } else {
+ if (mainband_flag == 0) {
+ FDKmemcpy(dmx_re_prev, store_dmx_re_prev,
+ windowLen * sizeof(FIXP_DBL));
+ }
+ specScaleL[0] = dmx_re_prev_e;
+ specScaleR[0] = dmx_re_prev_e;
+ }
+ } else { /* window != 0 */
+ FDK_ASSERT(pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT);
+ if (specScaleL[window - 1] < frameMaxScale) {
+ for (int i = 0; i < windowLen; i++) {
+ dmx_re[windowLen * (window - 1) + i] >>=
+ (frameMaxScale - specScaleL[window - 1]);
+ }
+ } else {
+ specScaleL[window] = specScaleL[window - 1];
+ specScaleR[window] = specScaleR[window - 1];
+ }
+ }
+ } /* if ( pJointStereoData->use_prev_frame == 1 ) */
+
+ /* scaling factors of both channels ought to be equal now */
+ FDK_ASSERT(specScaleL[window] == specScaleR[window]);
+
+ /* rescale signal and calculate downmix MDCT */
+ for (band = 0; band < max_sfb_ste; band++) {
+ /* first adapt scaling of current band to scaling of current window =>
+ * shift signal right */
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+
+ lScale = fMin(DFRACT_BITS - 1, specScaleL[window] - lScale);
+ rScale = fMin(DFRACT_BITS - 1,
+ specScaleL[window] - rScale); /* L or R doesn't
+ matter,
+ specScales are
+ equal at this
+ point */
+
+ /* Write back to sfb scale to cover the case when max_sfb_ste <
+ * max_sfb */
+ leftScale[band] = rightScale[band] = specScaleL[window];
+
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ spectrumL[windowLen * window + i] >>= lScale;
+ spectrumR[windowLen * window + i] >>= rScale;
+ }
+
+ /* now calculate downmix MDCT */
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ spectrumL[windowLen * window + i];
+ }
+ } else {
+ if (cplxPredictionData->pred_dir == 0) {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ (spectrumL[windowLen * window + i] +
+ spectrumR[windowLen * window + i]) >>
+ 1;
+ }
+ } else {
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ dmx_re[windowLen * window + i] =
+ (spectrumL[windowLen * window + i] -
+ spectrumR[windowLen * window + i]) >>
+ 1;
+ }
+ }
+ }
+
+ } /* for ( band=0; band<max_sfb_ste; band++ ) */
+ /* Clean until the end */
+ for (int i = pScaleFactorBandOffsets[max_sfb_ste_outside];
+ i < windowLen; i++) {
+ dmx_re[windowLen * window + i] = (FIXP_DBL)0;
+ }
+
+ /* 3. calculate MDST-portion corresponding to the current frame. */
+ if (cplxPredictionData->complex_coef == 1) {
+ {
+ /* 3.1 move pointer in filter-coefficient table in case of short
+ * window sequence */
+ /* (other coefficients are utilized for the last 7 short
+ * windows) */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) &&
+ (window != 0)) {
+ pCoeff = mdst_filt_coef_curr[currentShape];
+ pCoeffPrev = mdst_filt_coef_prev[currentShape];
+ }
+
+ /* The length of the filter processing must be extended because of
+ * filter boundary problems */
+ int extended_band = fMin(
+ pScaleFactorBandOffsets[max_sfb_ste_outside] + 7, windowLen);
+
+ /* 3.2. estimate downmix MDST from current frame downmix MDCT */
+ if ((pAacDecoderChannelInfo[L]->icsInfo.WindowSequence ==
+ BLOCK_SHORT) &&
+ (window != 0)) {
+ CJointStereo_filterAndAdd(&dmx_re[windowLen * window],
+ extended_band, windowLen, pCoeff,
+ &dmx_im[windowLen * window], 1);
+
+ CJointStereo_filterAndAdd(&dmx_re[windowLen * (window - 1)],
+ extended_band, windowLen, pCoeffPrev,
+ &dmx_im[windowLen * window], 0);
+ } else {
+ CJointStereo_filterAndAdd(dmx_re, extended_band, windowLen,
+ pCoeff, dmx_im, 1);
+
+ if (cplxPredictionData->use_prev_frame == 1) {
+ CJointStereo_filterAndAdd(dmx_re_prev, extended_band, windowLen,
+ pCoeffPrev,
+ &dmx_im[windowLen * window], 0);
+ }
+ }
+
+ } /* if(pAacDecoderChannelInfo[L]->transform_splitting_active) */
+ } /* if ( pJointStereoData->complex_coef == 1 ) */
+
+ /* 4. upmix process */
+ INT pred_dir = cplxPredictionData->pred_dir ? -1 : 1;
+ /* 0.1 in Q-3.34 */
+ const FIXP_DBL pointOne = 0x66666666; /* 0.8 */
+ /* Shift value for the downmix */
+ const INT shift_dmx = SF_FNA_COEFFS + 1;
+
+ for (band = 0; band < max_sfb_ste_outside; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ FIXP_SGL tempRe =
+ (FIXP_SGL)cplxPredictionData->alpha_q_re[group][band];
+ FIXP_SGL tempIm =
+ (FIXP_SGL)cplxPredictionData->alpha_q_im[group][band];
+
+ /* Find the minimum common headroom for alpha_re and alpha_im */
+ int alpha_re_headroom = CountLeadingBits((INT)tempRe) - 16;
+ if (tempRe == (FIXP_SGL)0) alpha_re_headroom = 15;
+ int alpha_im_headroom = CountLeadingBits((INT)tempIm) - 16;
+ if (tempIm == (FIXP_SGL)0) alpha_im_headroom = 15;
+ int val = fMin(alpha_re_headroom, alpha_im_headroom);
+
+ /* Multiply alpha by 0.1 with maximum precision */
+ FDK_ASSERT(val >= 0);
+ FIXP_DBL alpha_re_tmp = fMult((FIXP_SGL)(tempRe << val), pointOne);
+ FIXP_DBL alpha_im_tmp = fMult((FIXP_SGL)(tempIm << val), pointOne);
+
+ /* Calculate alpha exponent */
+ /* (Q-3.34 * Q15.0) shifted left by "val" */
+ int alpha_re_exp = -3 + 15 - val;
+
+ int help3_shift = alpha_re_exp + 1;
+
+ FIXP_DBL *p2CoeffL = &(
+ spectrumL[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2CoeffR = &(
+ spectrumR[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2dmxIm =
+ &(dmx_im[windowLen * window + pScaleFactorBandOffsets[band]]);
+ FIXP_DBL *p2dmxRe =
+ &(dmx_re[windowLen * window + pScaleFactorBandOffsets[band]]);
+
+ for (int i = pScaleFactorBandOffsets[band];
+ i < pScaleFactorBandOffsets[band + 1]; i++) {
+ /* Calculating helper term:
+ side = specR[i] - alpha_re[i] * dmx_re[i] - alpha_im[i] *
+ dmx_im[i];
+
+ Here "dmx_re" may be the same as "specL" or alternatively keep
+ the downmix. "dmx_re" and "specL" are two different pointers
+ pointing to separate arrays, which may or may not contain the
+ same data (with different scaling).
+ */
+
+ /* help1: alpha_re[i] * dmx_re[i] */
+ FIXP_DBL help1 = fMultDiv2(alpha_re_tmp, *p2dmxRe++);
+
+ /* tmp: dmx_im[i] */
+ FIXP_DBL tmp = (*p2dmxIm++) << shift_dmx;
+
+ /* help2: alpha_im[i] * dmx_im[i] */
+ FIXP_DBL help2 = fMultDiv2(alpha_im_tmp, tmp);
+
+ /* help3: alpha_re[i] * dmx_re[i] + alpha_im[i] * dmx_im[i] */
+ FIXP_DBL help3 = help1 + help2;
+
+ /* side (= help4) = specR[i] - (dmx_re[i] * specL[i] + alpha_im[i]
+ * * dmx_im[i]) */
+ FIXP_DBL help4 = *p2CoeffR - scaleValue(help3, help3_shift);
+
+ /* We calculate the left and right output by using the helper
+ * function */
+ /* specR[i] = -/+ (specL[i] - side); */
+ *p2CoeffR =
+ (FIXP_DBL)((LONG)(*p2CoeffL - help4) * (LONG)pred_dir);
+ p2CoeffR++;
+
+ /* specL[i] = specL[i] + side; */
+ *p2CoeffL = *p2CoeffL + help4;
+ p2CoeffL++;
+ }
+ }
+
+ } /* for ( band=0; band < max_sfb_ste; band++ ) */
+ } /* for ( groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++,
+ window++ ) */
+
+ } /* for ( window = 0, group = 0; group < windowGroups; group++ ) */
+
+ /* free scratch buffer */
+ C_AALLOC_SCRATCH_END(dmx_im, FIXP_DBL, 1024);
+
+ } else {
+ /* MS stereo */
+
+ for (window = 0, group = 0; group < windowGroups; group++) {
+ groupMask = 1 << group;
+
+ for (int groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ FIXP_DBL *leftSpectrum, *rightSpectrum;
+ SHORT *leftScale = &SFBleftScale[window * 16];
+ SHORT *rightScale = &SFBrightScale[window * 16];
+
+ leftSpectrum =
+ SPEC(spectrumL, window, pAacDecoderChannelInfo[L]->granuleLength);
+ rightSpectrum =
+ SPEC(spectrumR, window, pAacDecoderChannelInfo[R]->granuleLength);
+
+ for (band = 0; band < max_sfb_ste_outside; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ int lScale = leftScale[band];
+ int rScale = rightScale[band];
+ int commonScale = lScale > rScale ? lScale : rScale;
+ unsigned int offsetCurrBand, offsetNextBand;
+
+ /* ISO/IEC 14496-3 Chapter 4.6.8.1.1 :
+ M/S joint channel coding can only be used if common_window is 1.
+ */
+ FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
+ FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
+
+ commonScale++;
+ leftScale[band] = commonScale;
+ rightScale[band] = commonScale;
+
+ lScale = fMin(DFRACT_BITS - 1, commonScale - lScale);
+ rScale = fMin(DFRACT_BITS - 1, commonScale - rScale);
+
+ FDK_ASSERT(lScale >= 0 && rScale >= 0);
+
+ offsetCurrBand = pScaleFactorBandOffsets[band];
+ offsetNextBand = pScaleFactorBandOffsets[band + 1];
+
+ CJointStereo_GenerateMSOutput(&(leftSpectrum[offsetCurrBand]),
+ &(rightSpectrum[offsetCurrBand]),
+ lScale, rScale,
+ offsetNextBand - offsetCurrBand);
+ }
+ }
+ if (scaleFactorBandsTransmittedL > scaleFactorBandsTransmitted) {
+ for (; band < scaleFactorBandsTransmittedL; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ rightScale[band] = leftScale[band];
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ FIXP_DBL leftCoefficient = leftSpectrum[index];
+ /* FIXP_DBL rightCoefficient = (FIXP_DBL)0; */
+ rightSpectrum[index] = leftCoefficient;
+ }
+ }
+ }
+ } else if (scaleFactorBandsTransmittedR > scaleFactorBandsTransmitted) {
+ for (; band < scaleFactorBandsTransmittedR; band++) {
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ leftScale[band] = rightScale[band];
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ /* FIXP_DBL leftCoefficient = (FIXP_DBL)0; */
+ FIXP_DBL rightCoefficient = rightSpectrum[index];
+
+ leftSpectrum[index] = rightCoefficient;
+ rightSpectrum[index] = -rightCoefficient;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Reset MsUsed flags if no explicit signalling was transmitted. Necessary
+ for intensity coding. PNS correlation signalling was mapped before
+ calling CJointStereo_ApplyMS(). */
+ if (pJointStereoData->MsMaskPresent == 2) {
+ FDKmemclear(pJointStereoData->MsUsed,
+ JointStereoMaximumBands * sizeof(UCHAR));
+ }
+ }
+}
+
+void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
+ const SHORT *pScaleFactorBandOffsets,
+ const UCHAR *pWindowGroupLength,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted) {
+ CJointStereoData *pJointStereoData =
+ &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
+
+ for (int window = 0, group = 0; group < windowGroups; group++) {
+ UCHAR *CodeBook;
+ SHORT *ScaleFactor;
+ UCHAR groupMask = 1 << group;
+
+ CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16];
+ ScaleFactor =
+ &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16];
+
+ for (int groupwin = 0; groupwin < pWindowGroupLength[group];
+ groupwin++, window++) {
+ FIXP_DBL *leftSpectrum, *rightSpectrum;
+ SHORT *leftScale =
+ &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window * 16];
+ SHORT *rightScale =
+ &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window * 16];
+ int band;
+
+ leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient,
+ window, pAacDecoderChannelInfo[L]->granuleLength);
+ rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient,
+ window, pAacDecoderChannelInfo[R]->granuleLength);
+
+ for (band = 0; band < scaleFactorBandsTransmitted; band++) {
+ if ((CodeBook[band] == INTENSITY_HCB) ||
+ (CodeBook[band] == INTENSITY_HCB2)) {
+ int bandScale = -(ScaleFactor[band] + 100);
+
+ int msb = bandScale >> 2;
+ int lsb = bandScale & 0x03;
+
+ /* exponent of MantissaTable[lsb][0] is 1, thus msb+1 below. */
+ FIXP_DBL scale = MantissaTable[lsb][0];
+
+ /* ISO/IEC 14496-3 Chapter 4.6.8.2.3 :
+ The use of intensity stereo coding is signaled by the use of the
+ pseudo codebooks INTENSITY_HCB and INTENSITY_HCB2 (15 and 14) only
+ in the right channel of a channel_pair_element() having a common
+ ics_info() (common_window == 1). */
+ FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
+ FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) ==
+ GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));
+
+ rightScale[band] = leftScale[band] + msb + 1;
+
+ if (pJointStereoData->MsUsed[band] & groupMask) {
+ if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */
+ {
+ scale = -scale;
+ }
+ } else {
+ if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */
+ {
+ scale = -scale;
+ }
+ }
+
+ for (int index = pScaleFactorBandOffsets[band];
+ index < pScaleFactorBandOffsets[band + 1]; index++) {
+ rightSpectrum[index] = fMult(leftSpectrum[index], scale);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/fdk-aac/libAACdec/src/stereo.h b/fdk-aac/libAACdec/src/stereo.h
new file mode 100644
index 0000000..af7a74f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/stereo.h
@@ -0,0 +1,211 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Josef Hoepfl
+
+ Description: joint stereo processing
+
+*******************************************************************************/
+
+#ifndef STEREO_H
+#define STEREO_H
+
+#include "machine_type.h"
+#include "FDK_bitstream.h"
+#include "common_fix.h"
+
+#define SFB_PER_PRED_BAND 2
+
+#define SR_FNA_OUT \
+ 0 /* Additional scaling of the CJointStereo_filterAndAdd()-output to avoid \
+ overflows. */
+ /* The scaling factor can be set to 0 if the coefficients are prescaled
+ * appropriately. */
+/* Prescaling via factor SF_FNA_COEFFS is done at compile-time but should only
+ * be */
+/* utilized if the coefficients are stored as FIXP_DBL. (cp. aac_rom.cpp/.h) */
+
+/* The NO_CPLX_PRED_BUGFIX-switch was introduced to enable decoding of
+ conformance-streams in way that they are comparable to buggy
+ reference-streams. This is established by storing the prediction direction
+ for computation of the "downmix MDCT of previous frame". This is not standard
+ compliant. Once correct reference-streams for complex-stereo-prediction are
+ available this switch becomes obsolete.
+*/
+/*#define NO_CPLX_PRED_BUGFIX*/
+
+enum { JointStereoMaximumGroups = 8, JointStereoMaximumBands = 64 };
+
+typedef struct {
+ UCHAR pred_dir; // 0 = prediction from mid to side channel, 1 = vice versa
+ UCHAR
+ igf_pred_dir; // 0 = prediction from mid to side channel, 1 = vice versa
+ UCHAR complex_coef; // 0 = alpha_q_im[x] is 0 for all prediction bands, 1 =
+ // alpha_q_im[x] is transmitted via bitstream
+ UCHAR use_prev_frame; // 0 = use current frame for MDST estimation, 1 = use
+ // current and previous frame
+
+ SHORT alpha_q_re[JointStereoMaximumGroups][JointStereoMaximumBands];
+ SHORT alpha_q_im[JointStereoMaximumGroups][JointStereoMaximumBands];
+} CCplxPredictionData;
+
+/* joint stereo scratch memory (valid for this frame) */
+typedef struct {
+ UCHAR MsMaskPresent;
+ UCHAR MsUsed[JointStereoMaximumBands]; /*!< every arry element contains flags
+ for up to 8 groups. this array is
+ also utilized for complex stereo
+ prediction. */
+ UCHAR IGF_MsMaskPresent;
+
+ UCHAR cplx_pred_flag; /* stereo complex prediction was signalled for this
+ frame */
+ UCHAR igf_cplx_pred_flag;
+
+ /* The following array and variable are needed for the case when INF is
+ * active */
+ FIXP_DBL store_dmx_re_prev[1024];
+ SHORT store_dmx_re_prev_e;
+
+} CJointStereoData;
+
+/* joint stereo persistent memory */
+typedef struct {
+ UCHAR clearSpectralCoeffs; /* indicates that the spectral coeffs must be
+ cleared because the transform splitting active
+ flag of the left and right channel was different
+ */
+
+ FIXP_DBL *scratchBuffer; /* pointer to scratch buffer */
+
+ FIXP_DBL
+ *spectralCoeffs[2]; /* spectral coefficients of this channel utilized by
+ complex stereo prediction */
+ SHORT *specScale[2];
+
+ SHORT alpha_q_re_prev[JointStereoMaximumGroups][JointStereoMaximumBands];
+ SHORT alpha_q_im_prev[JointStereoMaximumGroups][JointStereoMaximumBands];
+
+ UCHAR winSeqPrev;
+ UCHAR winShapePrev;
+ UCHAR winGroupsPrev;
+
+} CJointStereoPersistentData;
+
+/*!
+ \brief Read joint stereo data from bitstream
+
+ The function reads joint stereo data from bitstream.
+
+ \param bs bit stream handle data source.
+ \param pJointStereoData pointer to stereo data structure to receive decoded
+ data. \param windowGroups number of window groups. \param
+ scaleFactorBandsTransmitted number of transmitted scalefactor bands. \param
+ flags decoder flags
+
+ \return 0 on success, -1 on error.
+*/
+int CJointStereo_Read(HANDLE_FDK_BITSTREAM bs,
+ CJointStereoData *pJointStereoData,
+ const int windowGroups,
+ const int scaleFactorBandsTransmitted,
+ const int max_sfb_ste_clear,
+ CJointStereoPersistentData *pJointStereoPersistentData,
+ CCplxPredictionData *cplxPredictionData,
+ int cplxPredictionActiv, int scaleFactorBandsTotal,
+ int windowSequence, const UINT flags);
+
+#endif /* #ifndef STEREO_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp
new file mode 100644
index 0000000..43e06cd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.cpp
@@ -0,0 +1,439 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s):
+
+ Description: ACELP
+
+*******************************************************************************/
+
+#include "usacdec_ace_d4t64.h"
+
+#define L_SUBFR 64 /* Subframe size */
+
+/*
+ * D_ACELP_add_pulse
+ *
+ * Parameters:
+ * pos I: position of pulse
+ * nb_pulse I: number of pulses
+ * track I: track
+ * code O: fixed codebook
+ *
+ * Function:
+ * Add pulses to fixed codebook
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_add_pulse(SHORT pos[], SHORT nb_pulse, SHORT track,
+ FIXP_COD code[]) {
+ SHORT i, k;
+ for (k = 0; k < nb_pulse; k++) {
+ /* i = ((pos[k] & (16-1))*NB_TRACK) + track; */
+ i = ((pos[k] & (16 - 1)) << 2) + track;
+ if ((pos[k] & 16) == 0) {
+ code[i] = code[i] + (FIXP_COD)(512 << (COD_BITS - FRACT_BITS));
+ } else {
+ code[i] = code[i] - (FIXP_COD)(512 << (COD_BITS - FRACT_BITS));
+ }
+ }
+ return;
+}
+/*
+ * D_ACELP_decode_1p_N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 1 pulse with N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_1p_N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT pos1;
+ LONG i, mask;
+
+ mask = ((1 << N) - 1);
+ /*
+ * Decode 1 pulse with N+1 bits
+ */
+ pos1 = (SHORT)((index & mask) + offset);
+ i = ((index >> N) & 1);
+ if (i == 1) {
+ pos1 += 16;
+ }
+ pos[0] = pos1;
+ return;
+}
+/*
+ * D_ACELP_decode_2p_2N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 2 pulses with 2*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_2p_2N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT pos1, pos2;
+ LONG mask, i;
+ mask = ((1 << N) - 1);
+ /*
+ * Decode 2 pulses with 2*N+1 bits
+ */
+ pos1 = (SHORT)(((index >> N) & mask) + offset);
+ i = (index >> (2 * N)) & 1;
+ pos2 = (SHORT)((index & mask) + offset);
+ if ((pos2 - pos1) < 0) {
+ if (i == 1) {
+ pos1 += 16;
+ } else {
+ pos2 += 16;
+ }
+ } else {
+ if (i == 1) {
+ pos1 += 16;
+ pos2 += 16;
+ }
+ }
+ pos[0] = pos1;
+ pos[1] = pos2;
+ return;
+}
+/*
+ * D_ACELP_decode_3p_3N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 3 pulses with 3*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_3p_3N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j;
+ LONG mask, idx;
+
+ /*
+ * Decode 3 pulses with 3*N+1 bits
+ */
+ mask = ((1 << ((2 * N) - 1)) - 1);
+ idx = index & mask;
+ j = offset;
+ if (((index >> ((2 * N) - 1)) & 1) == 1) {
+ j += (1 << (N - 1));
+ }
+ D_ACELP_decode_2p_2N1(idx, N - 1, j, pos);
+ mask = ((1 << (N + 1)) - 1);
+ idx = (index >> (2 * N)) & mask;
+ D_ACELP_decode_1p_N1(idx, N, offset, pos + 2);
+ return;
+}
+/*
+ * D_ACELP_decode_4p_4N1
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 4 pulses with 4*N+1 bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_4p_4N1(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j;
+ LONG mask, idx;
+ /*
+ * Decode 4 pulses with 4*N+1 bits
+ */
+ mask = ((1 << ((2 * N) - 1)) - 1);
+ idx = index & mask;
+ j = offset;
+ if (((index >> ((2 * N) - 1)) & 1) == 1) {
+ j += (1 << (N - 1));
+ }
+ D_ACELP_decode_2p_2N1(idx, N - 1, j, pos);
+ mask = ((1 << ((2 * N) + 1)) - 1);
+ idx = (index >> (2 * N)) & mask;
+ D_ACELP_decode_2p_2N1(idx, N, offset, pos + 2);
+ return;
+}
+/*
+ * D_ACELP_decode_4p_4N
+ *
+ * Parameters:
+ * index I: pulse index
+ * N I: number of bits for position
+ * offset I: offset
+ * pos O: position of the pulse
+ *
+ * Function:
+ * Decode 4 pulses with 4*N bits
+ *
+ * Returns:
+ * void
+ */
+static void D_ACELP_decode_4p_4N(LONG index, SHORT N, SHORT offset,
+ SHORT pos[]) {
+ SHORT j, n_1;
+ /*
+ * Decode 4 pulses with 4*N bits
+ */
+ n_1 = N - 1;
+ j = offset + (1 << n_1);
+ switch ((index >> ((4 * N) - 2)) & 3) {
+ case 0:
+ if (((index >> ((4 * n_1) + 1)) & 1) == 0) {
+ D_ACELP_decode_4p_4N1(index, n_1, offset, pos);
+ } else {
+ D_ACELP_decode_4p_4N1(index, n_1, j, pos);
+ }
+ break;
+ case 1:
+ D_ACELP_decode_1p_N1((index >> ((3 * n_1) + 1)), n_1, offset, pos);
+ D_ACELP_decode_3p_3N1(index, n_1, j, pos + 1);
+ break;
+ case 2:
+ D_ACELP_decode_2p_2N1((index >> ((2 * n_1) + 1)), n_1, offset, pos);
+ D_ACELP_decode_2p_2N1(index, n_1, j, pos + 2);
+ break;
+ case 3:
+ D_ACELP_decode_3p_3N1((index >> (n_1 + 1)), n_1, offset, pos);
+ D_ACELP_decode_1p_N1(index, n_1, j, pos + 3);
+ break;
+ }
+ return;
+}
+
+/*
+ * D_ACELP_decode_4t
+ *
+ * Parameters:
+ * index I: index
+ * mode I: speech mode
+ * code I: (Q9) algebraic (fixed) codebook excitation
+ *
+ * Function:
+ * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
+ * 4 tracks x 16 positions per track = 64 samples.
+ *
+ * 20 bits 5+5+5+5 --> 4 pulses in a frame of 64 samples.
+ * 36 bits 9+9+9+9 --> 8 pulses in a frame of 64 samples.
+ * 44 bits 13+9+13+9 --> 10 pulses in a frame of 64 samples.
+ * 52 bits 13+13+13+13 --> 12 pulses in a frame of 64 samples.
+ * 64 bits 2+2+2+2+14+14+14+14 --> 16 pulses in a frame of 64 samples.
+ * 72 bits 10+2+10+2+10+14+10+14 --> 18 pulses in a frame of 64 samples.
+ * 88 bits 11+11+11+11+11+11+11+11 --> 24 pulses in a frame of 64 samples.
+ *
+ * All pulses can have two (2) possible amplitudes: +1 or -1.
+ * Each pulse can sixteen (16) possible positions.
+ *
+ * codevector length 64
+ * number of track 4
+ * number of position 16
+ *
+ * Returns:
+ * void
+ */
+void D_ACELP_decode_4t64(SHORT index[], int nbits, FIXP_COD code[]) {
+ LONG L_index;
+ SHORT k, pos[6];
+
+ FDKmemclear(code, L_SUBFR * sizeof(FIXP_COD));
+
+ /* decode the positions and signs of pulses and build the codeword */
+ switch (nbits) {
+ case 12:
+ for (k = 0; k < 4; k += 2) {
+ L_index = index[2 * (k / 2) + 1];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, 2 * (index[2 * (k / 2)]) + k / 2, code);
+ }
+ break;
+ case 16: {
+ int i = 0;
+ int offset = index[i++];
+ offset = (offset == 0) ? 1 : 3;
+ for (k = 0; k < 4; k++) {
+ if (k != offset) {
+ L_index = index[i++];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ }
+ } break;
+ case 20:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ break;
+ case 28:
+ for (k = 0; k < 4 - 2; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ for (k = 2; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_1p_N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 1, k, code);
+ }
+ break;
+ case 36:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ break;
+ case 44:
+ for (k = 0; k < 4 - 2; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_3p_3N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 3, k, code);
+ }
+ for (k = 2; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_2p_2N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 2, k, code);
+ }
+ break;
+ case 52:
+ for (k = 0; k < 4; k++) {
+ L_index = (LONG)index[k];
+ D_ACELP_decode_3p_3N1(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 3, k, code);
+ }
+ break;
+ case 64:
+ for (k = 0; k < 4; k++) {
+ L_index = (((LONG)index[k] << 14) + (LONG)index[k + 4]);
+ D_ACELP_decode_4p_4N(L_index, 4, 0, pos);
+ D_ACELP_add_pulse(pos, 4, k, code);
+ }
+ break;
+ default:
+ FDK_ASSERT(0);
+ }
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_d4t64.h b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.h
new file mode 100644
index 0000000..76bc3d9
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_d4t64.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 decoder library ******************************
+
+ Author(s):
+
+ Description: ACELP
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACE_D4T64_H
+#define USACDEC_ACE_D4T64_H
+
+#include "common_fix.h"
+
+/* Data type definition for the fixed codebook vector */
+#define FIXP_COD FIXP_SGL
+#define FX_COD2FX_DBL(x) (FX_SGL2FX_DBL(x))
+#define FX_DBL2FX_COD(x) FX_DBL2FX_SGL((x) + (FIXP_DBL)0x8000)
+#define FX_SGL2FX_COD(x) (x)
+#define COD_BITS FRACT_BITS
+
+void D_ACELP_decode_4t64(SHORT index[], int nbits, FIXP_COD code[]);
+
+#endif /* USACDEC_ACE_D4T64_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp b/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp
new file mode 100644
index 0000000..5964b49
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_ltp.cpp
@@ -0,0 +1,229 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP LTP filter
+
+*******************************************************************************/
+
+#include "usacdec_ace_ltp.h"
+
+#include "genericStds.h"
+#include "common_fix.h"
+
+#define UP_SAMP 4
+#define L_INTERPOL2 16
+#define L_SUBFR 64
+
+#define A2 FL2FX_SGL(2 * 0.18f)
+#define B FL2FX_SGL(0.64f)
+
+static const LONG Pred_lt4_inter4_2[UP_SAMP][L_INTERPOL2] = {
+ {(LONG)0x0000FFFC, (LONG)0x0008FFFC, (LONG)0xFFEB004C, (LONG)0xFF50014A,
+ (LONG)0xFDD90351, (LONG)0xFB2A06CD, (LONG)0xF6920D46, (LONG)0xEBB42B35,
+ (LONG)0x6D9EEF39, (LONG)0x0618FE0F, (LONG)0xFFE00131, (LONG)0xFE5501C5,
+ (LONG)0xFE5E015D, (LONG)0xFEF700B6, (LONG)0xFF920037, (LONG)0xFFEC0003},
+ {(LONG)0x0002FFF2, (LONG)0x0026FFBD, (LONG)0x005DFF98, (LONG)0x0055FFEF,
+ (LONG)0xFF89015F, (LONG)0xFD3A04E5, (LONG)0xF7D90DAA, (LONG)0xE67A50EE,
+ (LONG)0x50EEE67A, (LONG)0x0DAAF7D9, (LONG)0x04E5FD3A, (LONG)0x015FFF89,
+ (LONG)0xFFEF0055, (LONG)0xFF98005D, (LONG)0xFFBD0026, (LONG)0xFFF20002},
+ {(LONG)0x0003FFEC, (LONG)0x0037FF92, (LONG)0x00B6FEF7, (LONG)0x015DFE5E,
+ (LONG)0x01C5FE55, (LONG)0x0131FFE0, (LONG)0xFE0F0618, (LONG)0xEF396D9E,
+ (LONG)0x2B35EBB4, (LONG)0x0D46F692, (LONG)0x06CDFB2A, (LONG)0x0351FDD9,
+ (LONG)0x014AFF50, (LONG)0x004CFFEB, (LONG)0xFFFC0008, (LONG)0xFFFC0000},
+ {(LONG)0x0002FFF2, (LONG)0x002BFF9E, (LONG)0x00B9FECE, (LONG)0x01CFFD75,
+ (LONG)0x035EFBC1, (LONG)0x0521FA0C, (LONG)0x06AAF8C9, (LONG)0x07907852,
+ (LONG)0x0790F8C9, (LONG)0x06AAFA0C, (LONG)0x0521FBC1, (LONG)0x035EFD75,
+ (LONG)0x01CFFECE, (LONG)0x00B9FF9E, (LONG)0x002BFFF2, (LONG)0x00020000}};
+
+void Pred_lt4(FIXP_DBL exc[], /* in/out: excitation buffer */
+ int T0, /* input : integer pitch lag */
+ int frac /* input : fraction of lag in range 0..3 */
+) {
+ int j;
+ FIXP_DBL *x;
+ const LONG *interpol;
+ FIXP_DBL L_sumb, L_sumt;
+
+ x = &exc[-T0 - L_INTERPOL2 + 1];
+
+ /* remap frac and x:
+ 0 -> 3 x (unchanged)
+ 1 -> 0 x--
+ 2 -> 1 x--
+ 3 -> 2 x--
+ */
+
+ if (--frac < 0)
+ frac += UP_SAMP;
+ else
+ x--;
+
+ j = L_SUBFR + 1;
+ do {
+ LONG filt;
+ FIXP_DBL x0, x1;
+ FIXP_DBL *xi = x++;
+ interpol = Pred_lt4_inter4_2[frac];
+ int i = 3;
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultDiv2(x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultDiv2(x1, (FIXP_SGL)((SHORT)filt));
+ do {
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+
+ filt = *interpol++;
+ x0 = *xi++;
+ x1 = *xi++;
+ L_sumt = fMultAddDiv2(L_sumt, x0, (FIXP_SGL)((SHORT)(filt >> 16)));
+ L_sumb = fMultAddDiv2(L_sumb, x1, (FIXP_SGL)((SHORT)filt));
+ } while (--i != 0);
+
+ L_sumb <<= 1;
+ L_sumb = fAddSaturate(L_sumt << 1, L_sumb);
+ *exc++ = L_sumb;
+ } while (--j != 0);
+ return;
+}
+
+void Pred_lt4_postfilter(FIXP_DBL exc[] /* in/out: excitation buffer */
+) {
+ /*
+ exc[i] = A*exc[i-1] + B*exc[i] + A*exc[i+1]
+ exc[i+1] = A*exc[i] + B*exc[i+1] + A*exc[i+2] ; i = 0:2:62
+ */
+ int i;
+ FIXP_DBL sum0, sum1, a_exc0, a_exc1;
+ a_exc0 = fMultDiv2(A2, exc[-1]);
+ a_exc1 = fMultDiv2(A2, exc[0]);
+
+ /* ARM926: 22 cycles/iteration */
+ for (i = 0; i < L_SUBFR; i += 2) {
+ sum0 = a_exc0 + fMult(B, exc[i]);
+ sum1 = a_exc1 + fMult(B, exc[i + 1]);
+ a_exc0 = fMultDiv2(A2, exc[i + 1]);
+ a_exc1 = fMultDiv2(A2, exc[i + 2]);
+ exc[i] = sum0 + a_exc0;
+ exc[i + 1] = sum1 + a_exc1;
+ }
+ return;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_ace_ltp.h b/fdk-aac/libAACdec/src/usacdec_ace_ltp.h
new file mode 100644
index 0000000..5128acd
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_ace_ltp.h
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP LTP filter
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACE_LTP_H
+#define USACDEC_ACE_LTP_H
+
+#include "common_fix.h"
+
+/**
+ * \brief Compute the initial adaptive codebook excitation v'(n) by
+ * interpolating the past excitation vector u'(n).
+ * \param exc points to adaptive codebook of current subframe (input/output)
+ * \param T0 integer part of decoded pitch lag (input)
+ * \param frac fractional part of decoded pitch lag (0..3) (input)
+ */
+void Pred_lt4(FIXP_DBL exc[], /* in/out: excitation buffer */
+ int T0, /* input : integer pitch lag */
+ int frac /* input : fraction of lag */
+);
+
+/**
+ * \brief Compute the adaptive codebook excitation v(n) in case of
+ * ltp_filtering_flag == 0.
+ * \param exc points to adaptive codebook of current subframe (input/output)
+ */
+void Pred_lt4_postfilter(FIXP_DBL exc[] /* in/out: excitation buffer */
+);
+
+#endif /* USACDEC_ACE_LTP_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_acelp.cpp b/fdk-aac/libAACdec/src/usacdec_acelp.cpp
new file mode 100644
index 0000000..a606459
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_acelp.cpp
@@ -0,0 +1,1296 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP frame decoder
+
+*******************************************************************************/
+
+#include "usacdec_acelp.h"
+
+#include "usacdec_ace_d4t64.h"
+#include "usacdec_ace_ltp.h"
+#include "usacdec_rom.h"
+#include "usacdec_lpc.h"
+#include "genericStds.h"
+
+#define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2 */
+#define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1 */
+#define TILT_CODE2 \
+ FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 ) */
+#define PIT_SHARP \
+ FL2FXCONST_SGL(0.85f) /* pitch sharpening factor */
+#define PREEMPH_FAC \
+ FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor */
+
+#define ACELP_HEADROOM 1
+#define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)
+
+/**
+ * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
+ * \param[in] in pointer to input signal; in[-1] is also needed.
+ * \param[out] out pointer to output signal.
+ * \param[in] L length of filtering.
+ */
+/* static */
+void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
+ int i;
+
+ for (i = 0; i < L; i++) {
+ out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
+ }
+
+ return;
+}
+
+/**
+ * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
+ * vector.
+ * \param[in,out] x innovative codebook vector.
+ */
+static void Preemph_code(
+ FIXP_COD x[] /* (i/o) : input signal overwritten by the output */
+) {
+ int i;
+ FIXP_DBL L_tmp;
+
+ /* ARM926: 12 cycles per sample */
+ for (i = L_SUBFR - 1; i > 0; i--) {
+ L_tmp = FX_COD2FX_DBL(x[i]);
+ L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
+ x[i] = FX_DBL2FX_COD(L_tmp);
+ }
+}
+
+/**
+ * \brief Apply pitch sharpener to the innovative codebook vector.
+ * \param[in,out] x innovative codebook vector.
+ * \param[in] pit_lag decoded pitch lag.
+ */
+static void Pit_shrp(
+ FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
+ int pit_lag /* input : pitch lag */
+) {
+ int i;
+ FIXP_DBL L_tmp;
+
+ for (i = pit_lag; i < L_SUBFR; i++) {
+ L_tmp = FX_COD2FX_DBL(x[i]);
+ L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
+ x[i] = FX_DBL2FX_COD(L_tmp);
+ }
+
+ return;
+}
+
+ /**
+ * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
+ * Innovative code vector energy.
+ * \param[in] index index of quantizer.
+ * \param[in] code innovative code vector with exponent = SF_CODE.
+ * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
+ * \param[out] gain_code Quantized codebook gain g_c.
+ * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
+ * \param[out] E_code unbiased innovative code vector energy.
+ * \param[out] E_code_e exponent of unbiased innovative code vector energy.
+ */
+
+#define SF_MEAN_ENER_LG10 9
+
+/* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
+static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
+ 0x1f791f65, 0x7d4bfba3};
+
+static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
+ FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
+ FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
+ FIXP_DBL *pEner_code, int *pEner_code_e) {
+ FIXP_DBL Ltmp;
+ FIXP_DBL gcode0, gcode_inov;
+ INT gcode0_e, gcode_inov_e;
+ int i;
+
+ FIXP_DBL ener_code;
+ INT ener_code_e;
+
+ /* ener_code = sum(code[]^2) */
+ ener_code = FIXP_DBL(0);
+ for (i = 0; i < L_SUBFR; i++) {
+ ener_code += fPow2Div2(code[i]);
+ }
+
+ ener_code_e = fMax(fNorm(ener_code) - 1, 0);
+ ener_code <<= ener_code_e;
+ ener_code_e = 2 * SF_CODE + 1 - ener_code_e;
+
+ /* export energy of code for calc_period_factor() */
+ *pEner_code = ener_code;
+ *pEner_code_e = ener_code_e;
+
+ ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);
+
+ /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
+ * below). */
+ if (ener_code_e & 1) {
+ ener_code_e -= 5;
+ ener_code >>= 1;
+ } else {
+ ener_code_e -= 6;
+ }
+ gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
+ gcode_inov_e = gcode0_e - (ener_code_e >> 1);
+
+ if (bfi) {
+ FIXP_DBL tgcode;
+ FIXP_SGL tgpit;
+
+ tgpit = *past_gpit;
+
+ if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
+ tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
+ } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
+ tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
+ }
+ *gain_pit = tgpit;
+ tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
+ *past_gpit = tgpit;
+
+ tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
+ tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
+ *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
+ *past_gcode = tgcode;
+
+ return;
+ }
+
+ /*-------------- Decode gains ---------------*/
+ /*
+ gcode0 = pow(10.0, (float)mean_ener/20.0);
+ gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
+ */
+ gcode0 = pow_10_mean_energy[mean_ener_bits];
+ gcode0 = fMultDiv2(gcode0, gcode_inov);
+ gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;
+
+ i = index << 1;
+ *gain_pit = fdk_t_qua_gain7b[i]; /* adaptive codebook gain */
+ /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
+ Ltmp = fMult(fdk_t_qua_gain7b[i + 1], gcode0);
+ *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);
+
+ /* update bad frame handler */
+ *past_gpit = *gain_pit;
+
+ /*--------------------------------------------------------
+ past_gcode = gain_code/gcode_inov
+ --------------------------------------------------------*/
+ {
+ FIXP_DBL gcode_m;
+ INT gcode_e;
+
+ gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
+ gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
+ *past_gcode = scaleValue(gcode_m, gcode_e);
+ }
+}
+
+/**
+ * \brief Calculate period/voicing factor r_v
+ * \param[in] exc pitch excitation.
+ * \param[in] gain_pit gain of pitch g_p.
+ * \param[in] gain_code gain of code g_c.
+ * \param[in] gain_code_e exponent of gain of code.
+ * \param[in] ener_code unbiased innovative code vector energy.
+ * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
+ * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
+ */
+static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
+ FIXP_DBL gain_code, FIXP_DBL ener_code,
+ int ener_code_e) {
+ int ener_exc_e, L_tmp_e, s = 0;
+ FIXP_DBL ener_exc, L_tmp;
+ FIXP_DBL period_fac;
+
+ /* energy of pitch excitation */
+ ener_exc = (FIXP_DBL)0;
+ for (int i = 0; i < L_SUBFR; i++) {
+ ener_exc += fPow2Div2(exc[i]) >> s;
+ if (ener_exc >= FL2FXCONST_DBL(0.5f)) {
+ ener_exc >>= 1;
+ s++;
+ }
+ }
+
+ ener_exc_e = fNorm(ener_exc);
+ ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
+ if (ener_exc != (FIXP_DBL)0) {
+ ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
+ } else {
+ ener_exc_e = 0;
+ }
+
+ /* energy of innovative code excitation */
+ /* L_tmp = ener_code * gain_code*gain_code; */
+ L_tmp_e = fNorm(gain_code);
+ L_tmp = fPow2(gain_code << L_tmp_e);
+ L_tmp = fMult(ener_code, L_tmp);
+ L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;
+
+ /* Find common exponent */
+ {
+ FIXP_DBL num, den;
+ int exp_diff;
+
+ exp_diff = ener_exc_e - L_tmp_e;
+ if (exp_diff >= 0) {
+ ener_exc >>= 1;
+ if (exp_diff <= DFRACT_BITS - 2) {
+ L_tmp >>= exp_diff + 1;
+ } else {
+ L_tmp = (FIXP_DBL)0;
+ }
+ den = ener_exc + L_tmp;
+ if (ener_exc_e < DFRACT_BITS - 1) {
+ den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
+ }
+ } else {
+ if (exp_diff >= -(DFRACT_BITS - 2)) {
+ ener_exc >>= 1 - exp_diff;
+ } else {
+ ener_exc = (FIXP_DBL)0;
+ }
+ L_tmp >>= 1;
+ den = ener_exc + L_tmp;
+ if (L_tmp_e < DFRACT_BITS - 1) {
+ den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
+ }
+ }
+ num = (ener_exc - L_tmp);
+ num >>= SF_PFAC;
+
+ if (den > (FIXP_DBL)0) {
+ if (ener_exc > L_tmp) {
+ period_fac = schur_div(num, den, 16);
+ } else {
+ period_fac = -schur_div(-num, den, 16);
+ }
+ } else {
+ period_fac = (FIXP_DBL)MAXVAL_DBL;
+ }
+ }
+
+ /* exponent = SF_PFAC */
+ return period_fac;
+}
+
+/*------------------------------------------------------------*
+ * noise enhancer *
+ * ~~~~~~~~~~~~~~ *
+ * - Enhance excitation on noise. (modify gain of code) *
+ * If signal is noisy and LPC filter is stable, move gain *
+ * of code 1.5 dB toward gain of code threshold. *
+ * This decrease by 3 dB noise energy variation. *
+ *------------------------------------------------------------*/
+/**
+ * \brief Enhance excitation on noise. (modify gain of code)
+ * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
+ * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
+ * \param[in] stab_fac stability factor, exponent = SF_STAB.
+ * \param[in,out] p_gc_threshold modified gain of previous subframe.
+ * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
+ */
+static FIXP_DBL
+noise_enhancer(/* (o) : smoothed gain g_sc SF_GAIN_C */
+ FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
+ FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
+ 1=voiced), SF_PFAC */
+ FIXP_SGL stab_fac, /* (i) : stability factor (0 <= ... < 1.0)
+ SF_STAB */
+ FIXP_DBL
+ *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
+{
+ FIXP_DBL fac, L_tmp, gc_thres;
+
+ gc_thres = *p_gc_threshold;
+
+ L_tmp = gain_code;
+ if (L_tmp < gc_thres) {
+ L_tmp += fMultDiv2(gain_code,
+ FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
+ if (L_tmp > gc_thres) {
+ L_tmp = gc_thres;
+ }
+ } else {
+ L_tmp = fMult(gain_code,
+ FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
+ if (L_tmp < gc_thres) {
+ L_tmp = gc_thres;
+ }
+ }
+ *p_gc_threshold = L_tmp;
+
+ /* voicing factor lambda = 0.5*(1-period_fac) */
+ /* gain smoothing factor S_m = lambda*stab_fac (=fac)
+ = 0.5(stab_fac - stab_fac * period_fac) */
+ fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
+ fMultDiv2(stab_fac, period_fac);
+ /* fac_e = SF_PFAC + SF_STAB */
+ FDK_ASSERT(fac >= (FIXP_DBL)0);
+
+ /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
+ gain_code = fMult(fac, L_tmp) -
+ fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
+ gain_code);
+ gain_code <<= (SF_PFAC + SF_STAB);
+
+ return gain_code;
+}
+
+/**
+ * \brief Update adaptive codebook u'(n) (exc)
+ * Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
+ * \param[in] code innovative codevector c(n), exponent = SF_CODE.
+ * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
+ * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
+ * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
+ * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
+ * SF_GAIN_C.
+ * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
+ * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
+ */
+void BuildAdaptiveExcitation(
+ FIXP_COD code[], /* (i) : algebraic codevector c(n) Q9 */
+ FIXP_DBL exc[], /* (io): filtered adaptive codebook v(n) Q15 */
+ FIXP_SGL gain_pit, /* (i) : adaptive codebook gain g_p Q14 */
+ FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c Q16 */
+ FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
+ Q16 */
+ FIXP_DBL period_fac, /* (i) : periodicity factor r_v Q15 */
+ FIXP_DBL exc2[] /* (o) : post-processed excitation u(n) Q15 */
+) {
+/* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
+ If exc2[i] is written, code[i] will be destroyed!
+*/
+#define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
+
+ int i;
+ FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
+
+ FIXP_COD code_i;
+ FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;
+
+ /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
+ cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
+
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
+ *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
+
+ /* u(n) */
+ code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
+ << SF; /* c(0) * g_sc */
+ code_i = *code++;
+ code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
+ tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
+ cpe_code_smooth = fMultDiv2(cpe, code_smooth);
+ *exc2++ = tmp - cpe_code_smooth;
+ cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
+
+ i = L_SUBFR - 2;
+ do /* ARM926: 22 cycles per iteration */
+ {
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
+ *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
+ /* u(n) */
+ tmp += code_smooth; /* += g_sc * c(i) */
+ tmp -= cpe_code_smooth_prev;
+ cpe_code_smooth_prev = cpe_code_smooth;
+ code_i = *code++;
+ code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
+ cpe_code_smooth = fMultDiv2(cpe, code_smooth);
+ *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
+ } while (--i != 0);
+
+ /* u'(n) */
+ tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
+ *exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
+ /* u(n) */
+ tmp += code_smooth;
+ tmp -= cpe_code_smooth_prev;
+ *exc2++ = tmp;
+
+ return;
+}
+
+/**
+ * \brief Interpolate LPC vector in LSP domain for current subframe and convert
+ * to LP domain
+ * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
+ * current ACELP frame.
+ * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
+ * current ACELP frame.
+ * \param[in] subfr_nr number of current ACELP subframe 0..3.
+ * \param[in] nb_subfr total number of ACELP subframes in this frame.
+ * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
+ * SF_A_COEFFS.
+ */
+/* static */
+void int_lpc_acelp(
+ const FIXP_LPC lsp_old[], /* input : LSPs from past frame */
+ const FIXP_LPC lsp_new[], /* input : LSPs from present frame */
+ int subfr_nr, int nb_subfr,
+ FIXP_LPC
+ A[], /* output: interpolated LP coefficients for current subframe */
+ INT *A_exp) {
+ int i;
+ FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
+ FIXP_SGL fac_old, fac_new;
+
+ FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));
+
+ fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
+ fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp_interpol[i] = FX_DBL2FX_LPC(
+ (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
+ }
+
+ E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);
+
+ return;
+}
+
+/**
+ * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
+ * through the LP synthesis filter 1/A(z)
+ * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
+ * \param[in] length length of input/output signal.
+ * \param[in] x post-processed excitation u(n).
+ * \param[in,out] y LP synthesis signal and filter memory
+ * y[-M_LP_FILTER_ORDER..-1].
+ */
+
+/* static */
+void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
+ const INT a_exp,
+ INT length, /* (i) : length of input/output signal (64|128) */
+ FIXP_DBL x[], /* (i) : input signal Qx */
+ FIXP_DBL y[] /* (i/o) : filter states / output signal Qx-s*/
+) {
+ int i, j;
+ FIXP_DBL L_tmp;
+
+ for (i = 0; i < length; i++) {
+ L_tmp = (FIXP_DBL)0;
+
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
+ y[i] = fAddSaturate(L_tmp, x[i]);
+ }
+
+ return;
+}
+
+/**
+ * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
+ * \param[in] x input signal.
+ * \param[out] y output signal.
+ * \param[in] L length of signal.
+ * \param[in,out] mem memory (signal[-1]).
+ */
+/* static */
+void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
+ int i;
+ FIXP_DBL yi = *mem;
+
+ for (i = 0; i < L; i++) {
+ FIXP_DBL xi = x[i] >> 1;
+ xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
+ yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
+ y[i] = yi;
+ }
+ *mem = yi;
+ return;
+}
+
+/**
+ * \brief Compute the LP residual by filtering the input speech through the
+ * analysis filter A(z).
+ * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
+ * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
+ * SF_SYNTH
+ * \param[out] y output signal (residual), exponent = SF_EXC
+ * \param[in] l length of filtering
+ */
+/* static */
+void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
+ INT l) {
+ FIXP_DBL s;
+ INT i, j;
+
+ /* (note that values x[-m..-1] are needed) */
+ for (i = 0; i < l; i++) {
+ s = (FIXP_DBL)0;
+
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ s = scaleValue(s, a_exp + LP_FILTER_SCALE);
+ y[i] = fAddSaturate(s, x[i]);
+ }
+
+ return;
+}
+
+/* use to map subfr number to number of bits used for acb_index */
+static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
+ {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
+ {9, 6, 6, 0} /* coreCoderFrameLength == 768 */
+};
+
+static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
+ const UCHAR num_acb_idx_bits,
+ const int PIT_MIN, /* TMIN */
+ const int PIT_FR2, /* TFR2 */
+ const int PIT_FR1, /* TFR1 */
+ const int PIT_MAX, /* TMAX */
+ int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
+ int acb_idx;
+ int error = 0;
+ int T0, T0_frac;
+
+ FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));
+
+ acb_idx = FDKreadBits(hBs, num_acb_idx_bits);
+
+ if (num_acb_idx_bits == 6) {
+ /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
+ always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
+ the fractional pitch lag of the previous subframe.
+ */
+ T0 = *pT0_min + acb_idx / 4;
+ T0_frac = acb_idx & 0x3;
+ } else { /* num_acb_idx_bits == 9 */
+ /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
+ used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
+ 0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
+ TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
+ */
+ int T0_min, T0_max;
+
+ if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
+ /* first interval with 0.25 pitch resolution */
+ T0 = PIT_MIN + (acb_idx / 4);
+ T0_frac = acb_idx & 0x3;
+ } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
+ /* second interval with 0.5 pitch resolution */
+ acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
+ T0 = PIT_FR2 + (acb_idx / 2);
+ T0_frac = (acb_idx & 0x1) * 2;
+ } else {
+ /* third interval with 1.0 pitch resolution */
+ T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
+ ((PIT_FR1 - PIT_FR2) * 2);
+ T0_frac = 0;
+ }
+ /* find T0_min and T0_max for subframe 1 or 3 */
+ T0_min = T0 - 8;
+ if (T0_min < PIT_MIN) {
+ T0_min = PIT_MIN;
+ }
+ T0_max = T0_min + 15;
+ if (T0_max > PIT_MAX) {
+ T0_max = PIT_MAX;
+ T0_min = T0_max - 15;
+ }
+ *pT0_min = T0_min;
+ *pT0_max = T0_max;
+ }
+ *pT0 = T0;
+ *pT0_frac = T0_frac;
+
+ return error;
+}
+static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
+ int *pT0, int *pT0_frac) {
+ USHORT *pold_T0 = &acelp_mem->old_T0;
+ UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
+
+ if ((int)*pold_T0 >= PIT_MAX) {
+ *pold_T0 = (UCHAR)(PIT_MAX - 5);
+ }
+ *pT0 = (int)*pold_T0;
+ *pT0_frac = (int)*pold_T0_frac;
+}
+
+static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};
+
+static int MapCoreMode2NBits(int core_mode) {
+ return (int)tab_coremode2nbits[core_mode];
+}
+
+void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
+ INT numLostSubframes, int lastLpcLost, int frameCnt,
+ FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
+ INT coreCoderFrameLength) {
+ int i_subfr, subfr_nr, l_div, T;
+ int T0 = -1, T0_frac = -1; /* mark invalid */
+
+ int pit_gain_index = 0;
+
+ const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */
+
+ FIXP_COD *code;
+ FIXP_DBL *exc2;
+ FIXP_DBL *syn;
+ FIXP_DBL *exc;
+ FIXP_LPC A[M_LP_FILTER_ORDER];
+ INT A_exp;
+
+ FIXP_DBL period_fac;
+ FIXP_SGL gain_pit;
+ FIXP_DBL gain_code, gain_code_smooth, Ener_code;
+ int Ener_code_e;
+ int n;
+ int bfi = (numLostSubframes > 0) ? 1 : 0;
+
+ C_ALLOC_SCRATCH_START(
+ exc_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
+ C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
+ M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
+ /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
+ C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
+ /* make sure they don't overlap if they are accessed alternatingly in
+ * BuildAdaptiveExcitation() */
+#if (COD_BITS == FRACT_BITS)
+ code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
+#elif (COD_BITS == DFRACT_BITS)
+ code = (FIXP_COD *)tmp_buf;
+#endif
+ exc2 = (FIXP_DBL *)tmp_buf;
+
+ syn = syn_buf + M_LP_FILTER_ORDER;
+ exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
+
+ FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
+ (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+
+ FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
+ (L_DIV + 1) * sizeof(FIXP_DBL));
+
+ l_div = coreCoderFrameLength / NB_DIV;
+
+ for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
+ i_subfr += L_SUBFR, subfr_nr++) {
+ /*-------------------------------------------------*
+ * - Decode pitch lag (T0 and T0_frac) *
+ *-------------------------------------------------*/
+ if (bfi) {
+ ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
+ } else {
+ T0 = (int)pAcelpData->T0[subfr_nr];
+ T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
+ }
+
+ /*-------------------------------------------------*
+ * - Find the pitch gain, the interpolation filter *
+ * and the adaptive codebook vector. *
+ *-------------------------------------------------*/
+ Pred_lt4(&exc[i_subfr], T0, T0_frac);
+
+ if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
+ (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
+ /* find pitch excitation with lp filter: v'(n) => v(n) */
+ Pred_lt4_postfilter(&exc[i_subfr]);
+ }
+
+ /*-------------------------------------------------------*
+ * - Decode innovative codebook. *
+ * - Add the fixed-gain pitch contribution to code[]. *
+ *-------------------------------------------------------*/
+ if (bfi) {
+ for (n = 0; n < L_SUBFR; n++) {
+ code[n] =
+ FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
+ }
+ } else {
+ int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
+ D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
+ }
+
+ T = T0;
+ if (T0_frac > 2) {
+ T += 1;
+ }
+
+ Preemph_code(code);
+ Pit_shrp(code, T);
+
+ /* Output pitch lag for bass post-filter */
+ if (T > PIT_MAX) {
+ pT[subfr_nr] = PIT_MAX;
+ } else {
+ pT[subfr_nr] = T;
+ }
+ D_gain2_plus(
+ pAcelpData->gains[subfr_nr],
+ code, /* (i) : Innovative code vector, exponent = SF_CODE */
+ &gain_pit, /* (o) : Quantized pitch gain, exponent = SF_GAIN_P */
+ &gain_code, /* (o) : Quantized codebook gain */
+ pAcelpData
+ ->mean_energy, /* (i) : mean_ener defined in open-loop (2 bits) */
+ bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
+ &Ener_code, /* (o) : Innovative code vector energy */
+ &Ener_code_e); /* (o) : Innovative code vector energy exponent */
+
+ pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);
+
+ /* calc periodicity factor r_v */
+ period_fac =
+ calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced) */
+ &exc[i_subfr], /* (i) : pitch excitation, exponent =
+ SF_EXC */
+ gain_pit, /* (i) : gain of pitch, exponent =
+ SF_GAIN_P */
+ gain_code, /* (i) : gain of code */
+ Ener_code, /* (i) : Energy of code[] */
+ Ener_code_e); /* (i) : Exponent of energy of code[]
+ */
+
+ if (lastLpcLost && frameCnt == 0) {
+ if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
+ gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
+ }
+ }
+
+ gain_code_smooth =
+ noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
+ gain_code, /* (i) : Quantized codebook gain */
+ period_fac, /* (i) : periodicity factor (-1=unvoiced to
+ 1=voiced) */
+ stab_fac, /* (i) : stability factor (0 <= ... < 1),
+ exponent = 1 */
+ &acelp_mem->gc_threshold);
+
+ /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
+ * post-processed excitation u(n). */
+ BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
+ gain_code_smooth, period_fac, exc2);
+
+ /* Interpolate filter coeffs for current subframe in lsp domain and convert
+ * to LP domain */
+ int_lpc_acelp(lsp_old, /* input : LSPs from past frame */
+ lsp_new, /* input : LSPs from present frame */
+ subfr_nr, /* input : ACELP subframe index */
+ coreCoderFrameLength / L_DIV,
+ A, /* output: LP coefficients of this subframe */
+ &A_exp);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ exc2, /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ } /* end of subframe loop */
+
+ /* update pitch value for bfi procedure */
+ acelp_mem->old_T0_frac = T0_frac;
+ acelp_mem->old_T0 = T0;
+
+ /* save old excitation and old synthesis memory for next ACELP frame */
+ FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
+ FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
+ sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
+
+ Deemph(syn, synth, l_div,
+ &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */
+
+ scaleValues(synth, l_div, -ACELP_OUTSCALE);
+ acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;
+
+ C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
+ C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
+ C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
+ return;
+}
+
+void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
+ acelp->gc_threshold = (FIXP_DBL)0;
+
+ acelp->past_gpit = (FIXP_SGL)0;
+ acelp->past_gcode = (FIXP_DBL)0;
+ acelp->old_T0 = 64;
+ acelp->old_T0_frac = 0;
+ acelp->deemph_mem_wsyn = (FIXP_DBL)0;
+ acelp->wsyn_rms = (FIXP_DBL)0;
+ acelp->seed_ace = 0;
+}
+
+/* TCX time domain concealment */
+/* Compare to figure 13a on page 54 in 3GPP TS 26.290 */
+void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
+ INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
+ /* repeat past excitation with pitch from previous decoded TCX frame */
+ C_ALLOC_SCRATCH_START(
+ exc_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 + 17 + 256 + 1 = */
+ C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
+ M_LP_FILTER_ORDER + L_DIV); /* 256 + 16 = */
+ /* += */
+ FIXP_DBL ns_buf[L_DIV + 1];
+ FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
+ FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
+ FIXP_DBL *ns = ns_buf + 1;
+ FIXP_DBL tmp, fact_exc;
+ INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
+ int i, i_subfr, subfr_nr;
+ int lDiv = coreCoderFrameLength / NB_DIV;
+
+ FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
+ (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+
+ /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
+ the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
+ coded frame extrapolation strategy: repeat lost excitation and
+ use extrapolated LSFs */
+
+ /* AMR-WB+ like TCX TD concealment */
+
+ /* number of lost frame cmpt */
+ if (nLostSf < 2) {
+ fact_exc = FL2FXCONST_DBL(0.8f);
+ } else {
+ fact_exc = FL2FXCONST_DBL(0.4f);
+ }
+
+ /* repeat past excitation */
+ for (i = 0; i < lDiv; i++) {
+ exc[i] = fMult(fact_exc, exc[i - T]);
+ }
+
+ tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
+ acelp_mem->wsyn_rms = tmp;
+
+ /* init deemph_mem_wsyn */
+ acelp_mem->deemph_mem_wsyn = exc[-1];
+
+ ns[-1] = acelp_mem->deemph_mem_wsyn;
+
+ for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
+ i_subfr += L_SUBFR, subfr_nr++) {
+ FIXP_DBL tRes[L_SUBFR];
+ FIXP_LPC A[M_LP_FILTER_ORDER];
+ INT A_exp;
+
+ /* interpolate LPC coefficients */
+ int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ &exc[i_subfr], /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ E_LPC_a_weight(
+ A, A,
+ M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */
+
+ E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);
+
+ Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);
+
+ /* Amplitude limiter (saturate at wsyn_rms) */
+ for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
+ if (ns[i] > tmp) {
+ ns[i] = tmp;
+ } else {
+ if (ns[i] < -tmp) {
+ ns[i] = -tmp;
+ }
+ }
+ }
+
+ E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);
+
+ Syn_filt(A, /* (i) : a[m] prediction coefficients */
+ A_exp, L_SUBFR, /* (i) : length */
+ tRes, /* (i) : input signal */
+ &syn[i_subfr] /* (i/o) : filter states / output signal */
+ );
+
+ FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
+ }
+
+ /* save old excitation and old synthesis memory for next ACELP frame */
+ FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
+ FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
+ sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
+ acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;
+
+ C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
+ C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
+}
+
+void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, FIXP_DBL *pit_gain,
+ FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
+ INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr) {
+ int n;
+
+ /* init beginning of synth_buf with old synthesis from previous frame */
+ FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
+
+ /* calculate pitch lag offset for ACELP decoder */
+ *i_offset =
+ (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
+ PIT_MIN_12k8;
+
+ /* for bass postfilter */
+ for (n = 0; n < synSfd; n++) {
+ pitch[n] = old_T_pf[n];
+ pit_gain[n] = old_gain_pf[n];
+ }
+ for (n = 0; n < nbSubfrSuperfr; n++) {
+ pitch[n + synSfd] = L_SUBFR;
+ pit_gain[n + synSfd] = (FIXP_DBL)0;
+ }
+}
+
+void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr) {
+ int n;
+
+ /* store last part of synth_buf (which is not handled by the IMDCT overlap)
+ * for next frame */
+ FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
+ sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
+
+ /* for bass postfilter */
+ for (n = 0; n < synSfd; n++) {
+ old_T_pf[n] = pitch[nbSubfrSuperfr + n];
+ }
+}
+
+#define L_FAC_ZIR (LFAC)
+
+void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
+ CAcelpStaticMem *acelp_mem, const INT length,
+ FIXP_DBL zir[], int doDeemph) {
+ C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
+ FDK_ASSERT(length <= L_FAC_ZIR);
+
+ FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+ FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));
+
+ Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
+ &tmp_buf[M_LP_FILTER_ORDER]);
+ if (!doDeemph) {
+ /* if last lpd mode was TD concealment, then bypass deemph */
+ FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
+ } else {
+ Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
+ &acelp_mem->de_emph_mem);
+ scaleValues(zir, length, -ACELP_OUTSCALE);
+ }
+ C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
+}
+
+void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
+ UCHAR last_last_lpd_mode,
+ const FIXP_LPC *A_new, const INT A_new_exp,
+ const FIXP_LPC *A_old, const INT A_old_exp,
+ CAcelpStaticMem *acelp_mem,
+ INT coreCoderFrameLength, INT clearOldExc,
+ UCHAR lpd_mode) {
+ int l_div =
+ coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
+ int l_div_partial;
+ FIXP_DBL *syn, *old_exc_mem;
+
+ C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ syn = &synth_buf[M_LP_FILTER_ORDER];
+
+ l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
+ old_exc_mem = acelp_mem->old_exc_mem;
+
+ if (lpd_mode == 4) {
+ /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
+ * end. */
+ FDKmemcpy(
+ synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
+ (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
+ /* Set deemphasis memory state for TD concealment */
+ acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
+ } else {
+ /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
+ * preemph domain */
+ E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
+ synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
+ ACELP_OUTSCALE);
+ }
+
+ /* Set deemphasis memory state */
+ acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
+
+ /* update acelp synth filter memory */
+ FDKmemcpy(acelp_mem->old_syn_mem,
+ &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
+ M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
+
+ if (clearOldExc) {
+ FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
+ C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+ return;
+ }
+
+ /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
+ if (last_lpd_mode == 1) { /* last frame was TCX20 */
+ if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
+ /* Delay valid part of excitation buffer (from previous ACELP frame) by
+ * l_div samples */
+ FDKmemmove(old_exc_mem, old_exc_mem + l_div,
+ sizeof(FIXP_DBL) * l_div_partial);
+ } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
+ E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
+ }
+ E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
+ old_exc_mem + l_div_partial, l_div);
+ } else { /* prev frame was FD, TCX40 or TCX80 */
+ int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
+ ? PIT_MAX_MAX + L_INTERPOL
+ : coreCoderFrameLength / 2;
+ int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
+ E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
+ E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
+ &old_exc_mem[exc_A_old_length], exc_A_new_length);
+ }
+ C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
+ PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
+
+ return;
+}
+
+FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
+ FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
+ return acelp_mem->old_exc_mem;
+}
+
+INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
+ INT acelp_core_mode, INT coreCoderFrameLength,
+ INT i_offset) {
+ int nb_subfr = coreCoderFrameLength / L_DIV;
+ const UCHAR *num_acb_index_bits =
+ (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
+ int nbits;
+ int error = 0;
+
+ const int PIT_MIN = PIT_MIN_12k8 + i_offset;
+ const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
+ const int PIT_FR1 = PIT_FR1_12k8;
+ const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
+ int T0, T0_frac, T0_min = 0, T0_max;
+
+ if (PIT_MAX > PIT_MAX_MAX) {
+ error = AAC_DEC_DECODE_FRAME_ERROR;
+ goto bail;
+ }
+
+ acelp->acelp_core_mode = acelp_core_mode;
+
+ nbits = MapCoreMode2NBits(acelp_core_mode);
+
+ /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
+ acelp->mean_energy = FDKreadBits(hBs, 2);
+
+ for (int sfr = 0; sfr < nb_subfr; sfr++) {
+ /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
+ error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
+ PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
+ if (error) {
+ goto bail;
+ }
+ acelp->T0[sfr] = (USHORT)T0;
+ acelp->T0_frac[sfr] = (UCHAR)T0_frac;
+ acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
+ switch (nbits) {
+ case 12: /* 12 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 16: /* 16 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 20: /* 20 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 28: /* 28 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
+ break;
+ case 36: /* 36 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
+ break;
+ case 44: /* 44 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
+ break;
+ case 52: /* 52 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
+ break;
+ case 64: /* 64 bits AMR-WB codebook is used */
+ acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
+ acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
+ acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
+ break;
+ default:
+ FDK_ASSERT(0);
+ break;
+ }
+ acelp->gains[sfr] = FDKreadBits(hBs, 7);
+ }
+
+bail:
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_acelp.h b/fdk-aac/libAACdec/src/usacdec_acelp.h
new file mode 100644
index 0000000..9de41ff
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_acelp.h
@@ -0,0 +1,281 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand
+
+ Description: USAC ACELP frame decoder
+
+*******************************************************************************/
+
+#ifndef USACDEC_ACELP_H
+#define USACDEC_ACELP_H
+
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "usacdec_const.h"
+#include "usacdec_rom.h"
+
+//#define ENHANCED_TCX_TD_CONCEAL_ENABLE
+
+/** Structure which holds the ACELP internal persistent memory */
+typedef struct {
+ FIXP_DBL old_exc_mem[PIT_MAX_MAX + L_INTERPOL];
+ FIXP_DBL old_syn_mem[M_LP_FILTER_ORDER]; /* synthesis filter states */
+ FIXP_SGL A[M_LP_FILTER_ORDER];
+ INT A_exp;
+ FIXP_DBL gc_threshold;
+ FIXP_DBL de_emph_mem;
+ FIXP_SGL past_gpit;
+ FIXP_DBL past_gcode;
+ USHORT old_T0;
+ UCHAR old_T0_frac;
+ FIXP_DBL deemph_mem_wsyn;
+ FIXP_DBL wsyn_rms;
+ SHORT seed_ace;
+} CAcelpStaticMem;
+
+/** Structure which holds the parameter data needed to decode one ACELP frame.
+ */
+typedef struct {
+ UCHAR
+ acelp_core_mode; /**< mean excitation energy index for whole ACELP frame
+ */
+ UCHAR mean_energy; /**< acelp core mode for whole ACELP frame */
+ USHORT T0[NB_SUBFR];
+ UCHAR T0_frac[NB_SUBFR];
+ UCHAR ltp_filtering_flag[NB_SUBFR]; /**< controlls whether LTP postfilter is
+ active for each ACELP subframe */
+ SHORT icb_index[NB_SUBFR]
+ [8]; /**< innovative codebook index for each ACELP subframe */
+ UCHAR gains[NB_SUBFR]; /**< gain index for each ACELP subframe */
+} CAcelpChannelData;
+
+/**
+ * \brief Read the acelp_coding() bitstream part.
+ * \param[in] hBs bitstream handle to read data from.
+ * \param[out] acelpData pointer to structure to store the parsed data of one
+ * ACELP frame.
+ * \param[in] acelp_core_mode the ACELP core mode index.
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelpData,
+ INT acelp_core_mode, INT i_offset, INT coreCoderFrameLength);
+/**
+ * \brief Initialization of memory before one LPD frame is decoded
+ * \param[out] synth_buf synthesis buffer to be initialized, exponent = SF_SYNTH
+ * \param[in] old_synth past synthesis of previous LPD frame, exponent =
+ * SF_SYNTH
+ * \param[out] synth_buf_fb fullband synthesis buffer to be initialized,
+ * exponent = SF_SYNTH
+ * \param[in] old_synth_fb past fullband synthesis of previous LPD frame,
+ * exponent = SF_SYNTH
+ * \param[out] pitch vector where decoded pitch lag values are stored
+ * \param[in] old_T_pf past pitch lag values of previous LPD frame
+ * \param[in] samplingRate sampling rate for pitch lag offset calculation
+ * \param[out] i_offset pitch lag offset for the decoding of the pitch lag
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, FIXP_DBL *pit_gain,
+ FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
+ INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr);
+
+/**
+ * \brief Save tail of buffers for the initialization of the next LPD frame
+ * \param[in] synth_buf synthesis of current LPD frame, exponent = SF_SYNTH
+ * \param[out] old_synth memory where tail of fullband synth_buf is stored,
+ * exponent = SF_SYNTH
+ * \param[in] synth_buf_fb fullband synthesis of current LPD frame, exponent =
+ * SF_SYNTH
+ * \param[out] old_synth_fb memory where tail of fullband synth_buf is stored,
+ * exponent = SF_SYNTH
+ * \param[in] pitch decoded pitch lag values of current LPD frame
+ * \param[out] old_T_pf memory where last SYN_SFD pitch lag values are stored
+ */
+void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
+ INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
+ INT nbSubfrSuperfr);
+
+/**
+ * \brief Decode one ACELP frame (three or four ACELP subframes with 64 samples
+ * each)
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] i_offset pitch lag offset
+ * \param[in] lsp_old LPC filter in LSP domain corresponding to previous frame
+ * \param[in] lsp_new LPC filter in LSP domain corresponding to current frame
+ * \param[in] stab_fac stability factor constrained by 0<=stab_fac<=1.0,
+ * exponent = SF_STAB
+ * \param[in] acelpData pointer to struct with data which is needed for decoding
+ * one ACELP frame
+ * \param[out] synth ACELP output signal
+ * \param[out] pT four decoded pitch lag values
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ FIXP_SGL stab_fac, CAcelpChannelData *acelpData,
+ INT numLostSubframes, int lastLpcLost, int frameCnt,
+ FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
+ INT coreCoderFrameLength);
+
+/**
+ * \brief Reset ACELP internal memory.
+ * \param[out] acelp_mem pointer to ACELP memory structure
+ */
+void CLpd_AcelpReset(CAcelpStaticMem *acelp_mem);
+
+/**
+ * \brief Initialize ACELP internal memory in case of FAC before ACELP decoder
+ * is called
+ * \param[in] synth points to end+1 of past valid synthesis signal, exponent =
+ * SF_SYNTH
+ * \param[in] last_lpd_mode last lpd mode
+ * \param[in] last_last_lpd_mode lpd mode before last_lpd_mode
+ * \param[in] A_new LP synthesis filter coeffs corresponding to last frame,
+ * exponent = SF_A_COEFFS
+ * \param[in] A_old LP synthesis filter coeffs corresponding to the frame before
+ * last frame, exponent = SF_A_COEFFS
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] coreCoderFrameLength length of core coder frame (1024|768)
+ */
+void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
+ UCHAR last_last_lpd_mode,
+ const FIXP_LPC *A_new, const INT A_new_exp,
+ const FIXP_LPC *A_old, const INT A_old_exp,
+ CAcelpStaticMem *acelp_mem,
+ INT coreCoderFrameLength, INT clearOldExc,
+ UCHAR lpd_mode);
+
+/**
+ * \brief Calculate zero input response (zir) of the acelp synthesis filter
+ * \param[in] A LP synthesis filter coefficients, exponent = SF_A_COEFFS
+ * \param[in,out] acelp_mem pointer to ACELP memory structure
+ * \param[in] length length of zir
+ * \param[out] zir pointer to zir output buffer, exponent = SF_SYNTH
+ */
+void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
+ CAcelpStaticMem *acelp_mem, const INT length,
+ FIXP_DBL zir[], int doDeemph);
+
+/**
+ * \brief Borrow static excitation memory from ACELP decoder
+ * \param[in] acelp_mem pointer to ACELP memory structure
+ * \param[in] length number of requested FIXP_DBL values
+ * \return pointer to requested memory
+ *
+ * The caller has to take care not to overwrite valid memory areas.
+ * During TCX/FAC calculations and before CLpd_AcelpPrepareInternalMem() is
+ * called, the following memory size is available:
+ * - 256 samples in case of ACELP -> TCX20 -> ACELP transition
+ * - PIT_MAX_MAX+L_INTERPOL samples in all other cases
+ */
+FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length);
+
+void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
+ const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
+ const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
+ const FIXP_SGL stab_fac, INT numLostSubframes,
+ FIXP_DBL synth[], INT coreCoderFrameLength,
+ UCHAR last_tcx_noise_factor);
+
+inline SHORT E_UTIL_random(SHORT *seed) {
+ *seed = (SHORT)((((LONG)*seed * (LONG)31821) >> 1) + (LONG)13849);
+ return (*seed);
+}
+
+#endif /* USACDEC_ACELP_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_const.h b/fdk-aac/libAACdec/src/usacdec_const.h
new file mode 100644
index 0000000..f68e808
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_const.h
@@ -0,0 +1,203 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC related constants
+
+*******************************************************************************/
+
+#ifndef USACDEC_CONST_H
+#define USACDEC_CONST_H
+
+/* scale factors */
+#define SF_CODE 6 /* exponent of code[], fixed codebook vector */
+#define SF_GAIN_C 16 /* exponent of gain code and smoothed gain code */
+#define SF_EXC 16 /* exponent of exc[] and exc2[], excitation buffer */
+#define SF_GAIN_P 1 /* exponent of gain_pit */
+#define SF_PFAC 0 /* exponent of period/voicing factor */
+#define SF_SYNTH SF_EXC /* exponent of synthesis buffer */
+#define SF_A_COEFFS 3 /* exponent of LP domain synthesis filter coefficient */
+#define SF_STAB 1 /* exponent of stability factor */
+
+/* definitions which are independent of coreCoderFrameLength */
+#define M_LP_FILTER_ORDER 16 /* LP filter order */
+#define LP_FILTER_SCALE 4 /* LP filter scale */
+
+#define PIT_MIN_12k8 34 /* Minimum pitch lag with resolution 1/4 */
+#define PIT_MAX_12k8 231 /* Maximum pitch lag for fs=12.8kHz */
+#define FSCALE_DENOM 12800 /* Frequency scale denominator */
+#define FAC_FSCALE_MIN \
+ 6000 /* Minimum allowed frequency scale for acelp decoder */
+
+#if !defined(LPD_MAX_CORE_SR)
+#define LPD_MAX_CORE_SR 24000 /* Default value from ref soft */
+#endif
+#define FAC_FSCALE_MAX \
+ LPD_MAX_CORE_SR /* Maximum allowed frequency scale for acelp decoder */
+
+/* Maximum pitch lag (= 411 for fs_max = 24000) */
+#define PIT_MAX_TMP \
+ (PIT_MAX_12k8 + \
+ (6 * \
+ ((((FAC_FSCALE_MAX * PIT_MIN_12k8) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - \
+ PIT_MIN_12k8)))
+#if (PIT_MAX_TMP < \
+ 256) /* cannot be smaller because of tcx time domain concealment */
+#define PIT_MAX_MAX 256
+#else
+#define PIT_MAX_MAX PIT_MAX_TMP
+#endif
+
+#define NB_DIV 4 /* number of division (20ms) per 80ms frame */
+#define L_SUBFR 64 /* subframe size (5ms) */
+#define BPF_SFD 1 /* bass postfilter delay (subframe) */
+#define BPF_DELAY (BPF_SFD * L_SUBFR) /* bass postfilter delay (samples) */
+
+#define L_FILT 12 /* Delay of up-sampling filter (bass post-filter) */
+#define L_EXTRA 96 /* for bass post-filter */
+#define L_INTERPOL \
+ (16 + 1) /* Length of filter for interpolation (acelp decoder) */
+
+/* definitions for coreCoderFrameLength = 1024 */
+#define L_FRAME_PLUS_1024 1024 /* length of one 80ms superframe */
+#define L_DIV_1024 \
+ (L_FRAME_PLUS_1024 / NB_DIV) /* length of one acelp or tcx20 frame */
+#define NB_SUBFR_1024 \
+ (L_DIV_1024 / L_SUBFR) /* number of 5ms subframe per division */
+#define NB_SUBFR_SUPERFR_1024 \
+ (L_FRAME_PLUS_1024 / L_SUBFR) /* number of 5ms subframe per 80ms frame */
+#define AAC_SFD_1024 (NB_SUBFR_SUPERFR_1024 / 2) /* AAC delay (subframe) */
+#define AAC_DELAY_1024 (AAC_SFD_1024 * L_SUBFR) /* AAC delay (samples) */
+#define SYN_SFD_1024 (AAC_SFD_1024 - BPF_SFD) /* synthesis delay (subframe) */
+#define SYN_DELAY_1024 \
+ (SYN_SFD_1024 * L_SUBFR) /* synthesis delay (samples) \
+ */
+#define LFAC_1024 (L_DIV_1024 / 2) /* FAC frame length */
+#define LFAC_SHORT_1024 \
+ (L_DIV_1024 / 4) /* for transitions EIGHT_SHORT FD->LPD and vv. */
+#define FDNS_NPTS_1024 64 /* FD noise shaping resolution (64=100Hz/point) */
+
+/* definitions for coreCoderFrameLength = 768 */
+#define L_FRAME_PLUS_768 768
+#define L_DIV_768 \
+ (L_FRAME_PLUS_768 / NB_DIV) /* length of one acelp or tcx20 frame */
+#define NB_SUBFR_768 \
+ (L_DIV_768 / L_SUBFR) /* number of 5ms subframe per division */
+#define NB_SUBFR_SUPERFR_768 \
+ (L_FRAME_PLUS_768 / L_SUBFR) /* number of 5ms subframe per 80ms frame */
+#define AAC_SFD_768 (NB_SUBFR_SUPERFR_768 / 2) /* AAC delay (subframe) */
+#define AAC_DELAY_768 (AAC_SFD_768 * L_SUBFR) /* AAC delay (samples) */
+#define SYN_SFD_768 (AAC_SFD_768 - BPF_SFD) /* synthesis delay (subframe) */
+#define SYN_DELAY_768 (SYN_SFD_768 * L_SUBFR) /* synthesis delay (samples) */
+#define LFAC_768 (L_DIV_768 / 2) /* FAC frame length */
+#define LFAC_SHORT_768 \
+ (L_DIV_768 / 4) /* for transitions EIGHT_SHORT FD->LPD and vv. */
+
+/* maximum (used for memory allocation) */
+#define L_FRAME_PLUS L_FRAME_PLUS_1024
+#define L_DIV L_DIV_1024
+#define NB_SUBFR NB_SUBFR_1024
+#define NB_SUBFR_SUPERFR NB_SUBFR_SUPERFR_1024
+#define AAC_SFD AAC_SFD_1024
+#define AAC_DELAY AAC_DELAY_1024
+#define SYN_SFD SYN_SFD_1024
+#define SYN_DELAY SYN_DELAY_1024
+#define LFAC LFAC_1024
+#define LFAC_SHORT LFAC_SHORT_1024
+#define FDNS_NPTS FDNS_NPTS_1024
+
+#endif /* USACDEC_CONST_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_fac.cpp b/fdk-aac/libAACdec/src/usacdec_fac.cpp
new file mode 100644
index 0000000..0d3d844
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_fac.cpp
@@ -0,0 +1,745 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC FAC
+
+*******************************************************************************/
+
+#include "usacdec_fac.h"
+
+#include "usacdec_const.h"
+#include "usacdec_lpc.h"
+#include "usacdec_acelp.h"
+#include "usacdec_rom.h"
+#include "dct.h"
+#include "FDK_tools_rom.h"
+#include "mdct.h"
+
+#define SPEC_FAC(ptr, i, gl) ((ptr) + ((i) * (gl)))
+
+FIXP_DBL *CLpd_FAC_GetMemory(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR mod[NB_DIV], int *pState) {
+ FIXP_DBL *ptr;
+ int i;
+ int k = 0;
+ int max_windows = 8;
+
+ FDK_ASSERT(*pState >= 0 && *pState < max_windows);
+
+ /* Look for free space to store FAC data. 2 FAC data blocks fit into each TCX
+ * spectral data block. */
+ for (i = *pState; i < max_windows; i++) {
+ if (mod[i >> 1] == 0) {
+ break;
+ }
+ }
+
+ *pState = i + 1;
+
+ if (i == max_windows) {
+ ptr = pAacDecoderChannelInfo->data.usac.fac_data0;
+ } else {
+ FDK_ASSERT(mod[(i >> 1)] == 0);
+ ptr = SPEC_FAC(pAacDecoderChannelInfo->pSpectralCoefficient, i,
+ pAacDecoderChannelInfo->granuleLength << k);
+ }
+
+ return ptr;
+}
+
+int CLpd_FAC_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pFac, SCHAR *pFacScale,
+ int length, int use_gain, int frame) {
+ FIXP_DBL fac_gain;
+ int fac_gain_e = 0;
+
+ if (use_gain) {
+ CLpd_DecodeGain(&fac_gain, &fac_gain_e, FDKreadBits(hBs, 7));
+ }
+
+ if (CLpc_DecodeAVQ(hBs, pFac, 1, 1, length) != 0) {
+ return -1;
+ }
+
+ {
+ int scale;
+
+ scale = getScalefactor(pFac, length);
+ scaleValues(pFac, length, scale);
+ pFacScale[frame] = DFRACT_BITS - 1 - scale;
+ }
+
+ if (use_gain) {
+ int i;
+
+ pFacScale[frame] += fac_gain_e;
+
+ for (i = 0; i < length; i++) {
+ pFac[i] = fMult(pFac[i], fac_gain);
+ }
+ }
+ return 0;
+}
+
+/**
+ * \brief Apply synthesis filter with zero input to x. The overall filter gain
+ * is 1.0.
+ * \param a LPC filter coefficients.
+ * \param length length of the input/output data vector x.
+ * \param x input/output vector, where the synthesis filter is applied in place.
+ */
+static void Syn_filt_zero(const FIXP_LPC a[], const INT a_exp, INT length,
+ FIXP_DBL x[]) {
+ int i, j;
+ FIXP_DBL L_tmp;
+
+ for (i = 0; i < length; i++) {
+ L_tmp = (FIXP_DBL)0;
+
+ for (j = 0; j < fMin(i, M_LP_FILTER_ORDER); j++) {
+ L_tmp -= fMultDiv2(a[j], x[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
+ }
+
+ L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
+ x[i] = fAddSaturate(x[i], L_tmp);
+ }
+}
+
+/* Table is also correct for coreCoderFrameLength = 768. Factor 3/4 is canceled
+ out: gainFac = 0.5 * sqrt(fac_length/lFrame)
+*/
+static const FIXP_DBL gainFac[4] = {0x40000000, 0x2d413ccd, 0x20000000,
+ 0x16a09e66};
+
+void CFac_ApplyGains(FIXP_DBL fac_data[LFAC], const INT fac_length,
+ const FIXP_DBL tcx_gain, const FIXP_DBL alfd_gains[],
+ const INT mod) {
+ FIXP_DBL facFactor;
+ int i;
+
+ FDK_ASSERT((fac_length == 128) || (fac_length == 96));
+
+ /* 2) Apply gain factor to FAC data */
+ facFactor = fMult(gainFac[mod], tcx_gain);
+ for (i = 0; i < fac_length; i++) {
+ fac_data[i] = fMult(fac_data[i], facFactor);
+ }
+
+ /* 3) Apply spectrum deshaping using alfd_gains */
+ for (i = 0; i < fac_length / 4; i++) {
+ int k;
+
+ k = i >> (3 - mod);
+ fac_data[i] = fMult(fac_data[i], alfd_gains[k])
+ << 1; /* alfd_gains is scaled by one bit. */
+ }
+}
+
+static void CFac_CalcFacSignal(FIXP_DBL *pOut, FIXP_DBL *pFac,
+ const int fac_scale, const int fac_length,
+ const FIXP_LPC A[M_LP_FILTER_ORDER],
+ const INT A_exp, const int fAddZir,
+ const int isFdFac) {
+ FIXP_LPC wA[M_LP_FILTER_ORDER];
+ FIXP_DBL tf_gain = (FIXP_DBL)0;
+ int wlength;
+ int scale = fac_scale;
+
+ /* obtain tranform gain. */
+ imdct_gain(&tf_gain, &scale, isFdFac ? 0 : fac_length);
+
+ /* 4) Compute inverse DCT-IV of FAC data. Output scale of DCT IV is 16 bits.
+ */
+ dct_IV(pFac, fac_length, &scale);
+ /* dct_IV scale = log2(fac_length). "- 7" is a factor of 2/128 */
+ if (tf_gain != (FIXP_DBL)0) { /* non-radix 2 transform gain */
+ int i;
+
+ for (i = 0; i < fac_length; i++) {
+ pFac[i] = fMult(tf_gain, pFac[i]);
+ }
+ }
+ scaleValuesSaturate(pOut, pFac, fac_length,
+ scale); /* Avoid overflow issues and saturate. */
+
+ E_LPC_a_weight(wA, A, M_LP_FILTER_ORDER);
+
+ /* We need the output of the IIR filter to be longer than "fac_length".
+ For this reason we run it with zero input appended to the end of the input
+ sequence, i.e. we generate its ZIR and extend the output signal.*/
+ FDKmemclear(pOut + fac_length, fac_length * sizeof(FIXP_DBL));
+ wlength = 2 * fac_length;
+
+ /* 5) Apply weighted synthesis filter to FAC data, including optional Zir (5.
+ * item 4). */
+ Syn_filt_zero(wA, A_exp, wlength, pOut);
+}
+
+INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac,
+ const int fac_scale, FIXP_LPC *A, INT A_exp,
+ INT nrOutSamples, const INT fac_length,
+ const INT isFdFac, UCHAR prevWindowShape) {
+ FIXP_DBL *pOvl;
+ FIXP_DBL *pOut0;
+ const FIXP_WTP *pWindow;
+ int i, fl, nrSamples = 0;
+
+ FDK_ASSERT(fac_length <= 1024 / (4 * 2));
+
+ fl = fac_length * 2;
+
+ pWindow = FDKgetWindowSlope(fl, prevWindowShape);
+
+ /* Adapt window slope length in case of frame loss. */
+ if (hMdct->prev_fr != fl) {
+ int nl = 0;
+ imdct_adapt_parameters(hMdct, &fl, &nl, fac_length, pWindow, nrOutSamples);
+ FDK_ASSERT(nl == 0);
+ }
+
+ if (nrSamples < nrOutSamples) {
+ pOut0 = output;
+ nrSamples += hMdct->ov_offset;
+ /* Purge buffered output. */
+ FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
+ hMdct->ov_offset = 0;
+ }
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
+
+ if (nrSamples >= nrOutSamples) {
+ pOut0 = hMdct->overlap.time + hMdct->ov_offset;
+ hMdct->ov_offset += hMdct->prev_nr + fl / 2;
+ } else {
+ pOut0 = output + nrSamples;
+ nrSamples += hMdct->prev_nr + fl / 2;
+ }
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ } else {
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = (*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+ }
+ hMdct->prev_nr = 0;
+
+ {
+ if (pFac != NULL) {
+ /* Note: The FAC gain might have been applied directly after bit stream
+ * parse in this case. */
+ CFac_CalcFacSignal(pOut0, pFac, fac_scale, fac_length, A, A_exp, 0,
+ isFdFac);
+ } else {
+ /* Clear buffer because of the overlap and ADD! */
+ FDKmemclear(pOut0, fac_length * sizeof(FIXP_DBL));
+ }
+ }
+
+ i = 0;
+
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ for (; i < fl / 2; i++) {
+ FIXP_DBL x0;
+
+ /* Overlap Add */
+ x0 = -fMult(*pOvl--, pWindow[i].v.re);
+
+ *pOut0 += IMDCT_SCALE_DBL(x0);
+ pOut0++;
+ }
+ } else {
+ for (; i < fl / 2; i++) {
+ FIXP_DBL x0;
+
+ /* Overlap Add */
+ x0 = fMult(*pOvl--, pWindow[i].v.re);
+
+ *pOut0 += IMDCT_SCALE_DBL(x0);
+ pOut0++;
+ }
+ }
+ if (hMdct->pFacZir !=
+ 0) { /* this should only happen for ACELP -> TCX20 -> ACELP transition */
+ FIXP_DBL *pOut = pOut0 - fl / 2; /* fl/2 == fac_length */
+ for (i = 0; i < fl / 2; i++) {
+ pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ }
+ hMdct->pFacZir = NULL;
+ }
+
+ hMdct->prev_fr = 0;
+ hMdct->prev_nr = 0;
+ hMdct->prev_tl = 0;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+
+ return nrSamples;
+}
+
+INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *_pSpec,
+ const SHORT spec_scale[], const int nSpec,
+ FIXP_DBL *pFac, const int fac_scale,
+ const INT fac_length, INT noOutSamples, const INT tl,
+ const FIXP_WTP *wrs, const INT fr, FIXP_LPC A[16],
+ INT A_exp, CAcelpStaticMem *acelp_mem,
+ const FIXP_DBL gain, const int last_frame_lost,
+ const int isFdFac, const UCHAR last_lpd_mode,
+ const int k, int currAliasingSymmetry) {
+ FIXP_DBL *pCurr, *pOvl, *pSpec;
+ const FIXP_WTP *pWindow;
+ const FIXP_WTB *FacWindowZir_conceal;
+ UCHAR doFacZirConceal = 0;
+ int doDeemph = 1;
+ const FIXP_WTB *FacWindowZir, *FacWindowSynth;
+ FIXP_DBL *pOut0 = output, *pOut1;
+ int w, i, fl, nl, nr, f_len, nrSamples = 0, s = 0, scale, total_gain_e;
+ FIXP_DBL *pF, *pFAC_and_FAC_ZIR = NULL;
+ FIXP_DBL total_gain = gain;
+
+ FDK_ASSERT(fac_length <= 1024 / (4 * 2));
+ switch (fac_length) {
+ /* coreCoderFrameLength = 1024 */
+ case 128:
+ pWindow = SineWindow256;
+ FacWindowZir = FacWindowZir128;
+ FacWindowSynth = FacWindowSynth128;
+ break;
+ case 64:
+ pWindow = SineWindow128;
+ FacWindowZir = FacWindowZir64;
+ FacWindowSynth = FacWindowSynth64;
+ break;
+ case 32:
+ pWindow = SineWindow64;
+ FacWindowZir = FacWindowZir32;
+ FacWindowSynth = FacWindowSynth32;
+ break;
+ /* coreCoderFrameLength = 768 */
+ case 96:
+ pWindow = SineWindow192;
+ FacWindowZir = FacWindowZir96;
+ FacWindowSynth = FacWindowSynth96;
+ break;
+ case 48:
+ pWindow = SineWindow96;
+ FacWindowZir = FacWindowZir48;
+ FacWindowSynth = FacWindowSynth48;
+ break;
+ default:
+ FDK_ASSERT(0);
+ return 0;
+ }
+
+ FacWindowZir_conceal = FacWindowSynth;
+ /* Derive NR and NL */
+ fl = fac_length * 2;
+ nl = (tl - fl) >> 1;
+ nr = (tl - fr) >> 1;
+
+ if (noOutSamples > nrSamples) {
+ /* Purge buffered output. */
+ FDKmemcpy(pOut0, hMdct->overlap.time, hMdct->ov_offset * sizeof(pOut0[0]));
+ nrSamples = hMdct->ov_offset;
+ hMdct->ov_offset = 0;
+ }
+
+ if (nrSamples >= noOutSamples) {
+ pOut1 = hMdct->overlap.time + hMdct->ov_offset;
+ if (hMdct->ov_offset < fac_length) {
+ pOut0 = output + nrSamples;
+ } else {
+ pOut0 = pOut1;
+ }
+ hMdct->ov_offset += fac_length + nl;
+ } else {
+ pOut1 = output + nrSamples;
+ pOut0 = output + nrSamples;
+ }
+
+ {
+ pFAC_and_FAC_ZIR = CLpd_ACELP_GetFreeExcMem(acelp_mem, 2 * fac_length);
+ {
+ const FIXP_DBL *pTmp1, *pTmp2;
+
+ doFacZirConceal |= ((last_frame_lost != 0) && (k == 0));
+ doDeemph &= (last_lpd_mode != 4);
+ if (doFacZirConceal) {
+ /* ACELP contribution in concealment case:
+ Use ZIR with a modified ZIR window to preserve some more energy.
+ Dont use FAC, which contains wrong information for concealed frame
+ Dont use last ACELP samples, but double ZIR, instead (afterwards) */
+ FDKmemclear(pFAC_and_FAC_ZIR, 2 * fac_length * sizeof(FIXP_DBL));
+ FacWindowSynth = (FIXP_WTB *)pFAC_and_FAC_ZIR;
+ FacWindowZir = FacWindowZir_conceal;
+ } else {
+ CFac_CalcFacSignal(pFAC_and_FAC_ZIR, pFac, fac_scale + s, fac_length, A,
+ A_exp, 1, isFdFac);
+ }
+ /* 6) Get windowed past ACELP samples and ACELP ZIR signal */
+
+ /*
+ * Get ACELP ZIR (pFac[]) and ACELP past samples (pOut0[]) and add them
+ * to the FAC synth signal contribution on pOut1[].
+ */
+ {
+ {
+ CLpd_Acelp_Zir(A, A_exp, acelp_mem, fac_length, pFac, doDeemph);
+
+ pTmp1 = pOut0;
+ pTmp2 = pFac;
+ }
+
+ for (i = 0, w = 0; i < fac_length; i++) {
+ FIXP_DBL x;
+ /* Div2 is compensated by table scaling */
+ x = fMultDiv2(pTmp2[i], FacWindowZir[w]);
+ x += fMultDiv2(pTmp1[-i - 1], FacWindowSynth[w]);
+ x += pFAC_and_FAC_ZIR[i];
+ pOut1[i] = x;
+
+ w++;
+ }
+ }
+
+ if (doFacZirConceal) {
+ /* ZIR is the only ACELP contribution, so double it */
+ scaleValues(pOut1, fac_length, 1);
+ }
+ }
+ }
+
+ if (nrSamples < noOutSamples) {
+ nrSamples += fac_length + nl;
+ }
+
+ /* Obtain transform gain */
+ total_gain = gain;
+ total_gain_e = 0;
+ imdct_gain(&total_gain, &total_gain_e, tl);
+
+ /* IMDCT overlap add */
+ scale = total_gain_e;
+ pSpec = _pSpec;
+
+ /* Note:when comming from an LPD frame (TCX/ACELP) the previous alisaing
+ * symmetry must always be 0 */
+ if (currAliasingSymmetry == 0) {
+ dct_IV(pSpec, tl, &scale);
+ } else {
+ FIXP_DBL _tmp[1024 + ALIGNMENT_DEFAULT / sizeof(FIXP_DBL)];
+ FIXP_DBL *tmp = (FIXP_DBL *)ALIGN_PTR(_tmp);
+ C_ALLOC_ALIGNED_REGISTER(tmp, sizeof(_tmp));
+ dst_III(pSpec, tmp, tl, &scale);
+ C_ALLOC_ALIGNED_UNREGISTER(tmp);
+ }
+
+ /* Optional scaling of time domain - no yet windowed - of current spectrum */
+ if (total_gain != (FIXP_DBL)0) {
+ for (i = 0; i < tl; i++) {
+ pSpec[i] = fMult(pSpec[i], total_gain);
+ }
+ }
+ int loc_scale = fixmin_I(spec_scale[0] + scale, (INT)DFRACT_BITS - 1);
+ scaleValuesSaturate(pSpec, tl, loc_scale);
+
+ pOut1 += fl / 2 - 1;
+ pCurr = pSpec + tl - fl / 2;
+
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x1;
+
+ /* FAC signal is already on pOut1, because of that the += operator. */
+ x1 = fMult(*pCurr++, pWindow[i].v.re);
+ FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
+ pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
+ (pOut1 >= output && pOut1 < output + 1024));
+ *pOut1 += IMDCT_SCALE_DBL(-x1);
+ pOut1--;
+ }
+
+ /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
+ pOut1 += (fl / 2) + 1;
+
+ pFAC_and_FAC_ZIR += fac_length; /* set pointer to beginning of FAC ZIR */
+
+ if (nl == 0) {
+ /* save pointer to write FAC ZIR data later */
+ hMdct->pFacZir = pFAC_and_FAC_ZIR;
+ } else {
+ FDK_ASSERT(nl >= fac_length);
+ /* FAC ZIR will be added now ... */
+ hMdct->pFacZir = NULL;
+ }
+
+ pF = pFAC_and_FAC_ZIR;
+ f_len = fac_length;
+
+ pCurr = pSpec + tl - fl / 2 - 1;
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = -(*pCurr--);
+ /* 5) (item 4) Synthesis filter Zir component, FAC ZIR (another one). */
+ if (i < f_len) {
+ x += *pF++;
+ }
+
+ FDK_ASSERT((pOut1 >= hMdct->overlap.time &&
+ pOut1 < hMdct->overlap.time + hMdct->ov_size) ||
+ (pOut1 >= output && pOut1 < output + 1024));
+ *pOut1 = IMDCT_SCALE_DBL(x);
+ pOut1++;
+ }
+
+ hMdct->prev_nr = nr;
+ hMdct->prev_fr = fr;
+ hMdct->prev_wrs = wrs;
+ hMdct->prev_tl = tl;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+ hMdct->prevAliasSymmetry = currAliasingSymmetry;
+ fl = fr;
+ nl = nr;
+
+ pOvl = pSpec + tl / 2 - 1;
+ pOut0 = pOut1;
+
+ for (w = 1; w < nSpec; w++) /* for ACELP -> FD short */
+ {
+ const FIXP_WTP *pWindow_prev;
+
+ /* Setup window pointers */
+ pWindow_prev = hMdct->prev_wrs;
+
+ /* Current spectrum */
+ pSpec = _pSpec + w * tl;
+
+ scale = total_gain_e;
+
+ /* For the second, third, etc. short frames the alisaing symmetry is equal,
+ * either (0,0) or (1,1) */
+ if (currAliasingSymmetry == 0) {
+ /* DCT IV of current spectrum */
+ dct_IV(pSpec, tl, &scale);
+ } else {
+ dst_IV(pSpec, tl, &scale);
+ }
+
+ /* Optional scaling of time domain - no yet windowed - of current spectrum
+ */
+ /* and de-scale current spectrum signal (time domain, no yet windowed) */
+ if (total_gain != (FIXP_DBL)0) {
+ for (i = 0; i < tl; i++) {
+ pSpec[i] = fMult(pSpec[i], total_gain);
+ }
+ }
+ loc_scale = fixmin_I(spec_scale[w] + scale, (INT)DFRACT_BITS - 1);
+ scaleValuesSaturate(pSpec, tl, loc_scale);
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output first half to overlap buffer if we already got enough
+ * output samples. */
+ pOut0 = hMdct->overlap.time + hMdct->ov_offset;
+ hMdct->ov_offset += hMdct->prev_nr + fl / 2;
+ } else {
+ /* Account output samples */
+ nrSamples += hMdct->prev_nr + fl / 2;
+ }
+
+ /* NR output samples 0 .. NR. -overlap[TL/2..TL/2-NR] */
+ for (i = 0; i < hMdct->prev_nr; i++) {
+ FIXP_DBL x = -(*pOvl--);
+ *pOut0 = IMDCT_SCALE_DBL(x);
+ pOut0++;
+ }
+
+ if (noOutSamples <= nrSamples) {
+ /* Divert output second half to overlap buffer if we already got enough
+ * output samples. */
+ pOut1 = hMdct->overlap.time + hMdct->ov_offset + fl / 2 - 1;
+ hMdct->ov_offset += fl / 2 + nl;
+ } else {
+ pOut1 = pOut0 + (fl - 1);
+ nrSamples += fl / 2 + nl;
+ }
+
+ /* output samples before window crossing point NR .. TL/2.
+ * -overlap[TL/2-NR..TL/2-NR-FL/2] + current[NR..TL/2] */
+ /* output samples after window crossing point TL/2 .. TL/2+FL/2.
+ * -overlap[0..FL/2] - current[TL/2..FL/2] */
+ pCurr = pSpec + tl - fl / 2;
+ if (currAliasingSymmetry == 0) {
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(-x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else {
+ if (hMdct->prevPrevAliasSymmetry == 0) {
+ /* Jump DST II -> DST IV for the second window */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, -*pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(x1);
+ pOut0++;
+ pOut1--;
+ }
+ } else {
+ /* Jump DST IV -> DST IV from the second window on */
+ for (i = 0; i < fl / 2; i++) {
+ FIXP_DBL x0, x1;
+
+ cplxMult(&x1, &x0, *pCurr++, *pOvl--, pWindow_prev[i]);
+ *pOut0 = IMDCT_SCALE_DBL(x0);
+ *pOut1 = IMDCT_SCALE_DBL(x1);
+ pOut0++;
+ pOut1--;
+ }
+ }
+ }
+
+ if (hMdct->pFacZir != 0) {
+ /* add FAC ZIR of previous ACELP -> mdct transition */
+ FIXP_DBL *pOut = pOut0 - fl / 2;
+ FDK_ASSERT(fl / 2 <= 128);
+ for (i = 0; i < fl / 2; i++) {
+ pOut[i] += IMDCT_SCALE_DBL(hMdct->pFacZir[i]);
+ }
+ hMdct->pFacZir = NULL;
+ }
+ pOut0 += (fl / 2);
+
+ /* NL output samples TL/2+FL/2..TL. - current[FL/2..0] */
+ pOut1 += (fl / 2) + 1;
+ pCurr = pSpec + tl - fl / 2 - 1;
+ for (i = 0; i < nl; i++) {
+ FIXP_DBL x = -(*pCurr--);
+ *pOut1 = IMDCT_SCALE_DBL(x);
+ pOut1++;
+ }
+
+ /* Set overlap source pointer for next window pOvl = pSpec + tl/2 - 1; */
+ pOvl = pSpec + tl / 2 - 1;
+
+ /* Previous window values. */
+ hMdct->prev_nr = nr;
+ hMdct->prev_fr = fr;
+ hMdct->prev_tl = tl;
+ hMdct->prev_wrs = pWindow_prev;
+ hMdct->prevPrevAliasSymmetry = hMdct->prevAliasSymmetry;
+ hMdct->prevAliasSymmetry = currAliasingSymmetry;
+ }
+
+ /* Save overlap */
+
+ pOvl = hMdct->overlap.freq + hMdct->ov_size - tl / 2;
+ FDK_ASSERT(pOvl >= hMdct->overlap.time + hMdct->ov_offset);
+ FDK_ASSERT(tl / 2 <= hMdct->ov_size);
+ for (i = 0; i < tl / 2; i++) {
+ pOvl[i] = _pSpec[i + (w - 1) * tl];
+ }
+
+ return nrSamples;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_fac.h b/fdk-aac/libAACdec/src/usacdec_fac.h
new file mode 100644
index 0000000..100a6fa
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_fac.h
@@ -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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC FAC
+
+*******************************************************************************/
+
+#ifndef USACDEC_FAC_H
+#define USACDEC_FAC_H
+
+#include "channelinfo.h"
+#include "FDK_bitstream.h"
+
+/**
+ * \brief Get the address of a memory area of the spectral data memory were the
+ * FAC data can be stored into.
+ * \param spec SPECTRAL_PTR pointing to the current spectral data.
+ * \param mod the current LPD mod array.
+ * \param pState pointer to a private state variable which must be 0 for the
+ * first call and not changed externally.
+ * \param isFullbandLPD is 1 if fullband LPD mode is on, otherwise it is 0.
+ */
+FIXP_DBL *CLpd_FAC_GetMemory(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ UCHAR mod[NB_SUBFR], int *pState);
+
+/**
+ * \brief read a fac bitstream data block.
+ * \param hBs a bit stream handle, where the fac bitstream data is located.
+ * \param pFac pointer to were the FAC data will be stored into.
+ * \param pFacScale pointer to were the FAC data scale value will be stored
+ * into.
+ * \param tcx_gain value to be used as FAC gain. If zero, read fac_gain from
+ * bitstream.
+ * \param tcx_gain_e exponen value of tcx_gain.
+ * \param frame the subframe to be considered from the current superframe.
+ * Always 0 for FD case.
+ * \return 0 on success, -1 on error.
+ */
+int CLpd_FAC_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pFac, SCHAR *pFacScale,
+ int length, int use_gain, int frame);
+
+/**
+ * \brief Apply TCX and ALFD gains to FAC data.
+ * \param fac_data pointer to FAC data.
+ * \param fac_length FAC length (128 or 96).
+ * \param tcx_gain TCX gain
+ * \param alfd_gains pointer to alfd gains.
+ * \param mod mod value (1,2,3) of TCX frame where the FAC signal needs to be
+ * applied.
+ */
+void CFac_ApplyGains(FIXP_DBL fac_data[LFAC], const INT fac_length,
+ const FIXP_DBL tcx_gain, const FIXP_DBL alfd_gains[],
+ const INT mod);
+
+/**
+ * \brief Do FAC transition from frequency domain to ACELP domain.
+ */
+INT CLpd_FAC_Mdct2Acelp(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pFac_data,
+ const int fac_data_e, FIXP_LPC *A, INT A_exp,
+ INT nrOutSamples, const INT fac_length,
+ const INT isFdFac, UCHAR prevWindowShape);
+
+/**
+ * \brief Do FAC transition from ACELP domain to frequency domain.
+ * \param hMdct MDCT context.
+ * \param output pointer for time domain output.
+ * \param pSpec pointer to MDCT spectrum input.
+ * \param spec_scale MDCT spectrum exponents.
+ * \param nSpec amount of contiguos MDCT spectra.
+ * \param pFac pointer to FAC MDCT domain data.
+ * \param fac_scale exponent of FAC data.
+ * \param fac_length length of FAC data.
+ * \param nrSamples room in samples in output buffer.
+ * \param tl MDCT transform length of pSpec.
+ * \param wrs right MDCT window slope.
+ * \param fr right MDCT window slope length.
+ * \param A LP domain filter coefficients.
+ * \param deemph_mem deemphasis filter state.
+ * \param gain gain to be applied to FAC data before overlap add.
+ * \param old_syn_mem Synthesis filter state.
+ * \param isFdFac indicates fac processing from or to FD.
+ * \param pFacData fac data stored for fullband LPD.
+ * \param elFlags element specific parser guidance flags.
+ * \param isFacForFullband indicates that fac is processed for fullband LPD.
+ */
+INT CLpd_FAC_Acelp2Mdct(H_MDCT hMdct, FIXP_DBL *output, FIXP_DBL *pSpec,
+ const SHORT spec_scale[], const int nSpec,
+ FIXP_DBL *pFac_data, const int fac_data_e,
+ const INT fac_length, INT nrSamples, const INT tl,
+ const FIXP_WTP *wrs, const INT fr, FIXP_LPC A[16],
+ INT A_exp, CAcelpStaticMem *acelp_mem,
+ const FIXP_DBL gain, const int last_frame_lost,
+ const int isFdFac, const UCHAR last_lpd, const int k,
+ int currAliasingSymmetry);
+
+#endif /* USACDEC_FAC_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_lpc.cpp b/fdk-aac/libAACdec/src/usacdec_lpc.cpp
new file mode 100644
index 0000000..271463f
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpc.cpp
@@ -0,0 +1,1194 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand, Manuel Jander
+
+ Description: USAC LPC/AVQ decode
+
+*******************************************************************************/
+
+#include "usacdec_lpc.h"
+
+#include "usacdec_rom.h"
+#include "FDK_trigFcts.h"
+
+#define NQ_MAX 36
+
+/*
+ * Helper functions.
+ */
+
+/**
+ * \brief Read unary code.
+ * \param hBs bitstream handle as data source.
+ * \return decoded value.
+ */
+static int get_vlclbf(HANDLE_FDK_BITSTREAM hBs) {
+ int result = 0;
+
+ while (FDKreadBits(hBs, 1) && result <= NQ_MAX) {
+ result++;
+ }
+ return result;
+}
+
+/**
+ * \brief Read bit count limited unary code.
+ * \param hBs bitstream handle as data source
+ * \param n max amount of bits to be read.
+ * \return decoded value.
+ */
+static int get_vlclbf_n(HANDLE_FDK_BITSTREAM hBs, int n) {
+ int result = 0;
+
+ while (FDKreadBits(hBs, 1)) {
+ result++;
+ n--;
+ if (n <= 0) {
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Algebraic Vector Quantizer
+ */
+
+/* ZF_SCALE must be greater than (number of FIXP_ZF)/2
+ because the loss of precision caused by fPow2Div2 in RE8_PPV() */
+//#define ZF_SCALE ((NQ_MAX-3)>>1)
+#define ZF_SCALE ((DFRACT_BITS / 2))
+#define FIXP_ZF FIXP_DBL
+#define INT2ZF(x, s) (FIXP_ZF)((x) << (ZF_SCALE - (s)))
+#define ZF2INT(x) (INT)((x) >> ZF_SCALE)
+
+/* 1.0 in ZF format format */
+#define ONEZF ((FIXP_ZF)INT2ZF(1, 0))
+
+/* static */
+void nearest_neighbor_2D8(FIXP_ZF x[8], int y[8]) {
+ FIXP_ZF s, em, e[8];
+ int i, j, sum;
+
+ /* round x into 2Z^8 i.e. compute y=(y1,...,y8) such that yi = 2[xi/2]
+ where [.] is the nearest integer operator
+ in the mean time, compute sum = y1+...+y8
+ */
+ sum = 0;
+ for (i = 0; i < 8; i++) {
+ FIXP_ZF tmp;
+ /* round to ..., -2, 0, 2, ... ([-1..1[ --> 0) */
+ if (x[i] < (FIXP_ZF)0) {
+ tmp = ONEZF - x[i];
+ y[i] = -2 * ((ZF2INT(tmp)) >> 1);
+ } else {
+ tmp = ONEZF + x[i];
+ y[i] = 2 * ((ZF2INT(tmp)) >> 1);
+ }
+ sum += y[i];
+ }
+ /* check if y1+...+y8 is a multiple of 4
+ if not, y is not round xj in the wrong way where j is defined by
+ j = arg max_i | xi -yi|
+ (this is called the Wagner rule)
+ */
+ if (sum % 4) {
+ /* find j = arg max_i | xi -yi| */
+ em = (FIXP_SGL)0;
+ j = 0;
+ for (i = 0; i < 8; i++) {
+ /* compute ei = xi-yi */
+ e[i] = x[i] - INT2ZF(y[i], 0);
+ }
+ for (i = 0; i < 8; i++) {
+ /* compute |ei| = | xi-yi | */
+ if (e[i] < (FIXP_ZF)0) {
+ s = -e[i];
+ } else {
+ s = e[i];
+ }
+ /* check if |ei| is maximal, if so, set j=i */
+ if (em < s) {
+ em = s;
+ j = i;
+ }
+ }
+ /* round xj in the "wrong way" */
+ if (e[j] < (FIXP_ZF)0) {
+ y[j] -= 2;
+ } else {
+ y[j] += 2;
+ }
+ }
+}
+
+/*--------------------------------------------------------------
+ RE8_PPV(x,y)
+ NEAREST NEIGHBOR SEARCH IN INFINITE LATTICE RE8
+ the algorithm is based on the definition of RE8 as
+ RE8 = (2D8) U (2D8+[1,1,1,1,1,1,1,1])
+ it applies the coset decoding of Sloane and Conway
+ (i) x: point in R^8 in 32-ZF_SCALE.ZF_SCALE format
+ (o) y: point in RE8 (8-dimensional integer vector)
+ --------------------------------------------------------------
+*/
+/* static */
+void RE8_PPV(FIXP_ZF x[], SHORT y[], int r) {
+ int i, y0[8], y1[8];
+ FIXP_ZF x1[8], tmp;
+ FIXP_DBL e;
+
+ /* find the nearest neighbor y0 of x in 2D8 */
+ nearest_neighbor_2D8(x, y0);
+ /* find the nearest neighbor y1 of x in 2D8+(1,...,1) (by coset decoding) */
+ for (i = 0; i < 8; i++) {
+ x1[i] = x[i] - ONEZF;
+ }
+ nearest_neighbor_2D8(x1, y1);
+ for (i = 0; i < 8; i++) {
+ y1[i] += 1;
+ }
+
+ /* compute e0=||x-y0||^2 and e1=||x-y1||^2 */
+ e = (FIXP_DBL)0;
+ for (i = 0; i < 8; i++) {
+ tmp = x[i] - INT2ZF(y0[i], 0);
+ e += fPow2Div2(
+ tmp << r); /* shift left to ensure that no fract part bits get lost. */
+ tmp = x[i] - INT2ZF(y1[i], 0);
+ e -= fPow2Div2(tmp << r);
+ }
+ /* select best candidate y0 or y1 to minimize distortion */
+ if (e < (FIXP_DBL)0) {
+ for (i = 0; i < 8; i++) {
+ y[i] = y0[i];
+ }
+ } else {
+ for (i = 0; i < 8; i++) {
+ y[i] = y1[i];
+ }
+ }
+}
+
+/* table look-up of unsigned value: find i where index >= table[i]
+ Note: range must be >= 2, index must be >= table[0] */
+static int table_lookup(const USHORT *table, unsigned int index, int range) {
+ int i;
+
+ for (i = 4; i < range; i += 4) {
+ if (index < table[i]) {
+ break;
+ }
+ }
+ if (i > range) {
+ i = range;
+ }
+
+ if (index < table[i - 2]) {
+ i -= 2;
+ }
+ if (index < table[i - 1]) {
+ i--;
+ }
+ i--;
+
+ return (i); /* index >= table[i] */
+}
+
+/*--------------------------------------------------------------------------
+ re8_decode_rank_of_permutation(rank, xs, x)
+ DECODING OF THE RANK OF THE PERMUTATION OF xs
+ (i) rank: index (rank) of a permutation
+ (i) xs: signed leader in RE8 (8-dimensional integer vector)
+ (o) x: point in RE8 (8-dimensional integer vector)
+ --------------------------------------------------------------------------
+ */
+static void re8_decode_rank_of_permutation(int rank, int *xs, SHORT x[8]) {
+ INT a[8], w[8], B, fac, fac_B, target;
+ int i, j;
+
+ /* --- pre-processing based on the signed leader xs ---
+ - compute the alphabet a=[a[0] ... a[q-1]] of x (q elements)
+ such that a[0]!=...!=a[q-1]
+ it is assumed that xs is sorted in the form of a signed leader
+ which can be summarized in 2 requirements:
+ a) |xs[0]| >= |xs[1]| >= |xs[2]| >= ... >= |xs[7]|
+ b) if |xs[i]|=|xs[i-1]|, xs[i]>=xs[i+1]
+ where |.| indicates the absolute value operator
+ - compute q (the number of symbols in the alphabet)
+ - compute w[0..q-1] where w[j] counts the number of occurences of
+ the symbol a[j] in xs
+ - compute B = prod_j=0..q-1 (w[j]!) where .! is the factorial */
+ /* xs[i], xs[i-1] and ptr_w/a*/
+ j = 0;
+ w[j] = 1;
+ a[j] = xs[0];
+ B = 1;
+ for (i = 1; i < 8; i++) {
+ if (xs[i] != xs[i - 1]) {
+ j++;
+ w[j] = 1;
+ a[j] = xs[i];
+ } else {
+ w[j]++;
+ B *= w[j];
+ }
+ }
+
+ /* --- actual rank decoding ---
+ the rank of x (where x is a permutation of xs) is based on
+ Schalkwijk's formula
+ it is given by rank=sum_{k=0..7} (A_k * fac_k/B_k)
+ the decoding of this rank is sequential and reconstructs x[0..7]
+ element by element from x[0] to x[7]
+ [the tricky part is the inference of A_k for each k...]
+ */
+
+ if (w[0] == 8) {
+ for (i = 0; i < 8; i++) {
+ x[i] = a[0]; /* avoid fac of 40320 */
+ }
+ } else {
+ target = rank * B;
+ fac_B = 1;
+ /* decode x element by element */
+ for (i = 0; i < 8; i++) {
+ fac = fac_B * fdk_dec_tab_factorial[i]; /* fac = 1..5040 */
+ j = -1;
+ do {
+ target -= w[++j] * fac;
+ } while (target >= 0); /* max of 30 tests / SV */
+ x[i] = a[j];
+ /* update rank, denominator B (B_k) and counter w[j] */
+ target += w[j] * fac; /* target = fac_B*B*rank */
+ fac_B *= w[j];
+ w[j]--;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------
+ re8_decode_base_index(n, I, y)
+ DECODING OF AN INDEX IN Qn (n=0,2,3 or 4)
+ (i) n: codebook number (*n is an integer defined in {0,2,3,4})
+ (i) I: index of c (pointer to unsigned 16-bit word)
+ (o) y: point in RE8 (8-dimensional integer vector)
+ note: the index I is defined as a 32-bit word, but only
+ 16 bits are required (long can be replaced by unsigned integer)
+ --------------------------------------------------------------------------
+ */
+static void re8_decode_base_index(int *n, UINT index, SHORT y[8]) {
+ int i, im, t, sign_code, ka, ks, rank, leader[8];
+
+ if (*n < 2) {
+ for (i = 0; i < 8; i++) {
+ y[i] = 0;
+ }
+ } else {
+ // index = (unsigned int)*I;
+ /* search for the identifier ka of the absolute leader (table-lookup)
+ Q2 is a subset of Q3 - the two cases are considered in the same branch
+ */
+ switch (*n) {
+ case 2:
+ case 3:
+ i = table_lookup(fdk_dec_I3, index, NB_LDQ3);
+ ka = fdk_dec_A3[i];
+ break;
+ case 4:
+ i = table_lookup(fdk_dec_I4, index, NB_LDQ4);
+ ka = fdk_dec_A4[i];
+ break;
+ default:
+ FDK_ASSERT(0);
+ return;
+ }
+ /* reconstruct the absolute leader */
+ for (i = 0; i < 8; i++) {
+ leader[i] = fdk_dec_Da[ka][i];
+ }
+ /* search for the identifier ks of the signed leader (table look-up)
+ (this search is focused based on the identifier ka of the absolute
+ leader)*/
+ t = fdk_dec_Ia[ka];
+ im = fdk_dec_Ns[ka];
+ ks = table_lookup(fdk_dec_Is + t, index, im);
+
+ /* reconstruct the signed leader from its sign code */
+ sign_code = 2 * fdk_dec_Ds[t + ks];
+ for (i = 7; i >= 0; i--) {
+ leader[i] *= (1 - (sign_code & 2));
+ sign_code >>= 1;
+ }
+
+ /* compute and decode the rank of the permutation */
+ rank = index - fdk_dec_Is[t + ks]; /* rank = index - cardinality offset */
+
+ re8_decode_rank_of_permutation(rank, leader, y);
+ }
+ return;
+}
+
+/* re8_y2k(y,m,k)
+ VORONOI INDEXING (INDEX DECODING) k -> y
+ (i) k: Voronoi index k[0..7]
+ (i) m: Voronoi modulo (m = 2^r = 1<<r, where r is integer >=2)
+ (i) r: Voronoi order (m = 2^r = 1<<r, where r is integer >=2)
+ (o) y: 8-dimensional point y[0..7] in RE8
+ */
+static void re8_k2y(int *k, int r, SHORT *y) {
+ int i, tmp, sum;
+ SHORT v[8];
+ FIXP_ZF zf[8];
+
+ FDK_ASSERT(r <= ZF_SCALE);
+
+ /* compute y = k M and z=(y-a)/m, where
+ M = [4 ]
+ [2 2 ]
+ [| \ ]
+ [2 2 ]
+ [1 1 _ 1 1]
+ a=(2,0,...,0)
+ m = 1<<r
+ */
+ for (i = 0; i < 8; i++) {
+ y[i] = k[7];
+ }
+ zf[7] = INT2ZF(y[7], r);
+ sum = 0;
+ for (i = 6; i >= 1; i--) {
+ tmp = 2 * k[i];
+ sum += tmp;
+ y[i] += tmp;
+ zf[i] = INT2ZF(y[i], r);
+ }
+ y[0] += (4 * k[0] + sum);
+ zf[0] = INT2ZF(y[0] - 2, r);
+ /* find nearest neighbor v of z in infinite RE8 */
+ RE8_PPV(zf, v, r);
+ /* compute y -= m v */
+ for (i = 0; i < 8; i++) {
+ y[i] -= (SHORT)(v[i] << r);
+ }
+}
+
+/*--------------------------------------------------------------------------
+ RE8_dec(n, I, k, y)
+ MULTI-RATE INDEXING OF A POINT y in THE LATTICE RE8 (INDEX DECODING)
+ (i) n: codebook number (*n is an integer defined in {0,2,3,4,..,n_max}). n_max
+ = 36 (i) I: index of c (pointer to unsigned 16-bit word) (i) k: index of v
+ (8-dimensional vector of binary indices) = Voronoi index (o) y: point in RE8
+ (8-dimensional integer vector) note: the index I is defined as a 32-bit word,
+ but only 16 bits are required (long can be replaced by unsigned integer)
+
+ return 0 on success, -1 on error.
+ --------------------------------------------------------------------------
+ */
+static int RE8_dec(int n, int I, int *k, FIXP_DBL *y) {
+ SHORT v[8];
+ SHORT _y[8];
+ UINT r;
+ int i;
+
+ /* Check bound of codebook qn */
+ if (n > NQ_MAX) {
+ return -1;
+ }
+
+ /* decode the sub-indices I and kv[] according to the codebook number n:
+ if n=0,2,3,4, decode I (no Voronoi extension)
+ if n>4, Voronoi extension is used, decode I and kv[] */
+ if (n <= 4) {
+ re8_decode_base_index(&n, I, _y);
+ for (i = 0; i < 8; i++) {
+ y[i] = (LONG)_y[i];
+ }
+ } else {
+ /* compute the Voronoi modulo m = 2^r where r is extension order */
+ r = ((n - 3) >> 1);
+
+ while (n > 4) {
+ n -= 2;
+ }
+ /* decode base codebook index I into c (c is an element of Q3 or Q4)
+ [here c is stored in y to save memory] */
+ re8_decode_base_index(&n, I, _y);
+ /* decode Voronoi index k[] into v */
+ re8_k2y(k, r, v);
+ /* reconstruct y as y = m c + v (with m=2^r, r integer >=1) */
+ for (i = 0; i < 8; i++) {
+ y[i] = (LONG)((_y[i] << r) + v[i]);
+ }
+ }
+ return 0;
+}
+
+/**************************/
+/* start LPC decode stuff */
+/**************************/
+//#define M 16
+#define FREQ_MAX 6400.0f
+#define FREQ_DIV 400.0f
+#define LSF_GAP 50.0f
+
+/**
+ * \brief calculate inverse weighting factor and add non-weighted residual
+ * LSF vector to first stage LSF approximation
+ * \param lsfq first stage LSF approximation values.
+ * \param xq weighted residual LSF vector
+ * \param nk_mode code book number coding mode.
+ */
+static void lsf_weight_2st(FIXP_LPC *lsfq, FIXP_DBL *xq, int nk_mode) {
+ FIXP_LPC d[M_LP_FILTER_ORDER + 1];
+ FIXP_SGL factor;
+ LONG w; /* inverse weight factor */
+ int i;
+
+ /* compute lsf distance */
+ d[0] = lsfq[0];
+ d[M_LP_FILTER_ORDER] =
+ FL2FXCONST_LPC(FREQ_MAX / (1 << LSF_SCALE)) - lsfq[M_LP_FILTER_ORDER - 1];
+ for (i = 1; i < M_LP_FILTER_ORDER; i++) {
+ d[i] = lsfq[i] - lsfq[i - 1];
+ }
+
+ switch (nk_mode) {
+ case 0:
+ factor = FL2FXCONST_SGL(2.0f * 60.0f / FREQ_DIV);
+ break; /* abs */
+ case 1:
+ factor = FL2FXCONST_SGL(2.0f * 65.0f / FREQ_DIV);
+ break; /* mid */
+ case 2:
+ factor = FL2FXCONST_SGL(2.0f * 64.0f / FREQ_DIV);
+ break; /* rel1 */
+ default:
+ factor = FL2FXCONST_SGL(2.0f * 63.0f / FREQ_DIV);
+ break; /* rel2 */
+ }
+ /* add non-weighted residual LSF vector to LSF1st */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ w = (LONG)fMultDiv2(factor, sqrtFixp(fMult(d[i], d[i + 1])));
+ lsfq[i] = fAddSaturate(lsfq[i], FX_DBL2FX_LPC((FIXP_DBL)(w * (LONG)xq[i])));
+ }
+
+ return;
+}
+
+/**
+ * \brief decode nqn amount of code book numbers. These values determine the
+ * amount of following bits for nqn AVQ RE8 vectors.
+ * \param nk_mode quantization mode.
+ * \param nqn amount code book number to read.
+ * \param qn pointer to output buffer to hold decoded code book numbers qn.
+ */
+static void decode_qn(HANDLE_FDK_BITSTREAM hBs, int nk_mode, int nqn,
+ int qn[]) {
+ int n;
+
+ if (nk_mode == 1) { /* nk mode 1 */
+ /* Unary code for mid LPC1/LPC3 */
+ /* Q0=0, Q2=10, Q3=110, ... */
+ for (n = 0; n < nqn; n++) {
+ qn[n] = get_vlclbf(hBs);
+ if (qn[n] > 0) {
+ qn[n]++;
+ }
+ }
+ } else { /* nk_mode 0, 3 and 2 */
+ /* 2 bits to specify Q2,Q3,Q4,ext */
+ for (n = 0; n < nqn; n++) {
+ qn[n] = 2 + FDKreadBits(hBs, 2);
+ }
+ if (nk_mode == 2) {
+ /* Unary code for rel LPC1/LPC3 */
+ /* Q0 = 0, Q5=10, Q6=110, ... */
+ for (n = 0; n < nqn; n++) {
+ if (qn[n] > 4) {
+ qn[n] = get_vlclbf(hBs);
+ if (qn[n] > 0) qn[n] += 4;
+ }
+ }
+ } else { /* nk_mode == (0 and 3) */
+ /* Unary code for abs and rel LPC0/LPC2 */
+ /* Q5 = 0, Q6=10, Q0=110, Q7=1110, ... */
+ for (n = 0; n < nqn; n++) {
+ if (qn[n] > 4) {
+ qn[n] = get_vlclbf(hBs);
+ switch (qn[n]) {
+ case 0:
+ qn[n] = 5;
+ break;
+ case 1:
+ qn[n] = 6;
+ break;
+ case 2:
+ qn[n] = 0;
+ break;
+ default:
+ qn[n] += 4;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * \brief reorder LSF coefficients to minimum distance.
+ * \param lsf pointer to buffer containing LSF coefficients and where reordered
+ * LSF coefficients will be stored into, scaled by LSF_SCALE.
+ * \param min_dist min distance scaled by LSF_SCALE
+ * \param n number of LSF/LSP coefficients.
+ */
+static void reorder_lsf(FIXP_LPC *lsf, FIXP_LPC min_dist, int n) {
+ FIXP_LPC lsf_min;
+ int i;
+
+ lsf_min = min_dist;
+ for (i = 0; i < n; i++) {
+ if (lsf[i] < lsf_min) {
+ lsf[i] = lsf_min;
+ }
+ lsf_min = fAddSaturate(lsf[i], min_dist);
+ }
+
+ /* reverse */
+ lsf_min = FL2FXCONST_LPC(FREQ_MAX / (1 << LSF_SCALE)) - min_dist;
+ for (i = n - 1; i >= 0; i--) {
+ if (lsf[i] > lsf_min) {
+ lsf[i] = lsf_min;
+ }
+
+ lsf_min = lsf[i] - min_dist;
+ }
+}
+
+/**
+ * \brief First stage approximation
+ * \param hBs bitstream handle as data source
+ * \param lsfq pointer to output buffer to hold LPC coefficients scaled by
+ * LSF_SCALE.
+ */
+static void vlpc_1st_dec(
+ HANDLE_FDK_BITSTREAM hBs, /* input: codebook index */
+ FIXP_LPC *lsfq /* i/o: i:prediction o:quantized lsf */
+) {
+ const FIXP_LPC *p_dico;
+ int i, index;
+
+ index = FDKreadBits(hBs, 8);
+ p_dico = &fdk_dec_dico_lsf_abs_8b[index * M_LP_FILTER_ORDER];
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsfq[i] = p_dico[i];
+ }
+}
+
+/**
+ * \brief Do first stage approximation weighting and multiply with AVQ
+ * refinement.
+ * \param hBs bitstream handle data ssource.
+ * \param lsfq buffer holding 1st stage approx, 2nd stage approx is added to
+ * this values.
+ * \param nk_mode quantization mode.
+ * \return 0 on success, -1 on error.
+ */
+static int vlpc_2st_dec(
+ HANDLE_FDK_BITSTREAM hBs,
+ FIXP_LPC *lsfq, /* i/o: i:1st stage o:1st+2nd stage */
+ int nk_mode /* input: 0=abs, >0=rel */
+) {
+ int err;
+ FIXP_DBL xq[M_LP_FILTER_ORDER]; /* weighted residual LSF vector */
+
+ /* Decode AVQ refinement */
+ { err = CLpc_DecodeAVQ(hBs, xq, nk_mode, 2, 8); }
+ if (err != 0) {
+ return -1;
+ }
+
+ /* add non-weighted residual LSF vector to LSF1st */
+ lsf_weight_2st(lsfq, xq, nk_mode);
+
+ /* reorder */
+ reorder_lsf(lsfq, FL2FXCONST_LPC(LSF_GAP / (1 << LSF_SCALE)),
+ M_LP_FILTER_ORDER);
+
+ return 0;
+}
+
+/*
+ * Externally visible functions
+ */
+
+int CLpc_DecodeAVQ(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *pOutput, int nk_mode,
+ int no_qn, int length) {
+ int i, l;
+
+ for (i = 0; i < length; i += 8 * no_qn) {
+ int qn[2], nk, n, I;
+ int kv[8] = {0};
+
+ decode_qn(hBs, nk_mode, no_qn, qn);
+
+ for (l = 0; l < no_qn; l++) {
+ if (qn[l] == 0) {
+ FDKmemclear(&pOutput[i + l * 8], 8 * sizeof(FIXP_DBL));
+ }
+
+ /* Voronoi extension order ( nk ) */
+ nk = 0;
+ n = qn[l];
+ if (qn[l] > 4) {
+ nk = (qn[l] - 3) >> 1;
+ n = qn[l] - nk * 2;
+ }
+
+ /* Base codebook index, in reverse bit group order (!) */
+ I = FDKreadBits(hBs, 4 * n);
+
+ if (nk > 0) {
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ kv[j] = FDKreadBits(hBs, nk);
+ }
+ }
+
+ if (RE8_dec(qn[l], I, kv, &pOutput[i + l * 8]) != 0) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
+int CLpc_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean_cand[M_LP_FILTER_ORDER],
+ FIXP_SGL pStability[], UCHAR *mod, int first_lpd_flag,
+ int last_lpc_lost, int last_frame_ok) {
+ int i, k, err;
+ int mode_lpc_bin = 0; /* mode_lpc bitstream representation */
+ int lpc_present[5] = {0, 0, 0, 0, 0};
+ int lpc0_available = 1;
+ int s = 0;
+ int l = 3;
+ const int nbDiv = NB_DIV;
+
+ lpc_present[4 >> s] = 1; /* LPC4 */
+
+ /* Decode LPC filters in the following order: LPC 4,0,2,1,3 */
+
+ /*** Decode LPC4 ***/
+ vlpc_1st_dec(hBs, lsp[4 >> s]);
+ err = vlpc_2st_dec(hBs, lsp[4 >> s], 0); /* nk_mode = 0 */
+ if (err != 0) {
+ return err;
+ }
+
+ /*** Decode LPC0 and LPC2 ***/
+ k = 0;
+ if (!first_lpd_flag) {
+ lpc_present[0] = 1;
+ lpc0_available = !last_lpc_lost;
+ /* old LPC4 is new LPC0 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i];
+ }
+ /* skip LPC0 and continue with LPC2 */
+ k = 2;
+ }
+
+ for (; k < l; k += 2) {
+ int nk_mode = 0;
+
+ if ((k == 2) && (mod[0] == 3)) {
+ break; /* skip LPC2 */
+ }
+
+ lpc_present[k >> s] = 1;
+
+ mode_lpc_bin = FDKreadBit(hBs);
+
+ if (mode_lpc_bin == 0) {
+ /* LPC0/LPC2: Abs */
+ vlpc_1st_dec(hBs, lsp[k >> s]);
+ } else {
+ /* LPC0/LPC2: RelR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[k >> s][i] = lsp[4 >> s][i];
+ }
+ nk_mode = 3;
+ }
+
+ err = vlpc_2st_dec(hBs, lsp[k >> s], nk_mode);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ /*** Decode LPC1 ***/
+ if (mod[0] < 2) { /* else: skip LPC1 */
+ lpc_present[1] = 1;
+ mode_lpc_bin = get_vlclbf_n(hBs, 2);
+
+ switch (mode_lpc_bin) {
+ case 1:
+ /* LPC1: abs */
+ vlpc_1st_dec(hBs, lsp[1]);
+ err = vlpc_2st_dec(hBs, lsp[1], 0);
+ if (err != 0) {
+ return err;
+ }
+ break;
+ case 2:
+ /* LPC1: mid0 (no second stage AVQ quantizer in this case) */
+ if (lpc0_available) { /* LPC0/lsf[0] might be zero some times */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = (lsp[0][i] >> 1) + (lsp[2][i] >> 1);
+ }
+ } else {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = lsp[2][i];
+ }
+ }
+ break;
+ case 0:
+ /* LPC1: RelR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[1][i] = lsp[2][i];
+ }
+ err = vlpc_2st_dec(hBs, lsp[1], 2 << s);
+ if (err != 0) {
+ return err;
+ }
+ break;
+ }
+ }
+
+ /*** Decode LPC3 ***/
+ if ((mod[2] < 2)) { /* else: skip LPC3 */
+ int nk_mode = 0;
+ lpc_present[3] = 1;
+
+ mode_lpc_bin = get_vlclbf_n(hBs, 3);
+
+ switch (mode_lpc_bin) {
+ case 1:
+ /* LPC3: abs */
+ vlpc_1st_dec(hBs, lsp[3]);
+ break;
+ case 0:
+ /* LPC3: mid */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = (lsp[2][i] >> 1) + (lsp[4][i] >> 1);
+ }
+ nk_mode = 1;
+ break;
+ case 2:
+ /* LPC3: relL */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = lsp[2][i];
+ }
+ nk_mode = 2;
+ break;
+ case 3:
+ /* LPC3: relR */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[3][i] = lsp[4][i];
+ }
+ nk_mode = 2;
+ break;
+ }
+ err = vlpc_2st_dec(hBs, lsp[3], nk_mode);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ if (!lpc0_available && !last_frame_ok) {
+ /* LPC(0) was lost. Use next available LPC(k) instead */
+ for (k = 1; k < (nbDiv + 1); k++) {
+ if (lpc_present[k]) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+#define LSF_INIT_TILT (0.25f)
+ if (mod[0] > 0) {
+ lsp[0][i] = FX_DBL2FX_LPC(
+ fMult(lsp[k][i], FL2FXCONST_SGL(1.0f - LSF_INIT_TILT)) +
+ fMult(fdk_dec_lsf_init[i], FL2FXCONST_SGL(LSF_INIT_TILT)));
+ } else {
+ lsp[0][i] = lsp[k][i];
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lpc4_lsf[i] = lsp[4 >> s][i];
+ }
+
+ {
+ FIXP_DBL divFac;
+ int last, numLpc = 0;
+
+ i = nbDiv;
+ do {
+ numLpc += lpc_present[i--];
+ } while (i >= 0 && numLpc < 3);
+
+ last = i;
+
+ switch (numLpc) {
+ case 3:
+ divFac = FL2FXCONST_DBL(1.0f / 3.0f);
+ break;
+ case 2:
+ divFac = FL2FXCONST_DBL(1.0f / 2.0f);
+ break;
+ default:
+ divFac = FL2FXCONST_DBL(1.0f);
+ break;
+ }
+
+ /* get the adaptive mean for the next (bad) frame */
+ for (k = 0; k < M_LP_FILTER_ORDER; k++) {
+ FIXP_DBL tmp = (FIXP_DBL)0;
+ for (i = nbDiv; i > last; i--) {
+ if (lpc_present[i]) {
+ tmp = fMultAdd(tmp >> 1, lsp[i][k], divFac);
+ }
+ }
+ lsf_adaptive_mean_cand[k] = FX_DBL2FX_LPC(tmp);
+ }
+ }
+
+ /* calculate stability factor Theta. Needed for ACELP decoder and concealment
+ */
+ {
+ FIXP_LPC *lsf_prev, *lsf_curr;
+ k = 0;
+
+ FDK_ASSERT(lpc_present[0] == 1 && lpc_present[4 >> s] == 1);
+ lsf_prev = lsp[0];
+ for (i = 1; i < (nbDiv + 1); i++) {
+ if (lpc_present[i]) {
+ FIXP_DBL tmp = (FIXP_DBL)0;
+ int j;
+ lsf_curr = lsp[i];
+
+ /* sum = tmp * 2^(LSF_SCALE*2 + 4) */
+ for (j = 0; j < M_LP_FILTER_ORDER; j++) {
+ tmp += fPow2Div2((FIXP_SGL)(lsf_curr[j] - lsf_prev[j])) >> 3;
+ }
+
+ /* tmp = (float)(FL2FXCONST_DBL(1.25f) - fMult(tmp,
+ * FL2FXCONST_DBL(1/400000.0f))); */
+ tmp = FL2FXCONST_DBL(1.25f / (1 << LSF_SCALE)) -
+ fMult(tmp, FL2FXCONST_DBL((1 << (LSF_SCALE + 4)) / 400000.0f));
+ if (tmp >= FL2FXCONST_DBL(1.0f / (1 << LSF_SCALE))) {
+ pStability[k] = FL2FXCONST_SGL(1.0f / 2.0f);
+ } else if (tmp < FL2FXCONST_DBL(0.0f)) {
+ pStability[k] = FL2FXCONST_SGL(0.0f);
+ } else {
+ pStability[k] = FX_DBL2FX_SGL(tmp << (LSF_SCALE - 1));
+ }
+
+ lsf_prev = lsf_curr;
+ k = i;
+ } else {
+ /* Mark stability value as undefined. */
+ pStability[i] = (FIXP_SGL)-1;
+ }
+ }
+ }
+
+ /* convert into LSP domain */
+ for (i = 0; i < (nbDiv + 1); i++) {
+ if (lpc_present[i]) {
+ for (k = 0; k < M_LP_FILTER_ORDER; k++) {
+ lsp[i][k] = FX_DBL2FX_LPC(
+ fixp_cos(fMult(lsp[i][k],
+ FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+ }
+ }
+
+ return 0;
+}
+
+void CLpc_Conceal(FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean[M_LP_FILTER_ORDER],
+ const int first_lpd_flag) {
+ int i, j;
+
+#define BETA (FL2FXCONST_SGL(0.25f))
+#define ONE_BETA (FL2FXCONST_SGL(0.75f))
+#define BFI_FAC (FL2FXCONST_SGL(0.90f))
+#define ONE_BFI_FAC (FL2FXCONST_SGL(0.10f))
+
+ /* Frame loss concealment (could be improved) */
+
+ if (first_lpd_flag) {
+ /* Reset past LSF values */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i] = fdk_dec_lsf_init[i];
+ }
+ } else {
+ /* old LPC4 is new LPC0 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[0][i] = lpc4_lsf[i];
+ }
+ }
+
+ /* LPC1 */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ FIXP_LPC lsf_mean = FX_DBL2FX_LPC(fMult(BETA, fdk_dec_lsf_init[i]) +
+ fMult(ONE_BETA, lsf_adaptive_mean[i]));
+
+ lsp[1][i] = FX_DBL2FX_LPC(fMult(BFI_FAC, lpc4_lsf[i]) +
+ fMult(ONE_BFI_FAC, lsf_mean));
+ }
+
+ /* LPC2 - LPC4 */
+ for (j = 2; j <= 4; j++) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ /* lsf_mean[i] = FX_DBL2FX_LPC(fMult((FIXP_LPC)(BETA + j *
+ FL2FXCONST_LPC(0.1f)), fdk_dec_lsf_init[i])
+ + fMult((FIXP_LPC)(ONE_BETA - j *
+ FL2FXCONST_LPC(0.1f)), lsf_adaptive_mean[i])); */
+
+ FIXP_LPC lsf_mean = FX_DBL2FX_LPC(
+ fMult((FIXP_SGL)(BETA + (FIXP_SGL)(j * (INT)FL2FXCONST_SGL(0.1f))),
+ (FIXP_SGL)fdk_dec_lsf_init[i]) +
+ fMult(
+ (FIXP_SGL)(ONE_BETA - (FIXP_SGL)(j * (INT)FL2FXCONST_SGL(0.1f))),
+ lsf_adaptive_mean[i]));
+
+ lsp[j][i] = FX_DBL2FX_LPC(fMult(BFI_FAC, lsp[j - 1][i]) +
+ fMult(ONE_BFI_FAC, lsf_mean));
+ }
+ }
+
+ /* Update past values for the future */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lpc4_lsf[i] = lsp[4][i];
+ }
+
+ /* convert into LSP domain */
+ for (j = 0; j < 5; j++) {
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ lsp[j][i] = FX_DBL2FX_LPC(fixp_cos(
+ fMult(lsp[j][i], FL2FXCONST_SGL((1 << LSPARG_SCALE) * M_PI / 6400.0)),
+ LSF_SCALE - LSPARG_SCALE));
+ }
+ }
+}
+
+void E_LPC_a_weight(FIXP_LPC *wA, const FIXP_LPC *A, int m) {
+ FIXP_DBL f;
+ int i;
+
+ f = FL2FXCONST_DBL(0.92f);
+ for (i = 0; i < m; i++) {
+ wA[i] = FX_DBL2FX_LPC(fMult(A[i], f));
+ f = fMult(f, FL2FXCONST_DBL(0.92f));
+ }
+}
+
+void CLpd_DecodeGain(FIXP_DBL *gain, INT *gain_e, int gain_code) {
+ /* gain * 2^(gain_e) = 10^(gain_code/28) */
+ *gain = fLdPow(
+ FL2FXCONST_DBL(3.3219280948873623478703194294894 / 4.0), /* log2(10)*/
+ 2,
+ fMultDiv2((FIXP_DBL)gain_code << (DFRACT_BITS - 1 - 7),
+ FL2FXCONST_DBL(2.0f / 28.0f)),
+ 7, gain_e);
+}
+
+ /**
+ * \brief * Find the polynomial F1(z) or F2(z) from the LSPs.
+ * This is performed by expanding the product polynomials:
+ *
+ * F1(z) = product ( 1 - 2 LSP_i z^-1 + z^-2 )
+ * i=0,2,4,6,8
+ * F2(z) = product ( 1 - 2 LSP_i z^-1 + z^-2 )
+ * i=1,3,5,7,9
+ *
+ * where LSP_i are the LSPs in the cosine domain.
+ * R.A.Salami October 1990
+ * \param lsp input, line spectral freq. (cosine domain)
+ * \param f output, the coefficients of F1 or F2, scaled by 8 bits
+ * \param n no of coefficients (m/2)
+ * \param flag 1 : F1(z) ; 2 : F2(z)
+ */
+
+#define SF_F 8
+
+static void get_lsppol(FIXP_LPC lsp[], FIXP_DBL f[], int n, int flag) {
+ FIXP_DBL b;
+ FIXP_LPC *plsp;
+ int i, j;
+
+ plsp = lsp + flag - 1;
+ f[0] = FL2FXCONST_DBL(1.0f / (1 << SF_F));
+ b = -FX_LPC2FX_DBL(*plsp);
+ f[1] = b >> (SF_F - 1);
+ for (i = 2; i <= n; i++) {
+ plsp += 2;
+ b = -FX_LPC2FX_DBL(*plsp);
+ f[i] = ((fMultDiv2(b, f[i - 1]) << 1) + (f[i - 2])) << 1;
+ for (j = i - 1; j > 1; j--) {
+ f[j] = f[j] + (fMultDiv2(b, f[j - 1]) << 2) + f[j - 2];
+ }
+ f[1] = f[1] + (b >> (SF_F - 1));
+ }
+ return;
+}
+
+#define NC M_LP_FILTER_ORDER / 2
+
+/**
+ * \brief lsp input LSP vector
+ * \brief a output LP filter coefficient vector scaled by SF_A_COEFFS.
+ */
+void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp) {
+ FIXP_DBL f1[NC + 1], f2[NC + 1];
+ int i, k;
+
+ /*-----------------------------------------------------*
+ * Find the polynomials F1(z) and F2(z) *
+ *-----------------------------------------------------*/
+
+ get_lsppol(lsp, f1, NC, 1);
+ get_lsppol(lsp, f2, NC, 2);
+
+ /*-----------------------------------------------------*
+ * Multiply F1(z) by (1+z^-1) and F2(z) by (1-z^-1) *
+ *-----------------------------------------------------*/
+ for (i = NC; i > 0; i--) {
+ f1[i] += f1[i - 1];
+ f2[i] -= f2[i - 1];
+ }
+
+ FIXP_DBL aDBL[M_LP_FILTER_ORDER];
+
+ for (i = 1, k = M_LP_FILTER_ORDER - 1; i <= NC; i++, k--) {
+ FIXP_DBL tmp1, tmp2;
+
+ tmp1 = f1[i] >> 1;
+ tmp2 = f2[i] >> 1;
+
+ aDBL[i - 1] = (tmp1 + tmp2);
+ aDBL[k] = (tmp1 - tmp2);
+ }
+
+ int headroom_a = getScalefactor(aDBL, M_LP_FILTER_ORDER);
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ a[i] = FX_DBL2FX_LPC(aDBL[i] << headroom_a);
+ }
+
+ *a_exp = 8 - headroom_a;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_lpc.h b/fdk-aac/libAACdec/src/usacdec_lpc.h
new file mode 100644
index 0000000..a6713c1
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpc.h
@@ -0,0 +1,190 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Matthias Hildenbrand, Manuel Jander
+
+ Description: USAC LPC/AVQ decode
+
+*******************************************************************************/
+
+#ifndef USACDEC_LPC_H
+#define USACDEC_LPC_H
+
+#include "channelinfo.h"
+#include "common_fix.h"
+#include "FDK_bitstream.h"
+#include "usacdec_rom.h"
+
+#define LSPARG_SCALE 10
+
+/**
+ * \brief AVQ (refinement) decode
+ * \param hBs bitstream handle
+ * \param lsfq buffer for AVQ decode output.
+ * \param nk_mode quantization mode.
+ * \param nqn amount of split/interleaved RE8 vectors.
+ * \param total amount of individual data values to decode.
+ * \return 0 on success, -1 on error.
+ */
+int CLpc_DecodeAVQ(HANDLE_FDK_BITSTREAM hBs, FIXP_DBL *lsfq, int nk_mode,
+ int nqn, int length);
+
+/**
+ * \brief Read and decode LPC coeficient sets. First stage approximation + AVQ
+ * decode.
+ * \param[in] hBs bitstream handle to read data from.
+ * \param[out] lsp buffer into which the decoded LSP coefficients will be stored
+ * into.
+ * \param[in,out] lpc4_lsf buffer into which the decoded LCP4 LSF coefficients
+ * will be stored into (persistent).
+ * \param[out] lsf_adaptive_mean_cand lsf adaptive mean vector needed for
+ * concealment.
+ * \param[out] pStability array with stability values for the ACELP decoder (and
+ * concealment).
+ * \param[in] mod array which defines modes (ACELP, TCX20|40|80) are used in
+ * the current superframe.
+ * \param[in] first_lpd_flag indicates the presence of LPC0
+ * \param[in] last_lpc_lost indicate that LPC4 of previous frame was lost.
+ * \param[in] last_frame_ok indicate that the last frame was ok.
+ * \return 0 on success, -1 on error.
+ */
+int CLpc_Read(HANDLE_FDK_BITSTREAM hBs, FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC lsf_adaptive_mean_cand[M_LP_FILTER_ORDER],
+ FIXP_SGL pStability[], UCHAR *mod, int first_lpd_flag,
+ int last_lpc_lost, int last_frame_ok);
+
+/**
+ * \brief Generate LPC coefficient sets in case frame loss.
+ * \param lsp buffer into which the decoded LSP coefficients will be stored
+ * into.
+ * \param lpc4_lsf buffer into which the decoded LCP4 LSF coefficients will be
+ * stored into (persistent).
+ * \param isf_adaptive_mean
+ * \param first_lpd_flag indicates the previous LSF4 coefficients lpc4_lsf[] are
+ * not valid.
+ */
+void CLpc_Conceal(FIXP_LPC lsp[][M_LP_FILTER_ORDER],
+ FIXP_LPC lpc4_lsf[M_LP_FILTER_ORDER],
+ FIXP_LPC isf_adaptive_mean[M_LP_FILTER_ORDER],
+ const int first_lpd_flag);
+
+/**
+ * \brief apply absolute weighting
+ * \param A weighted LPC coefficient vector output. The first coeffcient is
+ * implicitly 1.0
+ * \param A LPC coefficient vector. The first coeffcient is implicitly 1.0
+ * \param m length of vector A
+ */
+/* static */
+void E_LPC_a_weight(FIXP_LPC *wA, const FIXP_LPC *A, const int m);
+
+/**
+ * \brief decode TCX/FAC gain. In case of TCX the lg/sqrt(rms) part
+ * must still be applied to obtain the gain value.
+ * \param gain (o) pointer were the gain mantissa is stored into.
+ * \param gain_e (o) pointer were the gain exponent is stored into.
+ * \param gain_code (i) the 7 bit binary word from the bitstream
+ * representing the gain.
+ */
+void CLpd_DecodeGain(FIXP_DBL *gain, INT *gain_e, int gain_code);
+
+/**
+ * \brief convert LSP coefficients into LP domain.
+ */
+void E_LPC_f_lsp_a_conversion(FIXP_LPC *lsp, FIXP_LPC *a, INT *a_exp);
+
+#endif /* USACDEC_LPC_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_lpd.cpp b/fdk-aac/libAACdec/src/usacdec_lpd.cpp
new file mode 100644
index 0000000..2110172
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpd.cpp
@@ -0,0 +1,2029 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC Linear Prediction Domain coding
+
+*******************************************************************************/
+
+#include "usacdec_lpd.h"
+
+#include "usacdec_rom.h"
+#include "usacdec_fac.h"
+#include "usacdec_lpc.h"
+#include "FDK_tools_rom.h"
+#include "fft.h"
+#include "mdct.h"
+#include "usacdec_acelp.h"
+#include "overlapadd.h"
+
+#include "conceal.h"
+
+#include "block.h"
+
+#define SF_PITCH_TRACK 6
+#define SF_GAIN 3
+#define MIN_VAL FL2FXCONST_DBL(0.0f)
+#define MAX_VAL (FIXP_DBL) MAXVAL_DBL
+
+#include "ac_arith_coder.h"
+
+void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
+ const FIXP_SGL *filt, INT stop, int len) {
+ INT i, j;
+ FIXP_DBL tmp;
+
+ for (i = 0; i < stop; i++) {
+ tmp = fMultDiv2(noise[i], filt[0]); // Filt in Q-1.16
+ for (j = 1; j <= len; j++) {
+ tmp += fMultDiv2((noise[i - j] + noise[i + j]), filt[j]);
+ }
+ syn_out[i] = (FIXP_PCM)(IMDCT_SCALE(syn[i] - tmp));
+ }
+}
+
+void bass_pf_1sf_delay(
+ FIXP_DBL *syn, /* (i) : 12.8kHz synthesis to postfilter */
+ const INT *T_sf, /* (i) : Pitch period for all subframes (T_sf[16]) */
+ FIXP_DBL *pit_gain,
+ const int frame_length, /* (i) : frame length (should be 768|1024) */
+ const INT l_frame,
+ const INT l_next, /* (i) : look ahead for symmetric filtering */
+ FIXP_PCM *synth_out, /* (o) : filtered synthesis (with delay of 1 subfr) */
+ FIXP_DBL mem_bpf[]) /* i/o : memory state [L_FILT+L_SUBFR] */
+{
+ INT i, sf, i_subfr, T, T2, lg;
+
+ FIXP_DBL tmp, ener, corr, gain;
+ FIXP_DBL *noise, *noise_in;
+ FIXP_DBL
+ noise_buf[L_FILT + (2 * L_SUBFR)]; // L_FILT = 12, L_SUBFR = 64 => 140
+ const FIXP_DBL *x, *y;
+
+ {
+ noise = noise_buf + L_FILT; // L_FILT = 12 delay of upsampling filter
+ noise_in = noise_buf + L_FILT + L_SUBFR;
+ /* Input scaling of the BPF memory */
+ scaleValues(mem_bpf, (L_FILT + L_SUBFR), 1);
+ }
+
+ int gain_exp = 17;
+
+ sf = 0;
+ for (i_subfr = 0; i_subfr < l_frame; i_subfr += L_SUBFR, sf++) {
+ T = T_sf[sf];
+ gain = pit_gain[sf];
+
+ /* Gain is in Q17.14 */
+ /* If gain > 1 set to 1 */
+ if (gain > (FIXP_DBL)(1 << 14)) gain = (FIXP_DBL)(1 << 14);
+
+ /* If gain < 0 set to 0 */
+ if (gain < (FIXP_DBL)0) gain = (FIXP_DBL)0;
+
+ if (gain > (FIXP_DBL)0) {
+ /* pitch tracker: test pitch/2 to avoid continuous pitch doubling */
+ /* Note: pitch is limited to PIT_MIN (34 = 376Hz) at the encoder */
+ T2 = T >> 1;
+ x = &syn[i_subfr - L_EXTRA];
+ y = &syn[i_subfr - T2 - L_EXTRA];
+
+ ener = (FIXP_DBL)0;
+ corr = (FIXP_DBL)0;
+ tmp = (FIXP_DBL)0;
+
+ int headroom_x = getScalefactor(x, L_SUBFR + L_EXTRA);
+ int headroom_y = getScalefactor(y, L_SUBFR + L_EXTRA);
+
+ int width_shift = 7;
+
+ for (i = 0; i < (L_SUBFR + L_EXTRA); i++) {
+ ener += fPow2Div2((x[i] << headroom_x)) >> width_shift;
+ corr += fMultDiv2((x[i] << headroom_x), (y[i] << headroom_y)) >>
+ width_shift;
+ tmp += fPow2Div2((y[i] << headroom_y)) >> width_shift;
+ }
+
+ int exp_ener = ((17 - headroom_x) << 1) + width_shift + 1;
+ int exp_corr = (17 - headroom_x) + (17 - headroom_y) + width_shift + 1;
+ int exp_tmp = ((17 - headroom_y) << 1) + width_shift + 1;
+
+ /* Add 0.01 to "ener". Adjust exponents */
+ FIXP_DBL point_zero_one = (FIXP_DBL)0x51eb851f; /* In Q-6.37 */
+ int diff;
+ ener = fAddNorm(ener, exp_ener, point_zero_one, -6, &exp_ener);
+ corr = fAddNorm(corr, exp_corr, point_zero_one, -6, &exp_corr);
+ tmp = fAddNorm(tmp, exp_tmp, point_zero_one, -6, &exp_tmp);
+
+ /* use T2 if normalized correlation > 0.95 */
+ INT s1, s2;
+ s1 = CntLeadingZeros(ener) - 1;
+ s2 = CntLeadingZeros(tmp) - 1;
+
+ FIXP_DBL ener_by_tmp = fMultDiv2(ener << s1, tmp << s2);
+ int ener_by_tmp_exp = (exp_ener - s1) + (exp_tmp - s2) + 1;
+
+ if (ener_by_tmp_exp & 1) {
+ ener_by_tmp <<= 1;
+ ener_by_tmp_exp -= 1;
+ }
+
+ int temp_exp = 0;
+
+ FIXP_DBL temp1 = invSqrtNorm2(ener_by_tmp, &temp_exp);
+
+ int temp1_exp = temp_exp - (ener_by_tmp_exp >> 1);
+
+ FIXP_DBL tmp_result = fMult(corr, temp1);
+
+ int tmp_result_exp = exp_corr + temp1_exp;
+
+ diff = tmp_result_exp - 0;
+ FIXP_DBL point95 = FL2FXCONST_DBL(0.95f);
+ if (diff >= 0) {
+ diff = fMin(diff, 31);
+ point95 = FL2FXCONST_DBL(0.95f) >> diff;
+ } else {
+ diff = fMax(diff, -31);
+ tmp_result >>= (-diff);
+ }
+
+ if (tmp_result > point95) T = T2;
+
+ /* prevent that noise calculation below reaches into not defined signal
+ parts at the end of the synth_buf or in other words restrict the below
+ used index (i+i_subfr+T) < l_frame + l_next
+ */
+ lg = l_frame + l_next - T - i_subfr;
+
+ if (lg > L_SUBFR)
+ lg = L_SUBFR;
+ else if (lg < 0)
+ lg = 0;
+
+ /* limit gain to avoid problem on burst */
+ if (lg > 0) {
+ FIXP_DBL tmp1;
+
+ /* max(lg) = 64 => scale with 6 bits minus 1 (fPow2Div2) */
+
+ s1 = getScalefactor(&syn[i_subfr], lg);
+ s2 = getScalefactor(&syn[i_subfr + T], lg);
+ INT s = fixMin(s1, s2);
+
+ tmp = (FIXP_DBL)0;
+ ener = (FIXP_DBL)0;
+ for (i = 0; i < lg; i++) {
+ tmp += fPow2Div2(syn[i + i_subfr] << s1) >> (SF_PITCH_TRACK);
+ ener += fPow2Div2(syn[i + i_subfr + T] << s2) >> (SF_PITCH_TRACK);
+ }
+ tmp = tmp >> fMin(DFRACT_BITS - 1, (2 * (s1 - s)));
+ ener = ener >> fMin(DFRACT_BITS - 1, (2 * (s2 - s)));
+
+ /* error robustness: for the specific case syn[...] == -1.0f for all 64
+ samples ener or tmp might overflow and become negative. For all sane
+ cases we have enough headroom.
+ */
+ if (ener <= (FIXP_DBL)0) {
+ ener = (FIXP_DBL)1;
+ }
+ if (tmp <= (FIXP_DBL)0) {
+ tmp = (FIXP_DBL)1;
+ }
+ FDK_ASSERT(ener > (FIXP_DBL)0);
+
+ /* tmp = sqrt(tmp/ener) */
+ int result_e = 0;
+ tmp1 = fDivNorm(tmp, ener, &result_e);
+ if (result_e & 1) {
+ tmp1 >>= 1;
+ result_e += 1;
+ }
+ tmp = sqrtFixp(tmp1);
+ result_e >>= 1;
+
+ gain_exp = 17;
+
+ diff = result_e - gain_exp;
+
+ FIXP_DBL gain1 = gain;
+
+ if (diff >= 0) {
+ diff = fMin(diff, 31);
+ gain1 >>= diff;
+ } else {
+ result_e += (-diff);
+ diff = fMax(diff, -31);
+ tmp >>= (-diff);
+ }
+
+ if (tmp < gain1) {
+ gain = tmp;
+ gain_exp = result_e;
+ }
+ }
+
+ /* calculate noise based on voiced pitch */
+ /* fMultDiv2() replaces weighting of gain with 0.5 */
+ diff = gain_exp - 17;
+ if (diff >= 0) {
+ gain <<= diff;
+ } else {
+ gain >>= (-diff);
+ }
+
+ s1 = CntLeadingZeros(gain) - 1;
+ s1 -= 16; /* Leading bits for SGL */
+
+ FIXP_SGL gainSGL = FX_DBL2FX_SGL(gain << 16);
+
+ gainSGL = gainSGL << s1;
+
+ {
+ for (i = 0; i < lg; i++) {
+ /* scaled with SF_SYNTH + gain_sf + 1 */
+ noise_in[i] =
+ (fMult(gainSGL, syn[i + i_subfr] - (syn[i + i_subfr - T] >> 1) -
+ (syn[i + i_subfr + T] >> 1))) >>
+ s1;
+ }
+
+ for (i = lg; i < L_SUBFR; i++) {
+ /* scaled with SF_SYNTH + gain_sf + 1 */
+ noise_in[i] =
+ (fMult(gainSGL, syn[i + i_subfr] - syn[i + i_subfr - T])) >> s1;
+ }
+ }
+ } else {
+ FDKmemset(noise_in, (FIXP_DBL)0, L_SUBFR * sizeof(FIXP_DBL));
+ }
+
+ {
+ FDKmemcpy(noise_buf, mem_bpf, (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
+
+ FDKmemcpy(mem_bpf, noise_buf + L_SUBFR,
+ (L_FILT + L_SUBFR) * sizeof(FIXP_DBL));
+ }
+
+ /* substract from voiced speech low-pass filtered noise */
+ /* filter coefficients are scaled with factor SF_FILT_LP (1) */
+
+ {
+ filtLP(&syn[i_subfr - L_SUBFR], &synth_out[i_subfr], noise,
+ fdk_dec_filt_lp, L_SUBFR, L_FILT);
+ }
+ }
+
+ {
+
+ }
+
+ // To be determined (info from Ben)
+ {
+ /* Output scaling of the BPF memory */
+ scaleValues(mem_bpf, (L_FILT + L_SUBFR), -1);
+ /* Copy the rest of the signal (after the fac) */
+ scaleValuesSaturate((FIXP_PCM *)&synth_out[l_frame],
+ (FIXP_DBL *)&syn[l_frame - L_SUBFR],
+ (frame_length - l_frame), MDCT_OUT_HEADROOM);
+ }
+
+ return;
+}
+
+/*
+ * Frequency Domain Noise Shaping
+ */
+
+/**
+ * \brief Adaptive Low Frequencies Deemphasis of spectral coefficients.
+ *
+ * Ensure quantization of low frequencies in case where the
+ * signal dynamic is higher than the LPC noise shaping.
+ * This is the inverse operation of adap_low_freq_emph().
+ * Output gain of all blocks.
+ *
+ * \param x pointer to the spectral coefficients, requires 1 bit headroom.
+ * \param lg length of x.
+ * \param bUseNewAlfe if set, apply ALFD for fullband lpd.
+ * \param gainLpc1 pointer to gain based on old input LPC coefficients.
+ * \param gainLpc2 pointer to gain based on new input LPC coefficients.
+ * \param alfd_gains pointer to output gains.
+ * \param s current scale shift factor of x.
+ */
+#define ALFDPOW2_SCALE 3
+/*static*/
+void CLpd_AdaptLowFreqDeemph(FIXP_DBL x[], int lg, FIXP_DBL alfd_gains[],
+ INT s) {
+ {
+ int i, j, k, i_max;
+ FIXP_DBL max, fac;
+ /* Note: This stack array saves temporary accumulation results to be used in
+ * a second run */
+ /* The size should be limited to (1024/4)/8=32 */
+ FIXP_DBL tmp_pow2[32];
+
+ s = s * 2 + ALFDPOW2_SCALE;
+ s = fMin(31, s);
+
+ k = 8;
+ i_max = lg / 4; /* ALFD range = 1600Hz (lg = 6400Hz) */
+
+ /* find spectral peak */
+ max = FL2FX_DBL(0.01f) >> s;
+ for (i = 0; i < i_max; i += k) {
+ FIXP_DBL tmp;
+
+ tmp = FIXP_DBL(0);
+ FIXP_DBL *pX = &x[i];
+
+ j = 8;
+ do {
+ FIXP_DBL x0 = *pX++;
+ FIXP_DBL x1 = *pX++;
+ x0 = fPow2Div2(x0);
+ x1 = fPow2Div2(x1);
+ tmp = tmp + (x0 >> (ALFDPOW2_SCALE - 1));
+ tmp = tmp + (x1 >> (ALFDPOW2_SCALE - 1));
+ } while ((j = j - 2) != 0);
+ tmp = fMax(tmp, (FL2FX_DBL(0.01f) >> s));
+ tmp_pow2[i >> 3] = tmp;
+ if (tmp > max) {
+ max = tmp;
+ }
+ }
+
+ /* deemphasis of all blocks below the peak */
+ fac = FL2FX_DBL(0.1f) >> 1;
+ for (i = 0; i < i_max; i += k) {
+ FIXP_DBL tmp;
+ INT shifti;
+
+ tmp = tmp_pow2[i >> 3];
+
+ /* tmp = (float)sqrt(tmp/max); */
+
+ /* value of tmp is between 8/2*max^2 and max^2 / 2. */
+ /* required shift factor of division can grow up to 27
+ (grows exponentially for values toward zero)
+ thus using normalized division to assure valid result. */
+ {
+ INT sd;
+
+ if (tmp != (FIXP_DBL)0) {
+ tmp = fDivNorm(max, tmp, &sd);
+ if (sd & 1) {
+ sd++;
+ tmp >>= 1;
+ }
+ } else {
+ tmp = (FIXP_DBL)MAXVAL_DBL;
+ sd = 0;
+ }
+ tmp = invSqrtNorm2(tmp, &shifti);
+ tmp = scaleValue(tmp, shifti - 1 - (sd / 2));
+ }
+ if (tmp > fac) {
+ fac = tmp;
+ }
+ FIXP_DBL *pX = &x[i];
+
+ j = 8;
+ do {
+ FIXP_DBL x0 = pX[0];
+ FIXP_DBL x1 = pX[1];
+ x0 = fMultDiv2(x0, fac);
+ x1 = fMultDiv2(x1, fac);
+ x0 = x0 << 2;
+ x1 = x1 << 2;
+ *pX++ = x0;
+ *pX++ = x1;
+
+ } while ((j = j - 2) != 0);
+ /* Store gains for FAC */
+ *alfd_gains++ = fac;
+ }
+ }
+}
+
+/**
+ * \brief Interpolated Noise Shaping for mdct coefficients.
+ * This algorithm shapes temporally the spectral noise between
+ * the two spectral noise represention (FDNS_NPTS of resolution).
+ * The noise is shaped monotonically between the two points
+ * using a curved shape to favor the lower gain in mid-frame.
+ * ODFT and amplitud calculation are applied to the 2 LPC coefficients first.
+ *
+ * \param r pointer to spectrum data.
+ * \param rms RMS of output spectrum.
+ * \param lg length of r.
+ * \param A1 pointer to old input LPC coefficients of length M_LP_FILTER_ORDER
+ * scaled by SF_A_COEFFS.
+ * \param A2 pointer to new input LPC coefficients of length M_LP_FILTER_ORDER
+ * scaled by SF_A_COEFFS.
+ * \param bLpc2Mdct flags control lpc2mdct conversion and noise shaping.
+ * \param gainLpc1 pointer to gain based on old input LPC coefficients.
+ * \param gainLpc2 pointer to gain based on new input LPC coefficients.
+ * \param gLpc_e pointer to exponent of gainLpc1 and gainLpc2.
+ */
+/* static */
+#define NSHAPE_SCALE (4)
+
+#define LPC2MDCT_CALC (1)
+#define LPC2MDCT_GAIN_LOAD (2)
+#define LPC2MDCT_GAIN_SAVE (4)
+#define LPC2MDCT_APPLY_NSHAPE (8)
+
+void lpc2mdctAndNoiseShaping(FIXP_DBL *r, SHORT *pScale, const INT lg,
+ const INT fdns_npts, const FIXP_LPC *A1,
+ const INT A1_exp, const FIXP_LPC *A2,
+ const INT A2_exp) {
+ FIXP_DBL *tmp2 = NULL;
+ FIXP_DBL rr_minus_one;
+ int i, k, s, step;
+
+ C_AALLOC_SCRATCH_START(tmp1, FIXP_DBL, FDNS_NPTS * 8)
+
+ {
+ tmp2 = tmp1 + fdns_npts * 4;
+
+ /* lpc2mdct() */
+
+ /* ODFT. E_LPC_a_weight() for A1 and A2 vectors is included into the loop
+ * below. */
+ FIXP_DBL f = FL2FXCONST_DBL(0.92f);
+
+ const FIXP_STP *SinTab;
+ int k_step;
+ /* needed values: sin(phi), cos(phi); phi = i*PI/(2*fdns_npts), i = 0 ...
+ * M_LP_FILTER_ORDER */
+ switch (fdns_npts) {
+ case 64:
+ SinTab = SineTable512;
+ k_step = (512 / 64);
+ FDK_ASSERT(512 >= 64);
+ break;
+ case 48:
+ SinTab = SineTable384;
+ k_step = 384 / 48;
+ FDK_ASSERT(384 >= 48);
+ break;
+ default:
+ FDK_ASSERT(0);
+ return;
+ }
+
+ for (i = 0, k = k_step; i < M_LP_FILTER_ORDER; i++, k += k_step) {
+ FIXP_STP cs = SinTab[k];
+ FIXP_DBL wA1, wA2;
+
+ wA1 = fMult(A1[i], f);
+ wA2 = fMult(A2[i], f);
+
+ /* r[i] = A[i]*cos() */
+ tmp1[2 + i * 2] = fMult(wA1, cs.v.re);
+ tmp2[2 + i * 2] = fMult(wA2, cs.v.re);
+ /* i[i] = A[i]*sin() */
+ tmp1[3 + i * 2] = -fMult(wA1, cs.v.im);
+ tmp2[3 + i * 2] = -fMult(wA2, cs.v.im);
+
+ f = fMult(f, FL2FXCONST_DBL(0.92f));
+ }
+
+ /* Guarantee at least 2 bits of headroom for the FFT */
+ /* "3" stands for 1.0 with 2 bits of headroom; (A1_exp + 2) guarantess 2
+ * bits of headroom if A1_exp > 1 */
+ int A1_exp_fix = fMax(3, A1_exp + 2);
+ int A2_exp_fix = fMax(3, A2_exp + 2);
+
+ /* Set 1.0 in the proper format */
+ tmp1[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A1_exp_fix);
+ tmp2[0] = (FIXP_DBL)(INT)((ULONG)0x80000000 >> A2_exp_fix);
+
+ tmp1[1] = tmp2[1] = (FIXP_DBL)0;
+
+ /* Clear the resto of the array */
+ FDKmemclear(
+ tmp1 + 2 * (M_LP_FILTER_ORDER + 1),
+ 2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
+ FDKmemclear(
+ tmp2 + 2 * (M_LP_FILTER_ORDER + 1),
+ 2 * (fdns_npts * 2 - (M_LP_FILTER_ORDER + 1)) * sizeof(FIXP_DBL));
+
+ /* Guarantee 2 bits of headroom for FFT */
+ scaleValues(&tmp1[2], (2 * M_LP_FILTER_ORDER), (A1_exp - A1_exp_fix));
+ scaleValues(&tmp2[2], (2 * M_LP_FILTER_ORDER), (A2_exp - A2_exp_fix));
+
+ INT s2;
+ s = A1_exp_fix;
+ s2 = A2_exp_fix;
+
+ fft(2 * fdns_npts, tmp1, &s);
+ fft(2 * fdns_npts, tmp2, &s2);
+
+ /* Adjust the exponents of both fft outputs if necessary*/
+ if (s > s2) {
+ scaleValues(tmp2, 2 * fdns_npts, s2 - s);
+ s2 = s;
+ } else if (s < s2) {
+ scaleValues(tmp1, 2 * fdns_npts, s - s2);
+ s = s2;
+ }
+
+ FDK_ASSERT(s == s2);
+ }
+
+ /* Get amplitude and apply gains */
+ step = lg / fdns_npts;
+ rr_minus_one = (FIXP_DBL)0;
+
+ for (k = 0; k < fdns_npts; k++) {
+ FIXP_DBL g1, g2, inv_g1_g2, a, b;
+ INT inv_g1_g2_e;
+ int g_e, shift;
+
+ {
+ FIXP_DBL real, imag;
+ int si1, si2, sInput;
+
+ real = tmp1[k * 2];
+ imag = tmp1[k * 2 + 1];
+ sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
+ real <<= sInput;
+ imag <<= sInput;
+ /* g1_e = si1 - 2*s/2 */
+ g1 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si1);
+ si1 += sInput;
+
+ real = tmp2[k * 2];
+ imag = tmp2[k * 2 + 1];
+ sInput = fMax(fMin(fNorm(real), fNorm(imag)) - 1, 0);
+ real <<= sInput;
+ imag <<= sInput;
+ /* g2_e = si2 - 2*s/2 */
+ g2 = invSqrtNorm2(fPow2(real) + fPow2(imag), &si2);
+ si2 += sInput;
+
+ /* Pick a common scale factor for g1 and g2 */
+ if (si1 > si2) {
+ g2 >>= si1 - si2;
+ g_e = si1 - s;
+ } else {
+ g1 >>= si2 - si1;
+ g_e = si2 - s;
+ }
+ }
+
+ /* end of lpc2mdct() */
+
+ FDK_ASSERT(g1 >= (FIXP_DBL)0);
+ FDK_ASSERT(g2 >= (FIXP_DBL)0);
+
+ /* mdct_IntNoiseShaping() */
+ {
+ /* inv_g1_g2 * 2^inv_g1_g2_e = 1/(g1+g2) */
+ inv_g1_g2 = (g1 >> 1) + (g2 >> 1);
+ if (inv_g1_g2 != (FIXP_DBL)0) {
+ inv_g1_g2 = fDivNorm(FL2FXCONST_DBL(0.5f), inv_g1_g2, &inv_g1_g2_e);
+ inv_g1_g2_e = inv_g1_g2_e - g_e;
+ } else {
+ inv_g1_g2 = (FIXP_DBL)MAXVAL_DBL;
+ inv_g1_g2_e = 0;
+ }
+
+ if (g_e < 0) {
+ /* a_e = g_e + inv_g1_g2_e + 1 */
+ a = scaleValue(fMult(fMult(g1, g2), inv_g1_g2), g_e);
+ /* b_e = g_e + inv_g1_g2_e */
+ b = fMult(g2 - g1, inv_g1_g2);
+ shift = g_e + inv_g1_g2_e + 1 - NSHAPE_SCALE;
+ } else {
+ /* a_e = (g_e+g_e) + inv_g1_g2_e + 1 */
+ a = fMult(fMult(g1, g2), inv_g1_g2);
+ /* b_e = (g_e+g_e) + inv_g1_g2_e */
+ b = scaleValue(fMult(g2 - g1, inv_g1_g2), -g_e);
+ shift = (g_e + g_e) + inv_g1_g2_e + 1 - NSHAPE_SCALE;
+ }
+
+ for (i = k * step; i < (k + 1) * step; i++) {
+ FIXP_DBL tmp;
+
+ /* rr[i] = 2*a*r[i] + b*rr[i-1] */
+ tmp = fMult(a, r[i]);
+ tmp += scaleValue(fMultDiv2(b, rr_minus_one), NSHAPE_SCALE);
+ tmp = scaleValueSaturate(tmp, shift);
+ rr_minus_one = tmp;
+ r[i] = tmp;
+ }
+ }
+ }
+
+ /* end of mdct_IntNoiseShaping() */
+ { *pScale += NSHAPE_SCALE; }
+
+ C_AALLOC_SCRATCH_END(tmp1, FIXP_DBL, FDNS_NPTS * 8)
+}
+
+/**
+ * \brief Calculates the energy.
+ * \param r pointer to spectrum.
+ * \param rs scale factor of spectrum r.
+ * \param lg frame length in audio samples.
+ * \param rms_e pointer to exponent of energy value.
+ * \return mantissa of energy value.
+ */
+static FIXP_DBL calcEnergy(const FIXP_DBL *r, const SHORT rs, const INT lg,
+ INT *rms_e) {
+ int headroom = getScalefactor(r, lg);
+
+ FIXP_DBL rms_m = 0;
+
+ /* Calculate number of growth bits due to addition */
+ INT shift = (INT)(fNormz((FIXP_DBL)lg));
+ shift = 31 - shift;
+
+ /* Generate 1e-2 in Q-6.37 */
+ const FIXP_DBL value0_01 = 0x51eb851e;
+ const INT value0_01_exp = -6;
+
+ /* Find the exponent of the resulting energy value */
+ *rms_e = ((rs - headroom) << 1) + shift + 1;
+
+ INT delta = *rms_e - value0_01_exp;
+ if (delta > 0) {
+ /* Limit shift_to 31*/
+ delta = fMin(31, delta);
+ rms_m = value0_01 >> delta;
+ } else {
+ rms_m = value0_01;
+ *rms_e = value0_01_exp;
+ shift = shift - delta;
+ /* Limit shift_to 31*/
+ shift = fMin(31, shift);
+ }
+
+ for (int i = 0; i < lg; i++) {
+ rms_m += fPow2Div2(r[i] << headroom) >> shift;
+ }
+
+ return rms_m;
+}
+
+/**
+ * \brief TCX gain calculation.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param r output spectrum.
+ * \param rms_e pointer to mantissa of energy value.
+ * \param rms_e pointer to exponent of energy value.
+ * \param frame the frame index of the LPD super frame.
+ * \param lg the frame length in audio samples.
+ * \param gain_m pointer to mantissa of TCX gain.
+ * \param gain_e pointer to exponent of TCX gain.
+ * \param elFlags element specific parser guidance flags.
+ * \param lg_fb the fullband frame length in audio samples.
+ * \param IGF_bgn the IGF start index.
+ */
+static void calcTCXGain(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ FIXP_DBL *r, FIXP_DBL rms_m, INT rms_e, const INT frame,
+ const INT lg) {
+ if ((rms_m != (FIXP_DBL)0)) {
+ FIXP_DBL tcx_gain_m;
+ INT tcx_gain_e;
+
+ CLpd_DecodeGain(&tcx_gain_m, &tcx_gain_e,
+ pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .tcx_global_gain[frame]);
+
+ /* rms * 2^rms_e = lg/sqrt(sum(spec^2)) */
+ if (rms_e & 1) {
+ rms_m >>= 1;
+ rms_e++;
+ }
+
+ {
+ FIXP_DBL fx_lg;
+ INT fx_lg_e, s;
+ INT inv_e;
+
+ /* lg = fx_lg * 2^fx_lg_e */
+ s = fNorm((FIXP_DBL)lg);
+ fx_lg = (FIXP_DBL)lg << s;
+ fx_lg_e = DFRACT_BITS - 1 - s;
+ /* 1/sqrt(rms) */
+ rms_m = invSqrtNorm2(rms_m, &inv_e);
+ rms_m = fMult(rms_m, fx_lg);
+ rms_e = inv_e - (rms_e >> 1) + fx_lg_e;
+ }
+
+ {
+ int s = fNorm(tcx_gain_m);
+ tcx_gain_m = tcx_gain_m << s;
+ tcx_gain_e -= s;
+ }
+
+ tcx_gain_m = fMultDiv2(tcx_gain_m, rms_m);
+ tcx_gain_e = tcx_gain_e + rms_e;
+
+ /* global_gain * 2^(global_gain_e+rms_e) = (10^(global_gain/28)) * rms *
+ * 2^rms_e */
+ {
+ { tcx_gain_e += 1; }
+ }
+
+ pAacDecoderChannelInfo->data.usac.tcx_gain[frame] = tcx_gain_m;
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[frame] = tcx_gain_e;
+
+ pAacDecoderChannelInfo->specScale[frame] += tcx_gain_e;
+ }
+}
+
+/**
+ * \brief FDNS decoding.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param pAacDecoderStaticChannelInfo channel context static data.
+ * \param r output spectrum.
+ * \param lg the frame length in audio samples.
+ * \param frame the frame index of the LPD super frame.
+ * \param pScale pointer to current scale shift factor of r[].
+ * \param A1 old input LPC coefficients of length M_LP_FILTER_ORDER.
+ * \param A2 new input LPC coefficients of length M_LP_FILTER_ORDER.
+ * \param pAlfdGains pointer for ALFD gains output scaled by 1.
+ * \param fdns_npts number of lines (FDNS_NPTS).
+ * \param inf_mask pointer to noise mask.
+ * \param IGF_win_mode IGF window mode (LONG, SHORT, TCX10, TCX20).
+ * \param frameType (IGF_FRAME_DIVISION_AAC_OR_TCX_LONG or
+ * IGF_FRAME_DIVISION_TCX_SHORT_1).
+ * \param elFlags element specific parser guidance flags.
+ * \param lg_fb the fullband frame length in audio samples.
+ * \param IGF_bgn the IGF start index.
+ * \param rms_m mantisse of energy.
+ * \param rms_e exponent of energy.
+ */
+/* static */
+void CLpd_FdnsDecode(CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ FIXP_DBL r[], const INT lg, const INT frame, SHORT *pScale,
+ const FIXP_LPC A1[M_LP_FILTER_ORDER], const INT A1_exp,
+ const FIXP_LPC A2[M_LP_FILTER_ORDER], const INT A2_exp,
+ FIXP_DBL pAlfdGains[LFAC / 4], const INT fdns_npts) {
+ /* Weight LPC coefficients using Rm values */
+ CLpd_AdaptLowFreqDeemph(r, lg, pAlfdGains, *pScale);
+
+ FIXP_DBL rms_m = (FIXP_DBL)0;
+ INT rms_e = 0;
+ {
+ /* Calculate Energy */
+ rms_m = calcEnergy(r, *pScale, lg, &rms_e);
+ }
+
+ calcTCXGain(pAacDecoderChannelInfo, r, rms_m, rms_e, frame, lg);
+
+ /* Apply ODFT and Noise Shaping. LP coefficient (A1, A2) weighting is done
+ * inside on the fly. */
+
+ lpc2mdctAndNoiseShaping(r, pScale, lg, fdns_npts, A1, A1_exp, A2, A2_exp);
+}
+
+/**
+ * find pitch for TCX20 (time domain) concealment.
+ */
+static int find_mpitch(FIXP_DBL xri[], int lg) {
+ FIXP_DBL max, pitch;
+ INT pitch_e;
+ int i, n;
+
+ max = (FIXP_DBL)0;
+ n = 2;
+
+ /* find maximum below 400Hz */
+ for (i = 2; i < (lg >> 4); i += 2) {
+ FIXP_DBL tmp = fPow2Div2(xri[i]) + fPow2Div2(xri[i + 1]);
+ if (tmp > max) {
+ max = tmp;
+ n = i;
+ }
+ }
+
+ // pitch = ((float)lg<<1)/(float)n;
+ pitch = fDivNorm((FIXP_DBL)lg << 1, (FIXP_DBL)n, &pitch_e);
+ pitch >>= fixMax(0, DFRACT_BITS - 1 - pitch_e - 16);
+
+ /* find pitch multiple under 20ms */
+ if (pitch >= (FIXP_DBL)((256 << 16) - 1)) { /*231.0f*/
+ n = 256;
+ } else {
+ FIXP_DBL mpitch = pitch;
+ while (mpitch < (FIXP_DBL)(255 << 16)) {
+ mpitch += pitch;
+ }
+ n = (int)(mpitch - pitch) >> 16;
+ }
+
+ return (n);
+}
+
+/**
+ * number of spectral coefficients / time domain samples using frame mode as
+ * index.
+ */
+static const int lg_table_ccfl[2][4] = {
+ {256, 256, 512, 1024}, /* coreCoderFrameLength = 1024 */
+ {192, 192, 384, 768} /* coreCoderFrameLength = 768 */
+};
+
+/**
+ * \brief Decode and render one MDCT-TCX frame.
+ * \param pAacDecoderChannelInfo channel context data.
+ * \param lg the frame length in audio samples.
+ * \param frame the frame index of the LPD super frame.
+ */
+static void CLpd_TcxDecode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags,
+ int mod, int last_mod, int frame, int frameOk) {
+ FIXP_DBL *pAlfd_gains = pAacDecoderStaticChannelInfo->last_alfd_gains;
+ ULONG *pSeed = &pAacDecoderStaticChannelInfo->nfRandomSeed;
+ int lg = (pAacDecoderChannelInfo->granuleLength == 128)
+ ? lg_table_ccfl[0][mod + 0]
+ : lg_table_ccfl[1][mod + 0];
+ int next_frame = frame + (1 << (mod - 1));
+ int isFullBandLpd = 0;
+
+ /* Obtain r[] vector by combining the quant[] and noise[] vectors */
+ {
+ FIXP_DBL noise_level;
+ FIXP_DBL *coeffs =
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
+ int scale = pAacDecoderChannelInfo->specScale[frame];
+ int i, nfBgn, nfEnd;
+ UCHAR tcx_noise_factor = pAacDecoderChannelInfo->pDynData->specificTo.usac
+ .tcx_noise_factor[frame];
+
+ /* find pitch for bfi case */
+ pAacDecoderStaticChannelInfo->last_tcx_pitch = find_mpitch(coeffs, lg);
+
+ if (frameOk) {
+ /* store for concealment */
+ pAacDecoderStaticChannelInfo->last_tcx_noise_factor = tcx_noise_factor;
+ } else {
+ /* restore last frames value */
+ tcx_noise_factor = pAacDecoderStaticChannelInfo->last_tcx_noise_factor;
+ }
+
+ noise_level =
+ (FIXP_DBL)((LONG)FL2FXCONST_DBL(0.0625f) * (8 - tcx_noise_factor));
+ noise_level = scaleValue(noise_level, -scale);
+
+ const FIXP_DBL neg_noise_level = -noise_level;
+
+ {
+ nfBgn = lg / 6;
+ nfEnd = lg;
+ }
+
+ for (i = nfBgn; i < nfEnd - 7; i += 8) {
+ LONG tmp;
+
+ /* Fill all 8 consecutive zero coeffs with noise */
+ tmp = coeffs[i + 0] | coeffs[i + 1] | coeffs[i + 2] | coeffs[i + 3] |
+ coeffs[i + 4] | coeffs[i + 5] | coeffs[i + 6] | coeffs[i + 7];
+
+ if (tmp == 0) {
+ for (int k = i; k < i + 8; k++) {
+ UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
+ : (coeffs[k] = noise_level);
+ }
+ }
+ }
+ if ((nfEnd - i) >
+ 0) { /* noise filling for last "band" with less than 8 bins */
+ LONG tmp = (LONG)coeffs[i];
+ int k;
+
+ FDK_ASSERT((nfEnd - i) < 8);
+ for (k = 1; k < (nfEnd - i); k++) {
+ tmp |= (LONG)coeffs[i + k];
+ }
+ if (tmp == 0) {
+ for (k = i; k < nfEnd; k++) {
+ UsacRandomSign(pSeed) ? (coeffs[k] = neg_noise_level)
+ : (coeffs[k] = noise_level);
+ }
+ }
+ }
+ }
+
+ {
+ /* Convert LPC to LP domain */
+ if (last_mod == 0) {
+ /* Note: The case where last_mod == 255 is handled by other means
+ * in CLpdChannelStream_Read() */
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame]);
+ }
+
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[next_frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame]);
+
+ /* FDNS decoding */
+ CLpd_FdnsDecode(
+ pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ lg, frame, pAacDecoderChannelInfo->specScale + frame,
+ pAacDecoderChannelInfo->data.usac.lp_coeff[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[next_frame],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[next_frame], pAlfd_gains,
+ pAacDecoderChannelInfo->granuleLength / 2 /* == FDNS_NPTS(ccfl) */
+ );
+ }
+}
+
+/**
+ * \brief Read the tcx_coding bitstream part
+ * \param hBs bitstream handle to read from.
+ * \param pAacDecoderChannelInfo channel context info to store data into.
+ * \param lg the frame length in audio samples.
+ * \param first_tcx_flag flag indicating that this is the first TCX frame.
+ * \param frame the frame index of the LPD super frame.
+ */
+static AAC_DECODER_ERROR CLpd_TCX_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, int lg,
+ int first_tcx_flag, int frame, UINT flags) {
+ AAC_DECODER_ERROR errorAAC = AAC_DEC_OK;
+ ARITH_CODING_ERROR error = ARITH_CODER_OK;
+ FIXP_DBL *pSpec;
+ int arith_reset_flag = 0;
+ int isFullBandLpd = 0;
+
+ pSpec = SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, frame,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd);
+
+ /* TCX noise level */
+ {
+ pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_noise_factor[frame] =
+ FDKreadBits(hBs, 3);
+ }
+ /* TCX global gain */
+ pAacDecoderChannelInfo->pDynData->specificTo.usac.tcx_global_gain[frame] =
+ FDKreadBits(hBs, 7);
+
+ /* Arithmetic coded residual/spectrum */
+ if (first_tcx_flag) {
+ if (flags & AC_INDEP) {
+ arith_reset_flag = 1;
+ } else {
+ arith_reset_flag = FDKreadBits(hBs, 1);
+ }
+ }
+
+ /* CArco_DecodeArithData() output scale of "pSpec" is DFRACT_BITS-1 */
+ error = CArco_DecodeArithData(pAacDecoderStaticChannelInfo->hArCo, hBs, pSpec,
+ lg, lg, arith_reset_flag);
+
+ /* Rescale residual/spectrum */
+ {
+ int scale = getScalefactor(pSpec, lg) - 2; /* Leave 2 bits headroom */
+
+ /* Exponent of CArco_DecodeArithData() output is DFRACT_BITS; integer
+ * values. */
+ scaleValues(pSpec, lg, scale);
+ scale = DFRACT_BITS - 1 - scale;
+
+ pAacDecoderChannelInfo->specScale[frame] = scale;
+ }
+
+ if (error == ARITH_CODER_ERROR) errorAAC = AAC_DEC_UNKNOWN;
+
+ return errorAAC;
+}
+
+/**
+ * \brief translate lpd_mode into the mod[] array which describes the mode of
+ * each each LPD frame
+ * \param mod[] the array that will be filled with the mode indexes of the
+ * inidividual frames.
+ * \param lpd_mode the lpd_mode field read from the lpd_channel_stream
+ */
+static AAC_DECODER_ERROR CLpd_ReadAndMapLpdModeToModArray(
+ UCHAR mod[4], HANDLE_FDK_BITSTREAM hBs, UINT elFlags) {
+ int lpd_mode;
+
+ {
+ lpd_mode = FDKreadBits(hBs, 5);
+
+ if (lpd_mode > 25 || lpd_mode < 0) {
+ return AAC_DEC_PARSE_ERROR;
+ }
+
+ switch (lpd_mode) {
+ case 25:
+ /* 1 80MS frame */
+ mod[0] = mod[1] = mod[2] = mod[3] = 3;
+ break;
+ case 24:
+ /* 2 40MS frames */
+ mod[0] = mod[1] = mod[2] = mod[3] = 2;
+ break;
+ default:
+ switch (lpd_mode >> 2) {
+ case 4:
+ /* lpd_mode 19 - 16 => 1 40MS and 2 20MS frames */
+ mod[0] = mod[1] = 2;
+ mod[2] = (lpd_mode & 1) ? 1 : 0;
+ mod[3] = (lpd_mode & 2) ? 1 : 0;
+ break;
+ case 5:
+ /* lpd_mode 23 - 20 => 2 20MS and 1 40MS frames */
+ mod[2] = mod[3] = 2;
+ mod[0] = (lpd_mode & 1) ? 1 : 0;
+ mod[1] = (lpd_mode & 2) ? 1 : 0;
+ break;
+ default:
+ /* lpd_mode < 16 => 4 20MS frames */
+ mod[0] = (lpd_mode & 1) ? 1 : 0;
+ mod[1] = (lpd_mode & 2) ? 1 : 0;
+ mod[2] = (lpd_mode & 4) ? 1 : 0;
+ mod[3] = (lpd_mode & 8) ? 1 : 0;
+ break;
+ }
+ break;
+ }
+ }
+ return AAC_DEC_OK;
+}
+
+static void CLpd_Reset(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ int keep_past_signal) {
+ int i;
+
+ /* Reset TCX / ACELP common memory */
+ if (!keep_past_signal) {
+ FDKmemclear(pAacDecoderStaticChannelInfo->old_synth,
+ sizeof(pAacDecoderStaticChannelInfo->old_synth));
+ }
+
+ /* Initialize the LSFs */
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ pAacDecoderStaticChannelInfo->lpc4_lsf[i] = fdk_dec_lsf_init[i];
+ }
+
+ /* Reset memory needed by bass post-filter */
+ FDKmemclear(pAacDecoderStaticChannelInfo->mem_bpf,
+ sizeof(pAacDecoderStaticChannelInfo->mem_bpf));
+
+ pAacDecoderStaticChannelInfo->old_bpf_control_info = 0;
+ for (i = 0; i < SYN_SFD; i++) {
+ pAacDecoderStaticChannelInfo->old_T_pf[i] = 64;
+ pAacDecoderStaticChannelInfo->old_gain_pf[i] = (FIXP_DBL)0;
+ }
+
+ /* Reset ACELP memory */
+ CLpd_AcelpReset(&pAacDecoderStaticChannelInfo->acelp);
+
+ pAacDecoderStaticChannelInfo->last_lpc_lost = 0; /* prev_lpc_lost */
+ pAacDecoderStaticChannelInfo->last_tcx_pitch = L_DIV; /* pitch_tcx */
+ pAacDecoderStaticChannelInfo->numLostLpdFrames = 0; /* nbLostCmpt */
+}
+
+/*
+ * Externally visible functions
+ */
+
+AAC_DECODER_ERROR CLpdChannelStream_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, UINT flags) {
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int first_tcx_flag;
+ int k, nbDiv, fFacDataPresent, first_lpd_flag, acelp_core_mode,
+ facGetMemState = 0;
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ int lpd_mode_last, prev_frame_was_lpd;
+ USAC_COREMODE core_mode_last;
+ const int lg_table_offset = 0;
+ const int *lg_table = (pAacDecoderChannelInfo->granuleLength == 128)
+ ? &lg_table_ccfl[0][lg_table_offset]
+ : &lg_table_ccfl[1][lg_table_offset];
+ int last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost;
+
+ int last_frame_ok = CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1);
+
+ INT i_offset;
+ UINT samplingRate;
+
+ samplingRate = pSamplingRateInfo->samplingRate;
+
+ i_offset =
+ (INT)(samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
+ (INT)PIT_MIN_12k8;
+
+ if ((samplingRate < FAC_FSCALE_MIN) || (samplingRate > FAC_FSCALE_MAX)) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ acelp_core_mode = FDKreadBits(hBs, 3);
+
+ /* lpd_mode */
+ error = CLpd_ReadAndMapLpdModeToModArray(mod, hBs, 0);
+ if (error != AAC_DEC_OK) {
+ goto bail;
+ }
+
+ /* bpf_control_info */
+ pAacDecoderChannelInfo->data.usac.bpf_control_info = FDKreadBit(hBs);
+
+ /* last_core_mode */
+ prev_frame_was_lpd = FDKreadBit(hBs);
+ /* fac_data_present */
+ fFacDataPresent = FDKreadBit(hBs);
+
+ /* Set valid values from
+ * pAacDecoderStaticChannelInfo->{last_core_mode,last_lpd_mode} */
+ pAacDecoderChannelInfo->data.usac.core_mode_last =
+ pAacDecoderStaticChannelInfo->last_core_mode;
+ lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last =
+ pAacDecoderStaticChannelInfo->last_lpd_mode;
+
+ if (prev_frame_was_lpd == 0) {
+ /* Last frame was FD */
+ pAacDecoderChannelInfo->data.usac.core_mode_last = FD_LONG;
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
+ } else {
+ /* Last frame was LPD */
+ pAacDecoderChannelInfo->data.usac.core_mode_last = LPD;
+ if (((mod[0] == 0) && fFacDataPresent) ||
+ ((mod[0] != 0) && !fFacDataPresent)) {
+ /* Currend mod is ACELP, fac data present -> TCX, current mod TCX, no fac
+ * data -> TCX */
+ if (lpd_mode_last == 0) {
+ /* Bit stream interruption detected. Assume last TCX mode as TCX20. */
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 1;
+ }
+ /* Else assume that remembered TCX mode is correct. */
+ } else {
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 0;
+ }
+ }
+
+ first_lpd_flag = (pAacDecoderChannelInfo->data.usac.core_mode_last !=
+ LPD); /* Depends on bitstream configuration */
+ first_tcx_flag = 1;
+
+ if (pAacDecoderStaticChannelInfo->last_core_mode !=
+ LPD) { /* ATTENTION: Reset depends on what we rendered before! */
+ CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, 0);
+
+ if (!last_frame_ok) {
+ /* If last rendered frame was not LPD and first lpd flag is not set, this
+ * must be an error - set last_lpc_lost flag */
+ last_lpc_lost |= (first_lpd_flag) ? 0 : 1;
+ }
+ }
+
+ core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last;
+ lpd_mode_last = pAacDecoderChannelInfo->data.usac.lpd_mode_last;
+
+ nbDiv = NB_DIV;
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+
+ k = 0;
+ while (k < nbDiv) {
+ /* Reset FAC data pointers in order to avoid applying old random FAC data.
+ */
+ pAacDecoderChannelInfo->data.usac.fac_data[k] = NULL;
+
+ if ((k == 0 && core_mode_last == LPD && fFacDataPresent) ||
+ (lpd_mode_last == 0 && mod[k] > 0) ||
+ ((lpd_mode_last != 255) && lpd_mode_last > 0 && mod[k] == 0)) {
+ int err;
+
+ /* Assign FAC memory */
+ pAacDecoderChannelInfo->data.usac.fac_data[k] =
+ CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
+
+ /* FAC for (ACELP -> TCX) or (TCX -> ACELP) */
+ err = CLpd_FAC_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->data.usac.fac_data_e,
+ pAacDecoderChannelInfo->granuleLength, /* == fac_length */
+ 0, k);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ if (mod[k] == 0) /* acelp-mode */
+ {
+ int err;
+ err = CLpd_AcelpRead(
+ hBs, &pAacDecoderChannelInfo->data.usac.acelp[k], acelp_core_mode,
+ pAacDecoderChannelInfo->granuleLength * 8 /* coreCoderFrameLength */,
+ i_offset);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+
+ lpd_mode_last = 0;
+ k++;
+ } else /* mode != 0 => TCX */
+ {
+ error = CLpd_TCX_Read(hBs, pAacDecoderChannelInfo,
+ pAacDecoderStaticChannelInfo, lg_table[mod[k]],
+ first_tcx_flag, k, flags);
+
+ lpd_mode_last = mod[k];
+ first_tcx_flag = 0;
+ k += 1 << (mod[k] - 1);
+ }
+ if (error != AAC_DEC_OK) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ {
+ int err;
+
+ /* Read LPC coefficients */
+ err = CLpc_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
+ pAacDecoderChannelInfo->data.usac.aStability, mod, first_lpd_flag,
+ /* if last lpc4 is available from concealment do not extrapolate lpc0
+ from lpc2 */
+ (mod[0] & 0x3) ? 0
+ : (last_lpc_lost &&
+ pAacDecoderStaticChannelInfo->last_core_mode != LPD),
+ last_frame_ok);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ /* adjust old lsp[] following to a bad frame (to avoid overshoot) (ref:
+ * dec_LPD.c) */
+ if (last_lpc_lost && !last_frame_ok) {
+ int k_next;
+ k = 0;
+ while (k < nbDiv) {
+ int i;
+ k_next = k + (((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1)));
+ FIXP_LPC *lsp_old = pAacDecoderChannelInfo->data.usac.lsp_coeff[k];
+ FIXP_LPC *lsp_new = pAacDecoderChannelInfo->data.usac.lsp_coeff[k_next];
+
+ for (i = 0; i < M_LP_FILTER_ORDER; i++) {
+ if (lsp_new[i] < lsp_old[i]) {
+ lsp_old[i] = lsp_new[i];
+ }
+ }
+ k = k_next;
+ }
+ }
+
+ if (!CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
+ } else if (pAacDecoderStaticChannelInfo->last_lpd_mode != 0) {
+ if (pAacDecoderStaticChannelInfo->last_lpd_mode == 255) {
+ /* We need it for TCX decoding or ACELP excitation update */
+ E_LPC_f_lsp_a_conversion(
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ &pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0]);
+ } else { /* last_lpd_mode was TCX */
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ }
+ } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
+
+ if (fFacDataPresent && (core_mode_last != LPD)) {
+ int prev_frame_was_short;
+
+ prev_frame_was_short = FDKreadBit(hBs);
+
+ if (prev_frame_was_short) {
+ core_mode_last = pAacDecoderChannelInfo->data.usac.core_mode_last =
+ FD_SHORT;
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = 255;
+
+ if ((pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) &&
+ CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 1)) {
+ /* USAC Conformance document:
+ short_fac_flag shall be encoded with a value of 1 if the
+ window_sequence of the previous frame was 2 (EIGHT_SHORT_SEQUENCE).
+ Otherwise short_fac_flag shall be encoded with a
+ value of 0. */
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+
+ /* Assign memory */
+ pAacDecoderChannelInfo->data.usac.fac_data[0] =
+ CLpd_FAC_GetMemory(pAacDecoderChannelInfo, mod, &facGetMemState);
+
+ {
+ int err;
+
+ /* FAC for FD -> ACELP */
+ err = CLpd_FAC_Read(
+ hBs, pAacDecoderChannelInfo->data.usac.fac_data[0],
+ pAacDecoderChannelInfo->data.usac.fac_data_e,
+ CLpd_FAC_getLength(core_mode_last != FD_SHORT,
+ pAacDecoderChannelInfo->granuleLength),
+ 1, 0);
+ if (err != 0) {
+ error = AAC_DEC_PARSE_ERROR;
+ goto bail;
+ }
+ }
+ }
+
+bail:
+ if (error == AAC_DEC_OK) {
+ /* check consitency of last core/lpd mode values */
+ if ((pAacDecoderChannelInfo->data.usac.core_mode_last !=
+ pAacDecoderStaticChannelInfo->last_core_mode) &&
+ (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
+ /* Something got wrong! */
+ /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
+ } else if ((pAacDecoderChannelInfo->data.usac.core_mode_last == LPD) &&
+ (pAacDecoderChannelInfo->data.usac.lpd_mode_last !=
+ pAacDecoderStaticChannelInfo->last_lpd_mode) &&
+ (pAacDecoderStaticChannelInfo->last_lpc_lost == 0)) {
+ /* Something got wrong! */
+ /* error = AAC_DEC_PARSE_ERROR; */ /* Throwing errors does not help */
+ }
+ }
+
+ return error;
+}
+
+void CLpdChannelStream_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags) {
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ int k;
+ UCHAR last_lpd_mode;
+ int nbDiv = NB_DIV;
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ last_lpd_mode =
+ pAacDecoderChannelInfo->data.usac
+ .lpd_mode_last; /* could be different to what has been rendered */
+ while (k < nbDiv) {
+ if (mod[k] == 0) {
+ /* ACELP */
+
+ /* If FAC (fac_data[k] != NULL), and previous frame was TCX, apply (TCX)
+ * gains to FAC data */
+ if (last_lpd_mode > 0 && last_lpd_mode != 255 &&
+ pAacDecoderChannelInfo->data.usac.fac_data[k]) {
+ CFac_ApplyGains(pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->granuleLength,
+ pAacDecoderStaticChannelInfo->last_tcx_gain,
+ pAacDecoderStaticChannelInfo->last_alfd_gains,
+ (last_lpd_mode < 4) ? last_lpd_mode : 3);
+
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ }
+ } else {
+ /* TCX */
+ CLpd_TcxDecode(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags, mod[k], last_lpd_mode, k, 1 /* frameOk == 1 */
+ );
+
+ /* Store TCX gain scale for next possible FAC transition. */
+ pAacDecoderStaticChannelInfo->last_tcx_gain =
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k];
+ pAacDecoderStaticChannelInfo->last_tcx_gain_e =
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
+
+ /* If FAC (fac_data[k] != NULL), apply gains */
+ if (last_lpd_mode == 0 && pAacDecoderChannelInfo->data.usac.fac_data[k]) {
+ CFac_ApplyGains(
+ pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->granuleLength /* == fac_length */,
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ pAacDecoderStaticChannelInfo->last_alfd_gains, mod[k]);
+
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] +=
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k];
+ }
+ }
+
+ /* remember previous mode */
+ last_lpd_mode = mod[k];
+
+ /* Increase k to next frame */
+ k += (mod[k] == 0) ? 1 : (1 << (mod[k] - 1));
+ }
+}
+
+AAC_DECODER_ERROR CLpd_RenderTimeSignal(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
+ INT lFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk, UINT flags,
+ UINT strmFlags) {
+ UCHAR *mod = pAacDecoderChannelInfo->data.usac.mod;
+ AAC_DECODER_ERROR error = AAC_DEC_OK;
+ int k, i_offset;
+ int last_k;
+ int nrSamples = 0;
+ int facFB = 1;
+ int nbDiv = NB_DIV;
+ int lDiv = lFrame / nbDiv; /* length of division (acelp or tcx20 frame)*/
+ int lFac = lDiv / 2;
+ int nbSubfr =
+ lFrame / (nbDiv * L_SUBFR); /* number of subframes per division */
+ int nbSubfrSuperfr = nbDiv * nbSubfr;
+ int synSfd = (nbSubfrSuperfr / 2) - BPF_SFD;
+ int SynDelay = synSfd * L_SUBFR;
+ int aacDelay = lFrame / 2;
+
+ /*
+ In respect to the reference software, the synth pointer here is lagging by
+ aacDelay ( == SYN_DELAY + BPF_DELAY ) samples. The corresponding old
+ synthesis samples are handled by the IMDCT overlap.
+ */
+
+ FIXP_DBL *synth_buf =
+ pAacDecoderChannelInfo->pComStaticData->pWorkBufferCore1->synth_buf;
+ FIXP_DBL *synth = synth_buf + PIT_MAX_MAX - BPF_DELAY;
+ UCHAR last_lpd_mode, last_last_lpd_mode, last_lpc_lost, last_frame_lost;
+
+ INT pitch[NB_SUBFR_SUPERFR + SYN_SFD];
+ FIXP_DBL pit_gain[NB_SUBFR_SUPERFR + SYN_SFD];
+
+ const int *lg_table;
+ int lg_table_offset = 0;
+
+ UINT samplingRate = pSamplingRateInfo->samplingRate;
+
+ FDKmemclear(pitch, (NB_SUBFR_SUPERFR + SYN_SFD) * sizeof(INT));
+
+ if (flags & AACDEC_FLUSH) {
+ CLpd_Reset(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo,
+ flags & AACDEC_FLUSH);
+ frameOk = 0;
+ }
+
+ switch (lFrame) {
+ case 1024:
+ lg_table = &lg_table_ccfl[0][lg_table_offset];
+ break;
+ case 768:
+ lg_table = &lg_table_ccfl[1][lg_table_offset];
+ break;
+ default:
+ FDK_ASSERT(0);
+ return AAC_DEC_UNKNOWN;
+ }
+
+ last_frame_lost = !CConcealment_GetLastFrameOk(
+ &pAacDecoderStaticChannelInfo->concealmentInfo, 0);
+
+ /* Maintain LPD mode from previous frame */
+ if ((pAacDecoderStaticChannelInfo->last_core_mode == FD_LONG) ||
+ (pAacDecoderStaticChannelInfo->last_core_mode == FD_SHORT)) {
+ pAacDecoderStaticChannelInfo->last_lpd_mode = 255;
+ }
+
+ if (!frameOk) {
+ FIXP_DBL old_tcx_gain;
+ FIXP_SGL old_stab;
+ SCHAR old_tcx_gain_e;
+ int nLostSf;
+
+ last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
+ old_tcx_gain = pAacDecoderStaticChannelInfo->last_tcx_gain;
+ old_tcx_gain_e = pAacDecoderStaticChannelInfo->last_tcx_gain_e;
+ old_stab = pAacDecoderStaticChannelInfo->oldStability;
+ nLostSf = pAacDecoderStaticChannelInfo->numLostLpdFrames;
+
+ /* patch the last LPD mode */
+ pAacDecoderChannelInfo->data.usac.lpd_mode_last = last_lpd_mode;
+
+ /* Do mode extrapolation and repeat the previous mode:
+ if previous mode = ACELP -> ACELP
+ if previous mode = TCX-20/40 -> TCX-20
+ if previous mode = TCX-80 -> TCX-80
+ notes:
+ - ACELP is not allowed after TCX (no pitch information to reuse)
+ - TCX-40 is not allowed in the mode repetition to keep the logic simple
+ */
+ switch (last_lpd_mode) {
+ case 0:
+ mod[0] = mod[1] = mod[2] = mod[3] = 0; /* -> ACELP concealment */
+ break;
+ case 3:
+ mod[0] = mod[1] = mod[2] = mod[3] = 3; /* -> TCX FD concealment */
+ break;
+ case 2:
+ mod[0] = mod[1] = mod[2] = mod[3] = 2; /* -> TCX FD concealment */
+ break;
+ case 1:
+ default:
+ mod[0] = mod[1] = mod[2] = mod[3] = 4; /* -> TCX TD concealment */
+ break;
+ }
+
+ /* LPC extrapolation */
+ CLpc_Conceal(pAacDecoderChannelInfo->data.usac.lsp_coeff,
+ pAacDecoderStaticChannelInfo->lpc4_lsf,
+ pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ /*(pAacDecoderStaticChannelInfo->numLostLpdFrames == 0) ||*/
+ (last_lpd_mode == 255));
+
+ if ((last_lpd_mode > 0) && (last_lpd_mode < 255)) {
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ } /* case last_lpd_mode was ACELP is handled by CLpd_TcxDecode() */
+ /* case last_lpd_mode was Time domain TCX concealment is handled after this
+ * "if (!frameOk)"-block */
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ while (k < nbDiv) {
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k] = old_tcx_gain;
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] = old_tcx_gain_e;
+
+ /* restore stability value from last frame */
+ pAacDecoderChannelInfo->data.usac.aStability[k] = old_stab;
+
+ /* Increase k to next frame */
+ k += ((mod[k] & 0x3) == 0) ? 1 : (1 << ((mod[k] & 0x3) - 1));
+
+ nLostSf++;
+ }
+ } else {
+ if ((pAacDecoderStaticChannelInfo->last_lpd_mode == 4) && (mod[0] > 0)) {
+ /* Copy old LPC4 LP domain coefficients to LPC0 LP domain buffer (to avoid
+ * converting LSP coefficients again). */
+ FDKmemcpy(pAacDecoderChannelInfo->data.usac.lp_coeff[0],
+ pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0] =
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0];
+ }
+ }
+
+ Acelp_PreProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth, pitch,
+ pAacDecoderStaticChannelInfo->old_T_pf, pit_gain,
+ pAacDecoderStaticChannelInfo->old_gain_pf, samplingRate,
+ &i_offset, lFrame, synSfd, nbSubfrSuperfr);
+
+ /* k is the frame index. If a frame is of size 40MS or 80MS,
+ this frame index is incremented 2 or 4 instead of 1 respectively. */
+ k = 0;
+ last_k = -1; /* mark invalid */
+ last_lpd_mode = pAacDecoderStaticChannelInfo->last_lpd_mode;
+ last_last_lpd_mode = pAacDecoderStaticChannelInfo->last_last_lpd_mode;
+ last_lpc_lost = pAacDecoderStaticChannelInfo->last_lpc_lost | last_frame_lost;
+
+ /* This buffer must be avalable for the case of FD->ACELP transition. The
+ beginning of the buffer is used after the BPF to overwrite the output signal.
+ Only the FAC area must be affected by the BPF */
+
+ while (k < nbDiv) {
+ if (frameOk == 0) {
+ pAacDecoderStaticChannelInfo->numLostLpdFrames++;
+ } else {
+ last_frame_lost |=
+ (pAacDecoderStaticChannelInfo->numLostLpdFrames > 0) ? 1 : 0;
+ pAacDecoderStaticChannelInfo->numLostLpdFrames = 0;
+ }
+ if (mod[k] == 0 || mod[k] == 4) {
+ /* ACELP or TCX time domain concealment */
+ FIXP_DBL *acelp_out;
+
+ /* FAC management */
+ if ((last_lpd_mode != 0) && (last_lpd_mode != 4)) /* TCX TD concealment */
+ {
+ FIXP_DBL *pFacData = NULL;
+
+ if (frameOk && !last_frame_lost) {
+ pFacData = pAacDecoderChannelInfo->data.usac.fac_data[k];
+ }
+
+ nrSamples += CLpd_FAC_Mdct2Acelp(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples, pFacData,
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
+ lFrame - nrSamples,
+ CLpd_FAC_getLength(
+ (pAacDecoderStaticChannelInfo->last_core_mode != FD_SHORT) ||
+ (k > 0),
+ lFac),
+ (pAacDecoderStaticChannelInfo->last_core_mode != LPD) && (k == 0),
+ 0);
+
+ FDKmemcpy(
+ synth + nrSamples, pAacDecoderStaticChannelInfo->IMdct.overlap.time,
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset * sizeof(FIXP_DBL));
+ {
+ FIXP_LPC *lp_prev =
+ pAacDecoderChannelInfo->data.usac
+ .lp_coeff[0]; /* init value does not real matter */
+ INT lp_prev_exp = pAacDecoderChannelInfo->data.usac.lp_coeff_exp[0];
+
+ if (last_lpd_mode != 255) { /* last mode was tcx */
+ last_k = k - (1 << (last_lpd_mode - 1));
+ if (last_k < 0) {
+ lp_prev = pAacDecoderStaticChannelInfo->lp_coeff_old[1];
+ lp_prev_exp = pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1];
+ } else {
+ lp_prev = pAacDecoderChannelInfo->data.usac.lp_coeff[last_k];
+ lp_prev_exp =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
+ }
+ }
+
+ CLpd_AcelpPrepareInternalMem(
+ synth + aacDelay + k * lDiv, last_lpd_mode,
+ (last_last_lpd_mode == 4) ? 0 : last_last_lpd_mode,
+ pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k], lp_prev,
+ lp_prev_exp, &pAacDecoderStaticChannelInfo->acelp, lFrame,
+ (last_frame_lost && k < 2), mod[k]);
+ }
+ } else {
+ if (k == 0 && pAacDecoderStaticChannelInfo->IMdct.ov_offset !=
+ lFrame / facFB / 2) {
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset = lFrame / facFB / 2;
+ }
+ nrSamples += imdct_drain(&pAacDecoderStaticChannelInfo->IMdct,
+ synth + nrSamples, lFrame / facFB - nrSamples);
+ }
+
+ if (nrSamples >= lFrame / facFB) {
+ /* Write ACELP time domain samples into IMDCT overlap buffer at
+ * pAacDecoderStaticChannelInfo->IMdct.overlap.time +
+ * pAacDecoderStaticChannelInfo->IMdct.ov_offset
+ */
+ acelp_out = pAacDecoderStaticChannelInfo->IMdct.overlap.time +
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset;
+
+ /* Account ACELP time domain output samples to overlap buffer */
+ pAacDecoderStaticChannelInfo->IMdct.ov_offset += lDiv;
+ } else {
+ /* Write ACELP time domain samples into output buffer at pTimeData +
+ * nrSamples */
+ acelp_out = synth + nrSamples;
+
+ /* Account ACELP time domain output samples to output buffer */
+ nrSamples += lDiv;
+ }
+
+ if (mod[k] == 4) {
+ pAacDecoderStaticChannelInfo->acelp.wsyn_rms = scaleValue(
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ fixMin(0,
+ pAacDecoderChannelInfo->data.usac.tcx_gain_e[k] - SF_EXC));
+ CLpd_TcxTDConceal(&pAacDecoderStaticChannelInfo->acelp,
+ &pAacDecoderStaticChannelInfo->last_tcx_pitch,
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
+ pAacDecoderChannelInfo->data.usac.aStability[k],
+ pAacDecoderStaticChannelInfo->numLostLpdFrames,
+ acelp_out, lFrame,
+ pAacDecoderStaticChannelInfo->last_tcx_noise_factor);
+
+ } else {
+ FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[k] >=
+ (FIXP_SGL)0);
+ CLpd_AcelpDecode(&pAacDecoderStaticChannelInfo->acelp, i_offset,
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lsp_coeff[k + 1],
+ pAacDecoderChannelInfo->data.usac.aStability[k],
+ &pAacDecoderChannelInfo->data.usac.acelp[k],
+ pAacDecoderStaticChannelInfo->numLostLpdFrames,
+ last_lpc_lost, k, acelp_out,
+ &pitch[(k * nbSubfr) + synSfd],
+ &pit_gain[(k * nbSubfr) + synSfd], lFrame);
+ }
+
+ if (mod[k] != 4) {
+ if (last_lpd_mode != 0 &&
+ pAacDecoderChannelInfo->data.usac
+ .bpf_control_info) { /* FD/TCX -> ACELP transition */
+ /* bass post-filter past FAC area (past two (one for FD short)
+ * subframes) */
+ int currentSf = synSfd + k * nbSubfr;
+
+ if ((k > 0) || (pAacDecoderStaticChannelInfo->last_core_mode !=
+ FD_SHORT)) { /* TCX or FD long -> ACELP */
+ pitch[currentSf - 2] = pitch[currentSf - 1] = pitch[currentSf];
+ pit_gain[currentSf - 2] = pit_gain[currentSf - 1] =
+ pit_gain[currentSf];
+ } else { /* FD short -> ACELP */
+ pitch[currentSf - 1] = pitch[currentSf];
+ pit_gain[currentSf - 1] = pit_gain[currentSf];
+ }
+ }
+ }
+ } else { /* TCX */
+ int lg = lg_table[mod[k]];
+ int isFullBandLpd = 0;
+
+ /* FAC management */
+ if ((last_lpd_mode == 0) || (last_lpd_mode == 4)) /* TCX TD concealment */
+ {
+ C_AALLOC_SCRATCH_START(fac_buf, FIXP_DBL, 1024 / 8);
+
+ /* pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL means no FAC
+ * data available. */
+ if (last_frame_lost == 1 ||
+ pAacDecoderChannelInfo->data.usac.fac_data[k] == NULL) {
+ FDKmemclear(fac_buf, 1024 / 8 * sizeof(FIXP_DBL));
+ pAacDecoderChannelInfo->data.usac.fac_data[k] = fac_buf;
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k] = 0;
+ }
+
+ nrSamples += CLpd_FAC_Acelp2Mdct(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ pAacDecoderChannelInfo->specScale + k, 1,
+ pAacDecoderChannelInfo->data.usac.fac_data[k],
+ pAacDecoderChannelInfo->data.usac.fac_data_e[k],
+ pAacDecoderChannelInfo->granuleLength /* == fac_length */,
+ lFrame - nrSamples, lg,
+ FDKgetWindowSlope(lDiv,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ lDiv, pAacDecoderChannelInfo->data.usac.lp_coeff[k],
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[k],
+ &pAacDecoderStaticChannelInfo->acelp,
+ pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ (last_frame_lost || !frameOk), 0 /* is not FD FAC */
+ ,
+ last_lpd_mode, k,
+ pAacDecoderChannelInfo
+ ->currAliasingSymmetry /* Note: The current aliasing
+ symmetry for a TCX (i.e. LPD)
+ frame must always be 0 */
+ );
+
+ pitch[(k * nbSubfr) + synSfd + 1] = pitch[(k * nbSubfr) + synSfd] =
+ pitch[(k * nbSubfr) + synSfd - 1];
+ pit_gain[(k * nbSubfr) + synSfd + 1] =
+ pit_gain[(k * nbSubfr) + synSfd] =
+ pit_gain[(k * nbSubfr) + synSfd - 1];
+
+ C_AALLOC_SCRATCH_END(fac_buf, FIXP_DBL, 1024 / 8);
+ } else {
+ int tl = lg;
+ int fl = lDiv;
+ int fr = lDiv;
+
+ nrSamples += imlt_block(
+ &pAacDecoderStaticChannelInfo->IMdct, synth + nrSamples,
+ SPEC_TCX(pAacDecoderChannelInfo->pSpectralCoefficient, k,
+ pAacDecoderChannelInfo->granuleLength, isFullBandLpd),
+ pAacDecoderChannelInfo->specScale + k, 1, lFrame - nrSamples, tl,
+ FDKgetWindowSlope(fl,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fl,
+ FDKgetWindowSlope(fr,
+ GetWindowShape(&pAacDecoderChannelInfo->icsInfo)),
+ fr, pAacDecoderChannelInfo->data.usac.tcx_gain[k],
+ pAacDecoderChannelInfo->currAliasingSymmetry
+ ? MLT_FLAG_CURR_ALIAS_SYMMETRY
+ : 0);
+ }
+ }
+ /* remember previous mode */
+ last_last_lpd_mode = last_lpd_mode;
+ last_lpd_mode = mod[k];
+ last_lpc_lost = (frameOk == 0) ? 1 : 0;
+
+ /* Increase k to next frame */
+ last_k = k;
+ k += ((mod[k] & 0x3) == 0) ? 1 : (1 << (mod[k] - 1));
+ }
+
+ if (frameOk) {
+ /* assume data was ok => store for concealment */
+ FDK_ASSERT(pAacDecoderChannelInfo->data.usac.aStability[last_k] >=
+ (FIXP_SGL)0);
+ pAacDecoderStaticChannelInfo->oldStability =
+ pAacDecoderChannelInfo->data.usac.aStability[last_k];
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lsf_adaptive_mean,
+ pAacDecoderChannelInfo->data.usac.lsf_adaptive_mean_cand,
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ }
+
+ /* store past lp coeffs for next superframe (they are only valid and needed if
+ * last_lpd_mode was tcx) */
+ if (last_lpd_mode > 0) {
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[0],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[nbDiv],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[0] =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[nbDiv];
+ FDKmemcpy(pAacDecoderStaticChannelInfo->lp_coeff_old[1],
+ pAacDecoderChannelInfo->data.usac.lp_coeff[last_k],
+ M_LP_FILTER_ORDER * sizeof(FIXP_LPC));
+ pAacDecoderStaticChannelInfo->lp_coeff_old_exp[1] =
+ pAacDecoderChannelInfo->data.usac.lp_coeff_exp[last_k];
+ }
+
+ FDK_ASSERT(nrSamples == lFrame);
+
+ /* check whether usage of bass postfilter was de-activated in the bitstream;
+ if yes, set pitch gain to 0 */
+ if (!(pAacDecoderChannelInfo->data.usac.bpf_control_info)) {
+ if (mod[0] != 0 && (pAacDecoderStaticChannelInfo->old_bpf_control_info)) {
+ for (int i = 2; i < nbSubfrSuperfr; i++)
+ pit_gain[synSfd + i] = (FIXP_DBL)0;
+ } else {
+ for (int i = 0; i < nbSubfrSuperfr; i++)
+ pit_gain[synSfd + i] = (FIXP_DBL)0;
+ }
+ }
+
+ /* for bass postfilter */
+ for (int n = 0; n < synSfd; n++) {
+ pAacDecoderStaticChannelInfo->old_T_pf[n] = pitch[nbSubfrSuperfr + n];
+ pAacDecoderStaticChannelInfo->old_gain_pf[n] = pit_gain[nbSubfrSuperfr + n];
+ }
+
+ pAacDecoderStaticChannelInfo->old_bpf_control_info =
+ pAacDecoderChannelInfo->data.usac.bpf_control_info;
+
+ {
+ INT lookahead = -BPF_DELAY;
+ int copySamp = (mod[nbDiv - 1] == 0) ? (aacDelay) : (aacDelay - lFac);
+
+ /* Copy enough time domain samples from MDCT to synthesis buffer as needed
+ * by the bass postfilter */
+
+ lookahead += imdct_copy_ov_and_nr(&pAacDecoderStaticChannelInfo->IMdct,
+ synth + nrSamples, copySamp);
+
+ FDK_ASSERT(lookahead == copySamp - BPF_DELAY);
+
+ FIXP_DBL *p2_synth = synth + BPF_DELAY;
+
+ /* recalculate pitch gain to allow postfilering on FAC area */
+ for (int i = 0; i < nbSubfrSuperfr; i++) {
+ int T = pitch[i];
+ FIXP_DBL gain = pit_gain[i];
+
+ if (gain > (FIXP_DBL)0) {
+ gain = get_gain(&p2_synth[i * L_SUBFR], &p2_synth[(i * L_SUBFR) - T],
+ L_SUBFR);
+ pit_gain[i] = gain;
+ }
+ }
+
+ {
+ bass_pf_1sf_delay(p2_synth, pitch, pit_gain, lFrame, lFrame / facFB,
+ mod[nbDiv - 1] ? (SynDelay - (lDiv / 2)) : SynDelay,
+ pTimeData, pAacDecoderStaticChannelInfo->mem_bpf);
+ }
+ }
+
+ Acelp_PostProcessing(synth_buf, pAacDecoderStaticChannelInfo->old_synth,
+ pitch, pAacDecoderStaticChannelInfo->old_T_pf, lFrame,
+ synSfd, nbSubfrSuperfr);
+
+ /* Store last mode for next super frame */
+ { pAacDecoderStaticChannelInfo->last_core_mode = LPD; }
+ pAacDecoderStaticChannelInfo->last_lpd_mode = last_lpd_mode;
+ pAacDecoderStaticChannelInfo->last_last_lpd_mode = last_last_lpd_mode;
+ pAacDecoderStaticChannelInfo->last_lpc_lost = last_lpc_lost;
+
+ return error;
+}
diff --git a/fdk-aac/libAACdec/src/usacdec_lpd.h b/fdk-aac/libAACdec/src/usacdec_lpd.h
new file mode 100644
index 0000000..3e7938d
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_lpd.h
@@ -0,0 +1,198 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): Manuel Jander
+
+ Description: USAC Linear Prediction Domain coding
+
+*******************************************************************************/
+
+#ifndef USACDEC_LPD_H
+#define USACDEC_LPD_H
+
+#include "channelinfo.h"
+
+#define OPTIMIZE_AVG_PERFORMANCE
+
+/**
+ * \brief read a lpd_channel_stream.
+ * \param hBs a bit stream handle, where the lpd_channel_stream is located.
+ * \param pAacDecoderChannelInfo the channel context structure for storing read
+ * data.
+ * \param flags bit stream syntax flags.
+ * \return AAC_DECODER_ERROR error code.
+ */
+AAC_DECODER_ERROR CLpdChannelStream_Read(
+ HANDLE_FDK_BITSTREAM hBs, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ const SamplingRateInfo *pSamplingRateInfo, UINT flags);
+
+/**
+ * \brief decode one lpd_channel_stream and render the audio output.
+ * \param pAacDecoderChannelInfo struct holding the channel information to be
+ * rendered.
+ * \param pAacDecoderStaticChannelInfo struct holding the persistent channel
+ * information to be rendered.
+ * \param pSamplingRateInfo holds the sampling rate information
+ * \param elFlags holds the internal decoder flags
+ */
+void CLpdChannelStream_Decode(
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo,
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, UINT flags);
+
+/**
+ * \brief generate time domain output signal for LPD channel streams
+ * \param pAacDecoderStaticChannelInfo
+ * \param pAacDecoderChannelInfo
+ * \param pTimeData pointer to output buffer
+ * \param samplesPerFrame amount of output samples
+ * \param pSamplingRateInfo holds the sampling rate information
+ * \param pWorkBuffer1 pointer to work buffer for temporal data
+ */
+AAC_DECODER_ERROR CLpd_RenderTimeSignal(
+ CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo,
+ CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM *pTimeData,
+ INT samplesPerFrame, SamplingRateInfo *pSamplingRateInfo, UINT frameOk,
+ UINT flags, UINT strmFlags);
+
+static inline INT CLpd_FAC_getLength(int fNotShortBlock, int fac_length_long) {
+ if (fNotShortBlock) {
+ return (fac_length_long);
+ } else {
+ return fac_length_long / 2;
+ }
+}
+
+void filtLP(const FIXP_DBL *syn, FIXP_PCM *syn_out, FIXP_DBL *noise,
+ const FIXP_SGL *filt, INT stop, int len);
+
+/**
+ * \brief perform a low-frequency pitch enhancement on time domain signal
+ * \param[in] syn pointer to time domain input signal
+ * \param[in] synFB pointer to time domain input signal
+ * \param[in] upsampling factor
+ * \param[in] T_sf array with past decoded pitch period values for each subframe
+ * \param[in] non_zero_gain_flags indicates whether pitch gains of past
+ * subframes are zero or not, msb -> [1 BPF_DELAY subfr][7 SYN_DELAY subfr][16
+ * new subfr] <- lsb
+ * \param[in] l_frame length of filtering, must be multiple of L_SUBFR
+ * \param[in] l_next length of allowed look ahead on syn[i], i < l_frame+l_next
+ * \param[out] synth_out pointer to time domain output signal
+ * \param[in,out] mem_bpf pointer to filter memory (L_FILT+L_SUBFR)
+ */
+
+void bass_pf_1sf_delay(FIXP_DBL syn[], const INT T_sf[], FIXP_DBL *pit_gain,
+ const int frame_length, const INT l_frame,
+ const INT l_next, FIXP_PCM *synth_out,
+ FIXP_DBL mem_bpf[]);
+
+/**
+ * \brief random sign generator for FD and TCX noise filling
+ * \param[in,out] seed pointer to random seed
+ * \return if return value is zero use positive sign
+ * \Note: This code is also implemented as a copy in block.cpp, grep for
+ * "UsacRandomSign"
+ */
+FDK_INLINE
+int UsacRandomSign(ULONG *seed) {
+ *seed = (ULONG)((UINT64)(*seed) * 69069 + 5);
+
+ return (int)((*seed) & 0x10000);
+}
+
+void CFdp_Reset(CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo);
+
+#endif /* USACDEC_LPD_H */
diff --git a/fdk-aac/libAACdec/src/usacdec_rom.cpp b/fdk-aac/libAACdec/src/usacdec_rom.cpp
new file mode 100644
index 0000000..ca3009e
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_rom.cpp
@@ -0,0 +1,1504 @@
+/* -----------------------------------------------------------------------------
+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 decoder library ******************************
+
+ Author(s): M. Jander
+
+ Description:
+
+*******************************************************************************/
+
+#include "usacdec_rom.h"
+
+#define NB_SPHERE 32
+#define NB_LEADER 37
+#define NB_LDSIGN 226
+#define NB_LDQ3 9
+#define NB_LDQ4 28
+
+/* For bass post filter */
+#define FL2FXCONST_SGL_FILT(a) FL2FXCONST_SGL(a*(1 << SF_FILT_LP))
+#define SF_FILT_LP 1
+
+/* table of factorial */
+const UINT fdk_dec_tab_factorial[8] = {5040, 720, 120, 24, 6, 2, 1, 1};
+
+/* Da - Absolute leaders */
+const UCHAR fdk_dec_Da[NB_LEADER][8] = {
+ {1, 1, 1, 1, 1, 1, 1, 1}, {2, 2, 0, 0, 0, 0, 0, 0},
+ {2, 2, 2, 2, 0, 0, 0, 0}, {3, 1, 1, 1, 1, 1, 1, 1},
+ {4, 0, 0, 0, 0, 0, 0, 0}, {2, 2, 2, 2, 2, 2, 0, 0},
+ {3, 3, 1, 1, 1, 1, 1, 1}, {4, 2, 2, 0, 0, 0, 0, 0},
+ {2, 2, 2, 2, 2, 2, 2, 2}, {3, 3, 3, 1, 1, 1, 1, 1},
+ {4, 2, 2, 2, 2, 0, 0, 0}, {4, 4, 0, 0, 0, 0, 0, 0},
+ {5, 1, 1, 1, 1, 1, 1, 1}, {3, 3, 3, 3, 1, 1, 1, 1},
+ {4, 2, 2, 2, 2, 2, 2, 0}, {4, 4, 2, 2, 0, 0, 0, 0},
+ {5, 3, 1, 1, 1, 1, 1, 1}, {6, 2, 0, 0, 0, 0, 0, 0},
+ {4, 4, 4, 0, 0, 0, 0, 0}, {6, 2, 2, 2, 0, 0, 0, 0},
+ {6, 4, 2, 0, 0, 0, 0, 0}, {7, 1, 1, 1, 1, 1, 1, 1},
+ {8, 0, 0, 0, 0, 0, 0, 0}, {6, 6, 0, 0, 0, 0, 0, 0},
+ {8, 2, 2, 0, 0, 0, 0, 0}, {8, 4, 0, 0, 0, 0, 0, 0},
+ {9, 1, 1, 1, 1, 1, 1, 1}, {10, 2, 0, 0, 0, 0, 0, 0},
+ {8, 8, 0, 0, 0, 0, 0, 0}, {10, 6, 0, 0, 0, 0, 0, 0},
+ {12, 0, 0, 0, 0, 0, 0, 0}, {12, 4, 0, 0, 0, 0, 0, 0},
+ {10, 10, 0, 0, 0, 0, 0, 0}, {14, 2, 0, 0, 0, 0, 0, 0},
+ {12, 8, 0, 0, 0, 0, 0, 0}, {16, 0, 0, 0, 0, 0, 0, 0},
+ {20, 0, 0, 0, 0, 0, 0, 0}};
+
+/* Ds - Sign codes of all signed leaders */
+const UCHAR fdk_dec_Ds[NB_LDSIGN] = {
+ 0, 3, 15, 63, 255, 0, 64, 192, 0, 16, 48, 112, 240, 1, 7,
+ 31, 127, 128, 131, 143, 191, 0, 128, 0, 4, 12, 28, 60, 124, 252,
+ 0, 3, 15, 63, 65, 71, 95, 192, 195, 207, 255, 0, 32, 96, 128,
+ 160, 224, 0, 1, 3, 7, 15, 31, 63, 127, 255, 1, 7, 31, 32,
+ 35, 47, 97, 103, 127, 224, 227, 239, 0, 8, 24, 56, 120, 128, 136,
+ 152, 184, 248, 0, 64, 192, 0, 3, 15, 63, 129, 135, 159, 255, 0,
+ 3, 15, 17, 23, 48, 51, 63, 113, 119, 240, 243, 255, 0, 2, 6,
+ 14, 30, 62, 126, 128, 130, 134, 142, 158, 190, 254, 0, 16, 48, 64,
+ 80, 112, 192, 208, 240, 1, 7, 31, 64, 67, 79, 127, 128, 131, 143,
+ 191, 193, 199, 223, 0, 64, 128, 192, 0, 32, 96, 224, 0, 16, 48,
+ 112, 128, 144, 176, 240, 0, 32, 64, 96, 128, 160, 192, 224, 1, 7,
+ 31, 127, 128, 131, 143, 191, 0, 128, 0, 64, 192, 0, 32, 96, 128,
+ 160, 224, 0, 64, 128, 192, 0, 3, 15, 63, 129, 135, 159, 255, 0,
+ 64, 128, 192, 0, 64, 192, 0, 64, 128, 192, 0, 128, 0, 64, 128,
+ 192, 0, 64, 192, 0, 64, 128, 192, 0, 64, 128, 192, 0, 128, 0,
+ 128};
+
+/* Ns - Number of signed leader associated to a given absolute leader */
+const UCHAR fdk_dec_Ns[NB_LEADER] = {
+ 5, 3, 5, 8, 2, 7, 11, 6, 9, 12, 10, 3, 8, 13, 14, 9, 14, 4, 4,
+ 8, 8, 8, 2, 3, 6, 4, 8, 4, 3, 4, 2, 4, 3, 4, 4, 2, 2};
+
+/* Ia - Position of the first signed leader associated to an absolute leader */
+const UCHAR fdk_dec_Ia[NB_LEADER] = {
+ 0, 5, 8, 13, 21, 23, 30, 41, 47, 56, 68, 78, 81,
+ 89, 102, 116, 125, 139, 143, 147, 155, 163, 171, 173, 176, 182,
+ 186, 194, 198, 201, 205, 207, 211, 214, 218, 222, 224};
+
+/* Is - Cardinalite offset of signed leaders */
+const USHORT fdk_dec_Is[NB_LDSIGN] = {
+ 0, 1, 29, 99, 127, 128, 156, 212, 256, 326, 606,
+ 1026, 1306, 1376, 1432, 1712, 1880, 1888, 1896, 2064, 2344, 240,
+ 248, 0, 28, 196, 616, 1176, 1596, 1764, 1792, 1820, 2240,
+ 2660, 2688, 3024, 4144, 4480, 4508, 4928, 5348, 2400, 2568, 2904,
+ 3072, 3240, 3576, 5376, 5377, 5385, 5413, 5469, 5539, 5595, 5623,
+ 5631, 5632, 5912, 6472, 6528, 6696, 8376, 9216, 10056, 11736, 11904,
+ 11960, 12520, 12800, 13080, 14200, 15880, 17000, 17280, 17560, 18680, 20360,
+ 21480, 3744, 3772, 3828, 21760, 21768, 21936, 22216, 22272, 22328, 22608,
+ 22776, 22784, 22854, 23274, 23344, 24464, 25584, 26004, 28524, 28944, 30064,
+ 31184, 31254, 31674, 31744, 31800, 32136, 32976, 34096, 34936, 35272, 35328,
+ 35384, 35720, 36560, 37680, 38520, 38856, 38912, 39332, 40172, 40592, 41432,
+ 43112, 43952, 44372, 45212, 45632, 45968, 47088, 47424, 47480, 48320, 49160,
+ 49216, 49272, 50112, 50952, 51008, 51344, 52464, 3856, 3912, 3968, 4024,
+ 52800, 52856, 53024, 53192, 53248, 53528, 54368, 55208, 55488, 55768, 56608,
+ 57448, 57728, 58064, 58400, 58736, 59072, 59408, 59744, 60080, 60416, 60472,
+ 60752, 60920, 60928, 60936, 61104, 61384, 4080, 4088, 61440, 61468, 61524,
+ 61552, 61720, 62056, 62224, 62392, 62728, 62896, 62952, 63008, 63064, 63120,
+ 63128, 63296, 63576, 63632, 63688, 63968, 64136, 64144, 64200, 64256, 64312,
+ 64368, 64396, 64452, 64480, 64536, 64592, 64648, 64704, 64712, 64720, 64776,
+ 64832, 64888, 64944, 64972, 65028, 65056, 65112, 65168, 65224, 65280, 65336,
+ 65392, 65448, 65504, 65512, 65520, 65528};
+
+/* A3 - Number of the absolute leaders in codebooks Q2 and Q3 */
+const UCHAR fdk_dec_A3[NB_LDQ3] = {0, 1, 4, 2, 3, 7, 11, 17, 22};
+
+/* A4 - Number of the absolute leaders in codebook Q4 */
+const UCHAR fdk_dec_A4[NB_LDQ4] = {5, 6, 8, 9, 10, 12, 13, 14, 15, 16,
+ 18, 19, 20, 21, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36};
+
+/* I3 - Cardinality offsets for absolute leaders in Q3 */
+const USHORT fdk_dec_I3[NB_LDQ3] = {0, 128, 240, 256, 1376,
+ 2400, 3744, 3856, 4080};
+
+/* I4 - Cardinality offset for absolute leaders in Q4 */
+const USHORT fdk_dec_I4[NB_LDQ4] = {
+ 0, 1792, 5376, 5632, 12800, 21760, 22784, 31744, 38912, 45632,
+ 52800, 53248, 57728, 60416, 61440, 61552, 62896, 63120, 64144, 64368,
+ 64480, 64704, 64720, 64944, 65056, 65280, 65504, 65520};
+
+/* Initial ISF memory for concealment case */
+#define LSFI(x) ((x) << (FRACT_BITS - LSF_SCALE - 1))
+
+const FIXP_LPC fdk_dec_lsf_init[16] = {1506, 3012, 4518, 6024, 7529, 9035,
+ 10541, 12047, 13553, 15059, 16565, 18071,
+ 19576, 21082, 22588, 24094};
+
+/* dico_lsf_abs_8b is scaled by 1/(1<<13) */
+#define DICO(x) FX_DBL2FXCONST_LPC(x >> (LSF_SCALE - 13))
+
+const FIXP_LPC fdk_dec_dico_lsf_abs_8b[] = {
+ DICO(0x05e57fe8), DICO(0x0ac00810), DICO(0x11ed8500), DICO(0x16d42ce0),
+ DICO(0x1beb1e20), DICO(0x217eaf40), DICO(0x2768c740), DICO(0x2d26f600),
+ DICO(0x32fe68c0), DICO(0x38b1d980), DICO(0x3e95bd80), DICO(0x446dab00),
+ DICO(0x4abfd280), DICO(0x5094b380), DICO(0x56ccb800), DICO(0x5c9aba00),
+ DICO(0x09660ca0), DICO(0x10ab4c00), DICO(0x15a16f20), DICO(0x19d3c780),
+ DICO(0x1ee99060), DICO(0x241d1200), DICO(0x29c83700), DICO(0x2f098f00),
+ DICO(0x34803fc0), DICO(0x3a37bc00), DICO(0x3ff55580), DICO(0x45da9280),
+ DICO(0x4bec6700), DICO(0x5169e300), DICO(0x57797c80), DICO(0x5d09ae80),
+ DICO(0x08a203b0), DICO(0x0d6ed1a0), DICO(0x152ccf20), DICO(0x19639dc0),
+ DICO(0x1d7e3e60), DICO(0x21f4a7c0), DICO(0x27b2f8c0), DICO(0x2dbb4480),
+ DICO(0x33ecde80), DICO(0x3982e100), DICO(0x3ea16100), DICO(0x43ab6080),
+ DICO(0x49534a80), DICO(0x4ea7e100), DICO(0x550d6300), DICO(0x5bcdcc80),
+ DICO(0x072dd048), DICO(0x0c654690), DICO(0x1436e940), DICO(0x19459680),
+ DICO(0x1e0041c0), DICO(0x2240dc80), DICO(0x26de4040), DICO(0x2b509b00),
+ DICO(0x309d8780), DICO(0x36151180), DICO(0x3c6c1200), DICO(0x42df6b80),
+ DICO(0x4a144400), DICO(0x50541280), DICO(0x56c34b80), DICO(0x5cb6c600),
+ DICO(0x051fef00), DICO(0x06b9fb48), DICO(0x0b4f9cc0), DICO(0x17e27800),
+ DICO(0x1b8c7340), DICO(0x1f772ca0), DICO(0x2478dc80), DICO(0x28242240),
+ DICO(0x2f27c640), DICO(0x33b03e80), DICO(0x381f20c0), DICO(0x3c662c00),
+ DICO(0x49565080), DICO(0x529b0f00), DICO(0x583ed080), DICO(0x5d8cec00),
+ DICO(0x071c4d18), DICO(0x097853b0), DICO(0x0f0f0690), DICO(0x157bf980),
+ DICO(0x1801f580), DICO(0x1deb0c20), DICO(0x2523da40), DICO(0x28534600),
+ DICO(0x2eb499c0), DICO(0x32eb5ac0), DICO(0x36749580), DICO(0x3a748200),
+ DICO(0x4325f700), DICO(0x515d8300), DICO(0x58a18700), DICO(0x5d722100),
+ DICO(0x06cbcd88), DICO(0x08bb6740), DICO(0x0dead310), DICO(0x152f0cc0),
+ DICO(0x18427640), DICO(0x1d9f2f20), DICO(0x22ba3b40), DICO(0x271a6e80),
+ DICO(0x2c677ec0), DICO(0x31061b00), DICO(0x349eef40), DICO(0x3c531b80),
+ DICO(0x4aed0580), DICO(0x4f8bbf80), DICO(0x54b74980), DICO(0x5bc9b700),
+ DICO(0x046410c8), DICO(0x06522ab0), DICO(0x0b6528c0), DICO(0x0f94bd90),
+ DICO(0x1a8f8b80), DICO(0x1ea57820), DICO(0x233ee180), DICO(0x27b3acc0),
+ DICO(0x2bd1d240), DICO(0x2fc4bcc0), DICO(0x3a98ea40), DICO(0x43d3f500),
+ DICO(0x49b37580), DICO(0x4e2afd00), DICO(0x55953300), DICO(0x5d36f600),
+ DICO(0x05d0f6c8), DICO(0x07e56d90), DICO(0x0be98080), DICO(0x0f956f30),
+ DICO(0x1259b3c0), DICO(0x1f08b240), DICO(0x25008c00), DICO(0x2900b180),
+ DICO(0x31ea6f00), DICO(0x352d1e00), DICO(0x3c970c80), DICO(0x45271200),
+ DICO(0x4b632280), DICO(0x5098a480), DICO(0x5672fc80), DICO(0x5c163180),
+ DICO(0x05bd81a0), DICO(0x07d4b8f0), DICO(0x0ce224b0), DICO(0x110abe20),
+ DICO(0x13dfeac0), DICO(0x17dedae0), DICO(0x2535c0c0), DICO(0x2a19da80),
+ DICO(0x2e5224c0), DICO(0x38ddeec0), DICO(0x3da99d80), DICO(0x42799100),
+ DICO(0x48973b00), DICO(0x4ea62880), DICO(0x53f77e80), DICO(0x5bd9c100),
+ DICO(0x0395cd50), DICO(0x058244b8), DICO(0x0af45520), DICO(0x1329cea0),
+ DICO(0x1a3970c0), DICO(0x1d9f2e00), DICO(0x21704400), DICO(0x277a34c0),
+ DICO(0x30215b40), DICO(0x33875040), DICO(0x3c159840), DICO(0x452fea00),
+ DICO(0x4981d200), DICO(0x4e15a980), DICO(0x54e84780), DICO(0x5c79ea00),
+ DICO(0x05413b98), DICO(0x08132a80), DICO(0x0dc7f050), DICO(0x13e25460),
+ DICO(0x1784bf80), DICO(0x1d630200), DICO(0x238bc880), DICO(0x28cc0880),
+ DICO(0x30da1a40), DICO(0x391e2200), DICO(0x415d8d00), DICO(0x48f13280),
+ DICO(0x4e300300), DICO(0x52e56580), DICO(0x5849fe80), DICO(0x5cdef400),
+ DICO(0x04a058c8), DICO(0x07569b88), DICO(0x0ef26610), DICO(0x13208140),
+ DICO(0x168c0500), DICO(0x1afec080), DICO(0x22a0abc0), DICO(0x2a057880),
+ DICO(0x2fd1c840), DICO(0x3703c680), DICO(0x3d326b80), DICO(0x43df2e80),
+ DICO(0x4a6f9000), DICO(0x50900d80), DICO(0x56c73f00), DICO(0x5cc3da80),
+ DICO(0x065c99e8), DICO(0x09060c50), DICO(0x0d1ef1c0), DICO(0x16bd9020),
+ DICO(0x1a04dae0), DICO(0x1e3c0580), DICO(0x25783700), DICO(0x29710ac0),
+ DICO(0x309cbb80), DICO(0x36c66280), DICO(0x3adb0580), DICO(0x41b37e00),
+ DICO(0x496ca700), DICO(0x4dab7600), DICO(0x52be6280), DICO(0x58fec480),
+ DICO(0x04640880), DICO(0x05a75ab8), DICO(0x0edba410), DICO(0x16e076a0),
+ DICO(0x198acec0), DICO(0x1eb5fae0), DICO(0x228c9000), DICO(0x29986c00),
+ DICO(0x2c780c80), DICO(0x38078dc0), DICO(0x3f42dc00), DICO(0x441ba900),
+ DICO(0x492f8080), DICO(0x4ed85d00), DICO(0x54605800), DICO(0x5d106a80),
+ DICO(0x045cb970), DICO(0x0627a828), DICO(0x0db35290), DICO(0x1778f780),
+ DICO(0x1a243c60), DICO(0x23c2dd40), DICO(0x27c57840), DICO(0x2f53cd80),
+ DICO(0x36f65600), DICO(0x3bc1b2c0), DICO(0x40c36500), DICO(0x46074180),
+ DICO(0x4b551b80), DICO(0x50a99700), DICO(0x569b6c80), DICO(0x5ca25780),
+ DICO(0x05ef2828), DICO(0x07d3adf8), DICO(0x0b5416d0), DICO(0x0f9adb70),
+ DICO(0x126e7360), DICO(0x1baff460), DICO(0x2b5decc0), DICO(0x31036200),
+ DICO(0x34ca7500), DICO(0x39681340), DICO(0x3da97100), DICO(0x4161ee00),
+ DICO(0x46a62e80), DICO(0x4d1b9380), DICO(0x530e0300), DICO(0x59ff0480),
+ DICO(0x04f5bc50), DICO(0x06e90d18), DICO(0x0c2af480), DICO(0x123f7400),
+ DICO(0x1530a160), DICO(0x18aa3dc0), DICO(0x1cc0a240), DICO(0x2cdb02c0),
+ DICO(0x32909a00), DICO(0x36bae640), DICO(0x3c917a80), DICO(0x40121900),
+ DICO(0x48a90d80), DICO(0x51ccc180), DICO(0x5884ea00), DICO(0x5dbc4280),
+ DICO(0x05791410), DICO(0x07b0dd80), DICO(0x0bec4190), DICO(0x13c30520),
+ DICO(0x17ac1900), DICO(0x1b6f1d00), DICO(0x26e54f40), DICO(0x2d4a8040),
+ DICO(0x311c6840), DICO(0x38ec4180), DICO(0x3f0c4340), DICO(0x427c5b00),
+ DICO(0x4886e480), DICO(0x504a0b00), DICO(0x56d48700), DICO(0x5c80f600),
+ DICO(0x04b58880), DICO(0x0743f0d8), DICO(0x0be95e20), DICO(0x0fd0d9b0),
+ DICO(0x1c2e11a0), DICO(0x2241af80), DICO(0x296e83c0), DICO(0x2f16adc0),
+ DICO(0x32cd6fc0), DICO(0x374ddec0), DICO(0x3da95f80), DICO(0x45d56c80),
+ DICO(0x4c6afa80), DICO(0x5141f380), DICO(0x5616b380), DICO(0x5c58f580),
+ DICO(0x03f4b368), DICO(0x05939890), DICO(0x09d95480), DICO(0x122cac60),
+ DICO(0x17e27e00), DICO(0x1f9dc680), DICO(0x26e26680), DICO(0x2ae64040),
+ DICO(0x2dd6cf40), DICO(0x3295c400), DICO(0x3e23b400), DICO(0x44fd0380),
+ DICO(0x4ad7a700), DICO(0x51295e80), DICO(0x594a9400), DICO(0x5e41aa00),
+ DICO(0x0424b9d8), DICO(0x05b30508), DICO(0x09380f20), DICO(0x0c9509c0),
+ DICO(0x18730860), DICO(0x219a9d40), DICO(0x24f699c0), DICO(0x289b2680),
+ DICO(0x2cb62240), DICO(0x36e88180), DICO(0x3e968800), DICO(0x48053c80),
+ DICO(0x4d6dca80), DICO(0x51d9a580), DICO(0x563e5a80), DICO(0x5c0b2b80),
+ DICO(0x03456ae8), DICO(0x04e49948), DICO(0x07dd0e88), DICO(0x0ed5cd30),
+ DICO(0x1b06e980), DICO(0x1de2b9c0), DICO(0x21160540), DICO(0x270a8240),
+ DICO(0x3352a280), DICO(0x3b8b6c00), DICO(0x40241400), DICO(0x43f60f80),
+ DICO(0x4a897900), DICO(0x51692a00), DICO(0x57449d00), DICO(0x5d497480),
+ DICO(0x04b94290), DICO(0x067e99d0), DICO(0x0ab06840), DICO(0x0e697070),
+ DICO(0x1745c460), DICO(0x22ee8040), DICO(0x2647e8c0), DICO(0x2bc2c680),
+ DICO(0x2fd57d00), DICO(0x37186680), DICO(0x3d074500), DICO(0x412b2800),
+ DICO(0x4579af00), DICO(0x4caff980), DICO(0x557add00), DICO(0x5c6ae780),
+ DICO(0x0423a090), DICO(0x05b9bca0), DICO(0x091b45d0), DICO(0x0c5b6d60),
+ DICO(0x194dd1c0), DICO(0x1fc85020), DICO(0x2486b080), DICO(0x2920af80),
+ DICO(0x2dd4f140), DICO(0x3598be40), DICO(0x3b9c1440), DICO(0x42d19280),
+ DICO(0x4a314280), DICO(0x50b00a00), DICO(0x56c55400), DICO(0x5d5ba300),
+ DICO(0x03e68b28), DICO(0x05a7b190), DICO(0x0917f000), DICO(0x0d247050),
+ DICO(0x19e637a0), DICO(0x2221a540), DICO(0x2777e540), DICO(0x2c103380),
+ DICO(0x30c2e040), DICO(0x389f1240), DICO(0x3f4a2c80), DICO(0x454a4c00),
+ DICO(0x4b0ab680), DICO(0x50cf6000), DICO(0x571c0700), DICO(0x5d2ef600),
+ DICO(0x04886f18), DICO(0x065103e8), DICO(0x0a607d40), DICO(0x0db91960),
+ DICO(0x13546f20), DICO(0x22f5e200), DICO(0x27064240), DICO(0x2e371d40),
+ DICO(0x33659240), DICO(0x38aa1c40), DICO(0x417bb280), DICO(0x47ca9480),
+ DICO(0x4dd6fb80), DICO(0x528e3480), DICO(0x57c49d80), DICO(0x5cc98100),
+ DICO(0x02db2370), DICO(0x04398848), DICO(0x07a8da38), DICO(0x10b90280),
+ DICO(0x1a2a4a20), DICO(0x20b1f640), DICO(0x277096c0), DICO(0x2dc568c0),
+ DICO(0x341b33c0), DICO(0x3a000640), DICO(0x40152880), DICO(0x45eeee00),
+ DICO(0x4c08c480), DICO(0x51bf0600), DICO(0x5799a180), DICO(0x5d23db80),
+ DICO(0x047b1498), DICO(0x06089848), DICO(0x0905af20), DICO(0x0bf13c20),
+ DICO(0x11fcf620), DICO(0x1f79cd00), DICO(0x257f6b40), DICO(0x2cfc2600),
+ DICO(0x31610040), DICO(0x35ea8280), DICO(0x3c774bc0), DICO(0x44417280),
+ DICO(0x4b432500), DICO(0x510e9480), DICO(0x56f2e480), DICO(0x5d282780),
+ DICO(0x02cfd0b0), DICO(0x042845d8), DICO(0x0a1fa610), DICO(0x15911fc0),
+ DICO(0x1bc07f00), DICO(0x2281d640), DICO(0x287abcc0), DICO(0x2ec6b400),
+ DICO(0x34a0d040), DICO(0x3aa4dcc0), DICO(0x4074d980), DICO(0x46726b80),
+ DICO(0x4c3bf900), DICO(0x52055100), DICO(0x57b20500), DICO(0x5d34da80),
+ DICO(0x04d4f768), DICO(0x06cad828), DICO(0x0b52a540), DICO(0x0ea224e0),
+ DICO(0x13c3f460), DICO(0x23808900), DICO(0x27d1cec0), DICO(0x2d6051c0),
+ DICO(0x33c5ff00), DICO(0x37ef2440), DICO(0x3d2a5300), DICO(0x43266000),
+ DICO(0x4a53a100), DICO(0x50acce80), DICO(0x57612100), DICO(0x5cdee380),
+ DICO(0x04039a88), DICO(0x0626dcb0), DICO(0x0c059620), DICO(0x12c3db20),
+ DICO(0x1bb9eb40), DICO(0x240fda00), DICO(0x2baab840), DICO(0x3177c5c0),
+ DICO(0x36cf2e40), DICO(0x3c025100), DICO(0x40bb8d00), DICO(0x45960800),
+ DICO(0x4adaca00), DICO(0x505a7300), DICO(0x566a6400), DICO(0x5c8ce000),
+ DICO(0x062891e8), DICO(0x09680810), DICO(0x0e9a11b0), DICO(0x1523e320),
+ DICO(0x1c57db00), DICO(0x21f22c80), DICO(0x28aeeb00), DICO(0x2e4fd600),
+ DICO(0x341cf000), DICO(0x3a5034c0), DICO(0x40600f80), DICO(0x461fde00),
+ DICO(0x4c368480), DICO(0x51dbbc00), DICO(0x57709780), DICO(0x5cce9880),
+ DICO(0x05d41f70), DICO(0x0a65bb30), DICO(0x132ddfa0), DICO(0x17d26820),
+ DICO(0x1e6d8380), DICO(0x24e68dc0), DICO(0x2b68c4c0), DICO(0x30fa2880),
+ DICO(0x361998c0), DICO(0x3aa1d640), DICO(0x3f942400), DICO(0x44d11680),
+ DICO(0x4ab8e580), DICO(0x50643b80), DICO(0x5697fe00), DICO(0x5cb3a780),
+ DICO(0x0707fa10), DICO(0x0cb8beb0), DICO(0x15011d20), DICO(0x1a4ad300),
+ DICO(0x20997080), DICO(0x26dbe240), DICO(0x2d907880), DICO(0x3307a3c0),
+ DICO(0x38819740), DICO(0x3d3e89c0), DICO(0x41ea2300), DICO(0x469ce200),
+ DICO(0x4be61680), DICO(0x51261b80), DICO(0x5716ef80), DICO(0x5cba2900),
+ DICO(0x084dc830), DICO(0x0f16f610), DICO(0x16ca2420), DICO(0x1bb58380),
+ DICO(0x22f00f00), DICO(0x296ba4c0), DICO(0x306d2600), DICO(0x362ca080),
+ DICO(0x3b86d280), DICO(0x3ffa96c0), DICO(0x446a5300), DICO(0x48d0fd00),
+ DICO(0x4d8a0800), DICO(0x525bf200), DICO(0x57f5aa00), DICO(0x5d569480),
+ DICO(0x08d664f0), DICO(0x110c8520), DICO(0x1865fa40), DICO(0x1efe3160),
+ DICO(0x26f38740), DICO(0x2d4608c0), DICO(0x32862500), DICO(0x374f8840),
+ DICO(0x3bfa9900), DICO(0x3ff5c8c0), DICO(0x4450c500), DICO(0x4918e680),
+ DICO(0x4e1d0f00), DICO(0x53342600), DICO(0x58a38e00), DICO(0x5dbbff00),
+ DICO(0x09143fd0), DICO(0x0f401c30), DICO(0x169c1ee0), DICO(0x1bcfb280),
+ DICO(0x2190dd00), DICO(0x27bf56c0), DICO(0x2e8e0640), DICO(0x34b67080),
+ DICO(0x3b534dc0), DICO(0x41134c00), DICO(0x467a3280), DICO(0x4bd63600),
+ DICO(0x50de8700), DICO(0x55657580), DICO(0x5a0cef00), DICO(0x5e8aa200),
+ DICO(0x06b5d860), DICO(0x0c8a5000), DICO(0x13343620), DICO(0x17a2abe0),
+ DICO(0x1caf7340), DICO(0x22a3f740), DICO(0x29059980), DICO(0x2ecff880),
+ DICO(0x34ce0f00), DICO(0x3ad32280), DICO(0x40f08d80), DICO(0x46d1d400),
+ DICO(0x4ca9df00), DICO(0x523b9580), DICO(0x57ea9b80), DICO(0x5d4a9a00),
+ DICO(0x03822fec), DICO(0x0522c670), DICO(0x099f89a0), DICO(0x12ddc9c0),
+ DICO(0x17c3d380), DICO(0x1d27ec20), DICO(0x2219e480), DICO(0x25fdf580),
+ DICO(0x329d6500), DICO(0x368ba040), DICO(0x3afedb00), DICO(0x430db980),
+ DICO(0x4a105380), DICO(0x51205080), DICO(0x5673b880), DICO(0x5ca2e500),
+ DICO(0x04e07408), DICO(0x06a13dc0), DICO(0x0b31c780), DICO(0x0e67fcd0),
+ DICO(0x13723240), DICO(0x1f87a840), DICO(0x2321ab00), DICO(0x2c604680),
+ DICO(0x310bc180), DICO(0x351eea40), DICO(0x3a2d6440), DICO(0x3e7ebac0),
+ DICO(0x4798ef80), DICO(0x50721100), DICO(0x57ff9880), DICO(0x5dc2e080),
+ DICO(0x05d626b8), DICO(0x07eaf140), DICO(0x0c5675b0), DICO(0x0eba7b00),
+ DICO(0x1a7f36c0), DICO(0x1f969200), DICO(0x244d8c00), DICO(0x29666440),
+ DICO(0x2c94b100), DICO(0x31865380), DICO(0x3713c000), DICO(0x3c228f40),
+ DICO(0x4296ed80), DICO(0x4dcbde00), DICO(0x56059a00), DICO(0x5c932d00),
+ DICO(0x07dceb20), DICO(0x0b533fe0), DICO(0x0eb18880), DICO(0x13124220),
+ DICO(0x167f74e0), DICO(0x1afbee40), DICO(0x229e2f80), DICO(0x26b05ec0),
+ DICO(0x2c7b4040), DICO(0x32806140), DICO(0x38da6540), DICO(0x3e495540),
+ DICO(0x444d3880), DICO(0x4e784400), DICO(0x5865f580), DICO(0x5e616180),
+ DICO(0x06395790), DICO(0x084b8f20), DICO(0x0d0e26a0), DICO(0x10897ac0),
+ DICO(0x14bcd080), DICO(0x1c5babe0), DICO(0x2108f9c0), DICO(0x274f8e80),
+ DICO(0x2b0ba180), DICO(0x305b8480), DICO(0x383ad300), DICO(0x3e34f440),
+ DICO(0x47f7aa00), DICO(0x4fdb5880), DICO(0x56b8c280), DICO(0x5d07d700),
+ DICO(0x051f0880), DICO(0x071b8fa8), DICO(0x0ce79c90), DICO(0x1005bd60),
+ DICO(0x14a4a080), DICO(0x183def40), DICO(0x1ee8d0a0), DICO(0x2c5b9bc0),
+ DICO(0x309f9dc0), DICO(0x35659380), DICO(0x3c0439c0), DICO(0x49603800),
+ DICO(0x5018a800), DICO(0x54862380), DICO(0x593edd80), DICO(0x5d415b80),
+ DICO(0x051c8108), DICO(0x06bd97d8), DICO(0x0b47d030), DICO(0x0d9c81a0),
+ DICO(0x178f0be0), DICO(0x1cdf7c80), DICO(0x2183db40), DICO(0x26ec7180),
+ DICO(0x2a3856c0), DICO(0x366c9b40), DICO(0x3d3611c0), DICO(0x42788100),
+ DICO(0x4981f200), DICO(0x4dd68380), DICO(0x55286a00), DICO(0x5cc72500),
+ DICO(0x06ee58c8), DICO(0x098b1310), DICO(0x0ccbd880), DICO(0x0f9d68f0),
+ DICO(0x1277ac40), DICO(0x1d71faa0), DICO(0x230d9480), DICO(0x276b8c00),
+ DICO(0x2ec77000), DICO(0x31f2a700), DICO(0x3bee0200), DICO(0x42250700),
+ DICO(0x466b7100), DICO(0x4de41980), DICO(0x56a08d80), DICO(0x5d700880),
+ DICO(0x062f1d80), DICO(0x091bcd30), DICO(0x0cd875e0), DICO(0x0fd42e60),
+ DICO(0x1322b980), DICO(0x1f11b480), DICO(0x2651e5c0), DICO(0x29f9b480),
+ DICO(0x2e238840), DICO(0x30fc58c0), DICO(0x37aa3040), DICO(0x3e9ac580),
+ DICO(0x44c6fd00), DICO(0x4eba4300), DICO(0x56fdad00), DICO(0x5d885700),
+ DICO(0x04213a78), DICO(0x05d028c0), DICO(0x09a1f9e0), DICO(0x0d28ae90),
+ DICO(0x151819a0), DICO(0x1c78c860), DICO(0x21d78f00), DICO(0x29992cc0),
+ DICO(0x2fbdc180), DICO(0x36bab700), DICO(0x3d4db1c0), DICO(0x4402a280),
+ DICO(0x4a920700), DICO(0x50988600), DICO(0x5717c100), DICO(0x5d52c200),
+ DICO(0x036af4bc), DICO(0x0514cf40), DICO(0x09ec2d30), DICO(0x113de160),
+ DICO(0x1991b700), DICO(0x20590bc0), DICO(0x23892a00), DICO(0x2654cd00),
+ DICO(0x2ff5c0c0), DICO(0x387ed380), DICO(0x3e305300), DICO(0x46137700),
+ DICO(0x4bc29100), DICO(0x4f96dd80), DICO(0x564aca00), DICO(0x5c4d9e80),
+ DICO(0x041051a0), DICO(0x0734dad8), DICO(0x1064e780), DICO(0x14d8bf00),
+ DICO(0x19727e40), DICO(0x1f7bede0), DICO(0x25b5ebc0), DICO(0x2c71fd40),
+ DICO(0x32813740), DICO(0x39340c80), DICO(0x3f974f40), DICO(0x45ca1580),
+ DICO(0x4be69f00), DICO(0x51c9c900), DICO(0x57a1ce80), DICO(0x5d0b2b00),
+ DICO(0x04b73008), DICO(0x06598b60), DICO(0x0b0aee00), DICO(0x15ac7ba0),
+ DICO(0x18b5e340), DICO(0x1f5308c0), DICO(0x23cfc4c0), DICO(0x27d3fdc0),
+ DICO(0x30138080), DICO(0x343c85c0), DICO(0x389cb540), DICO(0x42def900),
+ DICO(0x4aa6a000), DICO(0x4f719580), DICO(0x5585d080), DICO(0x5bc03f00),
+ DICO(0x05601b88), DICO(0x07616b88), DICO(0x0c22ba40), DICO(0x16bc8200),
+ DICO(0x192ebf80), DICO(0x1f71c120), DICO(0x25c59d00), DICO(0x28f76d00),
+ DICO(0x33dbdd80), DICO(0x39f40d80), DICO(0x3da0c880), DICO(0x432c1e00),
+ DICO(0x4aa19d80), DICO(0x51006f80), DICO(0x56a62e80), DICO(0x5c67d000),
+ DICO(0x053095d0), DICO(0x06c43fc8), DICO(0x0f80a460), DICO(0x139b4960),
+ DICO(0x1769ed80), DICO(0x1c828b00), DICO(0x21195980), DICO(0x26329800),
+ DICO(0x29f35900), DICO(0x2dc9df80), DICO(0x3795f0c0), DICO(0x43139b00),
+ DICO(0x4acae680), DICO(0x5048de00), DICO(0x57c11880), DICO(0x5db35900),
+ DICO(0x0466e180), DICO(0x05d31550), DICO(0x10cad200), DICO(0x168c2be0),
+ DICO(0x1a5e9580), DICO(0x1ef2d480), DICO(0x238db240), DICO(0x2920ce80),
+ DICO(0x2c80b4c0), DICO(0x30bb2700), DICO(0x38b257c0), DICO(0x46abd580),
+ DICO(0x4c30dd80), DICO(0x50e51880), DICO(0x5782ab80), DICO(0x5d23da80),
+ DICO(0x06700f78), DICO(0x085ec0a0), DICO(0x0c037280), DICO(0x16d90a60),
+ DICO(0x1bf46c00), DICO(0x1e6f4740), DICO(0x22c2c180), DICO(0x263fa2c0),
+ DICO(0x2c4a74c0), DICO(0x3642b040), DICO(0x3a476900), DICO(0x3ea12840),
+ DICO(0x46b6e880), DICO(0x4b5bad80), DICO(0x5152a500), DICO(0x5c1c6080),
+ DICO(0x041f8108), DICO(0x05ef1d98), DICO(0x0ce43300), DICO(0x11647cc0),
+ DICO(0x16e77fe0), DICO(0x1cdafc40), DICO(0x218832c0), DICO(0x26dd1b40),
+ DICO(0x2c776100), DICO(0x34f1eb80), DICO(0x3caf6100), DICO(0x45630a80),
+ DICO(0x4c0c5380), DICO(0x517ae980), DICO(0x567f4280), DICO(0x5c4bf900),
+ DICO(0x06673f18), DICO(0x091ee510), DICO(0x0d6ccb10), DICO(0x12503240),
+ DICO(0x158696e0), DICO(0x1f035420), DICO(0x24e6eac0), DICO(0x2a03bf40),
+ DICO(0x329aa000), DICO(0x375aafc0), DICO(0x3da133c0), DICO(0x45645600),
+ DICO(0x4c447c00), DICO(0x51a26b00), DICO(0x57917c00), DICO(0x5c557680),
+ DICO(0x04f84c18), DICO(0x06db4c30), DICO(0x0d53a940), DICO(0x1095cd20),
+ DICO(0x142b0b20), DICO(0x184229c0), DICO(0x20147280), DICO(0x25152740),
+ DICO(0x2db89fc0), DICO(0x35f3d200), DICO(0x400aa680), DICO(0x47a51c00),
+ DICO(0x4d9c5c00), DICO(0x525d1680), DICO(0x5832af00), DICO(0x5d27d580),
+ DICO(0x05c973d0), DICO(0x07c25810), DICO(0x0e928e50), DICO(0x12f5ad00),
+ DICO(0x16b2a800), DICO(0x1c2c9ce0), DICO(0x20b0f100), DICO(0x28be1940),
+ DICO(0x2d0f3c00), DICO(0x30a06f40), DICO(0x399e4340), DICO(0x46b48280),
+ DICO(0x4bbbc300), DICO(0x50283700), DICO(0x54a1a800), DICO(0x5ab20c80),
+ DICO(0x03df9390), DICO(0x055ff1e0), DICO(0x0bbeb640), DICO(0x17d906c0),
+ DICO(0x1ac20140), DICO(0x1fd84440), DICO(0x24502600), DICO(0x2a9fe640),
+ DICO(0x2ef79700), DICO(0x34cbed40), DICO(0x3c48cd00), DICO(0x43ccce80),
+ DICO(0x49b1d500), DICO(0x50145e00), DICO(0x56f16f80), DICO(0x5d46dd80),
+ DICO(0x04a69ef0), DICO(0x06470480), DICO(0x0defbd00), DICO(0x1590e900),
+ DICO(0x18114000), DICO(0x1bda6c60), DICO(0x1f64d160), DICO(0x28d8d640),
+ DICO(0x2d4e2880), DICO(0x34cfe380), DICO(0x3b7077c0), DICO(0x42f36a80),
+ DICO(0x49615580), DICO(0x4ff9d200), DICO(0x5657ef80), DICO(0x5cb91300),
+ DICO(0x038893dc), DICO(0x0535cdf0), DICO(0x0aabff80), DICO(0x146daaa0),
+ DICO(0x1848c700), DICO(0x1ce578c0), DICO(0x21116000), DICO(0x2b116d40),
+ DICO(0x32113500), DICO(0x3751a480), DICO(0x3e88c200), DICO(0x44cb1800),
+ DICO(0x4af1c200), DICO(0x5122b980), DICO(0x5782bc80), DICO(0x5d20be00),
+ DICO(0x03118434), DICO(0x04afe2e8), DICO(0x08f144f0), DICO(0x12c787c0),
+ DICO(0x1c32e4e0), DICO(0x1f701180), DICO(0x2362f740), DICO(0x2b995cc0),
+ DICO(0x3322c540), DICO(0x3951f200), DICO(0x3f7c2c80), DICO(0x4569c480),
+ DICO(0x4b2a6200), DICO(0x50905e80), DICO(0x56236680), DICO(0x5c32fa00),
+ DICO(0x0460c3b0), DICO(0x061e1378), DICO(0x0b07f610), DICO(0x166e0680),
+ DICO(0x18d0f020), DICO(0x21120340), DICO(0x24d4c000), DICO(0x29bafc00),
+ DICO(0x338c0740), DICO(0x36cfbc00), DICO(0x3f313900), DICO(0x47bf9c00),
+ DICO(0x4dd5d480), DICO(0x52848200), DICO(0x585add00), DICO(0x5cf7b480),
+ DICO(0x041a4bc8), DICO(0x05ca0920), DICO(0x0a3ae5b0), DICO(0x13fbb840),
+ DICO(0x1cdd3d00), DICO(0x209d5b80), DICO(0x27e78e80), DICO(0x2d1f4ec0),
+ DICO(0x32d84c80), DICO(0x3b8aa680), DICO(0x4289c180), DICO(0x46c33580),
+ DICO(0x4c23e580), DICO(0x51583180), DICO(0x56f52680), DICO(0x5c7a3d00),
+ DICO(0x03067404), DICO(0x05914038), DICO(0x10d33e60), DICO(0x17377180),
+ DICO(0x1d7f32a0), DICO(0x23848880), DICO(0x29d32200), DICO(0x2fb167c0),
+ DICO(0x356c8480), DICO(0x3b420280), DICO(0x4106d080), DICO(0x46d29280),
+ DICO(0x4c8a1200), DICO(0x52383300), DICO(0x57db8f80), DICO(0x5d61f200),
+ DICO(0x04baf368), DICO(0x06670a08), DICO(0x0e0cbd90), DICO(0x126299c0),
+ DICO(0x17ed7220), DICO(0x1e369900), DICO(0x22d7d300), DICO(0x2c0f9300),
+ DICO(0x2f5e7fc0), DICO(0x3b7c0d40), DICO(0x405aff80), DICO(0x44f2ef80),
+ DICO(0x4982b400), DICO(0x4e501380), DICO(0x539daa00), DICO(0x5c114b00),
+ DICO(0x0694c170), DICO(0x092d6890), DICO(0x0d0faee0), DICO(0x13800d00),
+ DICO(0x170f8d80), DICO(0x1bcd8240), DICO(0x246a8480), DICO(0x28bab640),
+ DICO(0x2f482ac0), DICO(0x36e736c0), DICO(0x3aaa68c0), DICO(0x3fc43500),
+ DICO(0x46e16000), DICO(0x4b3fbc00), DICO(0x4ff68e80), DICO(0x5aabf600),
+ DICO(0x05e849a0), DICO(0x0b485a80), DICO(0x14be52c0), DICO(0x1a079380),
+ DICO(0x1e8b1ce0), DICO(0x22fbca00), DICO(0x28c36a40), DICO(0x2e3b2a00),
+ DICO(0x34360b80), DICO(0x3a24cf00), DICO(0x3fff6200), DICO(0x45a6bf00),
+ DICO(0x4baf7800), DICO(0x51720e80), DICO(0x57560c80), DICO(0x5ce57e00),
+ DICO(0x0751da38), DICO(0x0f0949f0), DICO(0x18141860), DICO(0x1dfcb2c0),
+ DICO(0x24adbf00), DICO(0x296af240), DICO(0x2dbe60c0), DICO(0x3179ae40),
+ DICO(0x35ec4400), DICO(0x3ab76400), DICO(0x4034f400), DICO(0x45cfc700),
+ DICO(0x4bea6b00), DICO(0x516f5f00), DICO(0x57655300), DICO(0x5cfc0e00),
+ DICO(0x069900d0), DICO(0x0d379520), DICO(0x175d0560), DICO(0x1c4d92c0),
+ DICO(0x21407680), DICO(0x250d0340), DICO(0x29804940), DICO(0x2dfb9ac0),
+ DICO(0x337a1f80), DICO(0x39105fc0), DICO(0x3efd0380), DICO(0x44bce380),
+ DICO(0x4b07cc80), DICO(0x50ad7d00), DICO(0x56ddce80), DICO(0x5cb9a000),
+ DICO(0x069c6948), DICO(0x0a56ea10), DICO(0x0f7cca20), DICO(0x12d18680),
+ DICO(0x17036d00), DICO(0x1f4c1e80), DICO(0x262e5540), DICO(0x2b951e40),
+ DICO(0x3468ad40), DICO(0x3a2b2100), DICO(0x3f02f0c0), DICO(0x4383e400),
+ DICO(0x48374180), DICO(0x4d8eec80), DICO(0x54d74800), DICO(0x5c309600),
+ DICO(0x05a50158), DICO(0x0797e350), DICO(0x0cf1f230), DICO(0x14f3fb20),
+ DICO(0x17676400), DICO(0x20636780), DICO(0x2617ef80), DICO(0x29cbf700),
+ DICO(0x32ed57c0), DICO(0x374c3080), DICO(0x3b348e40), DICO(0x3fde0180),
+ DICO(0x44d38c00), DICO(0x4a8c6100), DICO(0x55f0e400), DICO(0x5dfed100),
+ DICO(0x04b74228), DICO(0x0623d3e0), DICO(0x0ab4c670), DICO(0x1bde7fa0),
+ DICO(0x1fcb6ac0), DICO(0x2344a540), DICO(0x275f7c40), DICO(0x2b7a8300),
+ DICO(0x31407440), DICO(0x35237700), DICO(0x38798540), DICO(0x3d0af340),
+ DICO(0x4224c980), DICO(0x49a17900), DICO(0x57702880), DICO(0x5dba4c00),
+ DICO(0x03c83c84), DICO(0x05cc52d8), DICO(0x0b644c10), DICO(0x129ab9a0),
+ DICO(0x1cee46c0), DICO(0x2152b080), DICO(0x247b1c00), DICO(0x27697180),
+ DICO(0x304f7500), DICO(0x3895d880), DICO(0x3c3a1740), DICO(0x413ace80),
+ DICO(0x462b0100), DICO(0x4ab07e00), DICO(0x50967580), DICO(0x5ba5e700),
+ DICO(0x06bcfda8), DICO(0x08c8b920), DICO(0x0de21530), DICO(0x1028d320),
+ DICO(0x168cfe00), DICO(0x20f78a40), DICO(0x248493c0), DICO(0x2c34bf80),
+ DICO(0x2ff88540), DICO(0x32d28c40), DICO(0x36d99640), DICO(0x4438e500),
+ DICO(0x4bacdb00), DICO(0x50343700), DICO(0x56b79080), DICO(0x5b694d00),
+ DICO(0x069109a0), DICO(0x0a73bc50), DICO(0x0e3c8330), DICO(0x13082620),
+ DICO(0x1c3a3760), DICO(0x200b5e80), DICO(0x256a4880), DICO(0x2b256ac0),
+ DICO(0x2f34afc0), DICO(0x35580200), DICO(0x3e0bd9c0), DICO(0x43d92900),
+ DICO(0x494e6e00), DICO(0x4f1a2780), DICO(0x5532a980), DICO(0x5a835a80),
+ DICO(0x04053450), DICO(0x05cb8fe0), DICO(0x097387b0), DICO(0x1121af00),
+ DICO(0x1abf62c0), DICO(0x1e39bbe0), DICO(0x243de300), DICO(0x2b440ec0),
+ DICO(0x2f2c1480), DICO(0x34697d80), DICO(0x405f8600), DICO(0x440b6f80),
+ DICO(0x47373100), DICO(0x4c764f80), DICO(0x55293780), DICO(0x5c59a780),
+ DICO(0x03c5b4a4), DICO(0x056fb380), DICO(0x09b8f910), DICO(0x13833fa0),
+ DICO(0x185eed60), DICO(0x1ce33d40), DICO(0x242e4100), DICO(0x282e5b80),
+ DICO(0x2cfe4d40), DICO(0x38a06d80), DICO(0x3e002240), DICO(0x423be400),
+ DICO(0x49a5e600), DICO(0x5092b780), DICO(0x57023d00), DICO(0x5d5f7c80),
+ DICO(0x077ada38), DICO(0x09d5ac70), DICO(0x0e58be30), DICO(0x14fb2040),
+ DICO(0x17fc9dc0), DICO(0x1c2c31e0), DICO(0x26cf1b00), DICO(0x2a91ba80),
+ DICO(0x2ed880c0), DICO(0x38cbf900), DICO(0x3d2fc700), DICO(0x405d2280),
+ DICO(0x439c1d00), DICO(0x4dd16800), DICO(0x5672c080), DICO(0x5d313880),
+ DICO(0x04272090), DICO(0x05d76e18), DICO(0x0b4d8080), DICO(0x12883f60),
+ DICO(0x17952180), DICO(0x2040d480), DICO(0x23e8cc00), DICO(0x2819c200),
+ DICO(0x2b871040), DICO(0x357c8f00), DICO(0x3caf9ac0), DICO(0x40a39380),
+ DICO(0x45bc2780), DICO(0x4e4aa300), DICO(0x568c2280), DICO(0x5cadc400),
+ DICO(0x0375b03c), DICO(0x056f0b40), DICO(0x0b0dc930), DICO(0x128c51e0),
+ DICO(0x189fa360), DICO(0x1c8197e0), DICO(0x1eed52a0), DICO(0x23ed4500),
+ DICO(0x2e5eb840), DICO(0x36415a40), DICO(0x3dcf6340), DICO(0x43126e80),
+ DICO(0x4aeb7f80), DICO(0x501e1280), DICO(0x5852b100), DICO(0x5d040d80),
+ DICO(0x06351b88), DICO(0x07f90ac0), DICO(0x0bab4ea0), DICO(0x18d04b40),
+ DICO(0x1f1e1480), DICO(0x219abcc0), DICO(0x261c31c0), DICO(0x2a611a00),
+ DICO(0x2e725480), DICO(0x36b511c0), DICO(0x3d362f00), DICO(0x40be6d80),
+ DICO(0x456dc400), DICO(0x4b74c580), DICO(0x55c82680), DICO(0x5e318480),
+ DICO(0x046212d8), DICO(0x05ca95e8), DICO(0x0a02d910), DICO(0x1ae58f40),
+ DICO(0x1e73ec20), DICO(0x2197d640), DICO(0x2581df00), DICO(0x29c83780),
+ DICO(0x31294300), DICO(0x356f8a40), DICO(0x3b97d240), DICO(0x4505cc80),
+ DICO(0x4b497600), DICO(0x504e8780), DICO(0x55644480), DICO(0x5bdedf80),
+ DICO(0x0514f798), DICO(0x06bd0d00), DICO(0x0fc31550), DICO(0x13dfb1a0),
+ DICO(0x17dda900), DICO(0x204a8c40), DICO(0x23095300), DICO(0x2d0da040),
+ DICO(0x31b2a540), DICO(0x34620180), DICO(0x3ab3e000), DICO(0x448ac300),
+ DICO(0x4be6a600), DICO(0x5114e280), DICO(0x562b0780), DICO(0x5b833c00),
+ DICO(0x070f5ef0), DICO(0x0919c2b0), DICO(0x0e778740), DICO(0x154db320),
+ DICO(0x177cfbe0), DICO(0x1ea66040), DICO(0x23666680), DICO(0x2839c400),
+ DICO(0x30cc4ec0), DICO(0x3444a280), DICO(0x38c93580), DICO(0x42a80e00),
+ DICO(0x4c433880), DICO(0x519e4f80), DICO(0x56ff8f80), DICO(0x5be18200),
+ DICO(0x066c5968), DICO(0x08a589f0), DICO(0x0ca4d7a0), DICO(0x0ffdefb0),
+ DICO(0x12943f40), DICO(0x1be84ee0), DICO(0x21276540), DICO(0x265a9540),
+ DICO(0x2e0de140), DICO(0x325148c0), DICO(0x3bd05d40), DICO(0x41e81780),
+ DICO(0x4b7cf400), DICO(0x53289400), DICO(0x597d9000), DICO(0x5e458e00),
+ DICO(0x04da3e40), DICO(0x06e8e1b0), DICO(0x0b9b1a20), DICO(0x11264bc0),
+ DICO(0x14f3d7e0), DICO(0x1cf9c100), DICO(0x23568f40), DICO(0x292b5380),
+ DICO(0x33878d40), DICO(0x38dac840), DICO(0x3d578200), DICO(0x4223a880),
+ DICO(0x473fb700), DICO(0x4c765500), DICO(0x546c6480), DICO(0x5c76d280),
+ DICO(0x05e63bb0), DICO(0x07a1a428), DICO(0x0ec4ff10), DICO(0x1348a100),
+ DICO(0x16204f40), DICO(0x1a0a6440), DICO(0x1e33f6c0), DICO(0x2ae8ccc0),
+ DICO(0x2ed5e6c0), DICO(0x32427600), DICO(0x379d9980), DICO(0x3c0f4080),
+ DICO(0x441ea680), DICO(0x4e592b00), DICO(0x56e27700), DICO(0x5da2e280),
+ DICO(0x0474de80), DICO(0x06167248), DICO(0x0ce650e0), DICO(0x135b4aa0),
+ DICO(0x16cea2a0), DICO(0x1d138ac0), DICO(0x220a84c0), DICO(0x275ca380),
+ DICO(0x2c300340), DICO(0x333b3d80), DICO(0x37a35080), DICO(0x40b83880),
+ DICO(0x494c4780), DICO(0x4ff71c80), DICO(0x56db2d80), DICO(0x5d0aac00),
+ DICO(0x0746cd00), DICO(0x09deff10), DICO(0x0e4a3560), DICO(0x14f005e0),
+ DICO(0x186a4de0), DICO(0x1cd0b240), DICO(0x22287bc0), DICO(0x26ced500),
+ DICO(0x2d57c440), DICO(0x31d943c0), DICO(0x364b0f80), DICO(0x3c85a040),
+ DICO(0x4240ca00), DICO(0x4a648080), DICO(0x54d12200), DICO(0x5d1a1c00),
+ DICO(0x05522eb0), DICO(0x0704efb8), DICO(0x0c66cd50), DICO(0x15aefca0),
+ DICO(0x184f7b00), DICO(0x1e4b26a0), DICO(0x22667640), DICO(0x284e4e00),
+ DICO(0x2d8be3c0), DICO(0x31376f00), DICO(0x39cd9800), DICO(0x3e46b740),
+ DICO(0x43af0380), DICO(0x4e1dec00), DICO(0x562ac500), DICO(0x5d45f580),
+ DICO(0x062f5708), DICO(0x08d079a0), DICO(0x0c1b4920), DICO(0x13f147c0),
+ DICO(0x1ae77c80), DICO(0x1d200ea0), DICO(0x236e4740), DICO(0x2b98d000),
+ DICO(0x2eefc600), DICO(0x34c674c0), DICO(0x3d36f540), DICO(0x411d8c00),
+ DICO(0x45c50300), DICO(0x4d207480), DICO(0x55603100), DICO(0x5c442d80),
+ DICO(0x0510bcd0), DICO(0x06ec00a0), DICO(0x0b639550), DICO(0x15daa2c0),
+ DICO(0x18c0ba60), DICO(0x1e0f7d60), DICO(0x24b05c80), DICO(0x280638c0),
+ DICO(0x314a6580), DICO(0x35e4b2c0), DICO(0x3aef2bc0), DICO(0x4158c280),
+ DICO(0x4d245100), DICO(0x53c69a80), DICO(0x597f1000), DICO(0x5dcb0080),
+ DICO(0x042cb748), DICO(0x05d710b0), DICO(0x0afe6130), DICO(0x1256cdc0),
+ DICO(0x15b8cd00), DICO(0x1dc72d20), DICO(0x2205fc00), DICO(0x2a3d0d00),
+ DICO(0x2f3ba600), DICO(0x33b3d840), DICO(0x3b5a5440), DICO(0x416c9d00),
+ DICO(0x497cdd80), DICO(0x50405e00), DICO(0x570ca980), DICO(0x5d3aa180),
+ DICO(0x0443b7b8), DICO(0x063d8588), DICO(0x0c76ef20), DICO(0x12709b40),
+ DICO(0x1649f0a0), DICO(0x20c522c0), DICO(0x24cde400), DICO(0x2ba78280),
+ DICO(0x3104c340), DICO(0x360b1740), DICO(0x3cd6a6c0), DICO(0x42573800),
+ DICO(0x48b18480), DICO(0x4fca1e00), DICO(0x5700c100), DICO(0x5cf14480),
+ DICO(0x05123628), DICO(0x06bf10b0), DICO(0x0bde7570), DICO(0x175b7ee0),
+ DICO(0x1a134460), DICO(0x20fa4100), DICO(0x25eda440), DICO(0x29c3b540),
+ DICO(0x318a1b40), DICO(0x35e0d500), DICO(0x3a147f00), DICO(0x3f08e980),
+ DICO(0x445d7580), DICO(0x4ec48c80), DICO(0x588bce80), DICO(0x5dfae300),
+ DICO(0x04c9e750), DICO(0x065224f8), DICO(0x0c6f1e30), DICO(0x1a2ffca0),
+ DICO(0x1cac6140), DICO(0x21c2a640), DICO(0x25fb8ac0), DICO(0x2ab90f00),
+ DICO(0x33189200), DICO(0x38088ac0), DICO(0x3bb7de40), DICO(0x40180800),
+ DICO(0x4453c300), DICO(0x4cdba880), DICO(0x54902680), DICO(0x5bb21700),
+ DICO(0x06958570), DICO(0x097f32b0), DICO(0x0cb418b0), DICO(0x141b6900),
+ DICO(0x1c8cfb00), DICO(0x1fab7920), DICO(0x2477c800), DICO(0x2aabed40),
+ DICO(0x2eb1a080), DICO(0x339f67c0), DICO(0x3abcc240), DICO(0x3f661b00),
+ DICO(0x45663280), DICO(0x4c680800), DICO(0x51703000), DICO(0x58a0e000),
+ DICO(0x069f6c88), DICO(0x095e1490), DICO(0x0cf442b0), DICO(0x10ea8d60),
+ DICO(0x1377b580), DICO(0x195ed480), DICO(0x26542b00), DICO(0x2c9ea700),
+ DICO(0x318d8ac0), DICO(0x364e5a40), DICO(0x3a0db000), DICO(0x3e1087c0),
+ DICO(0x450ca380), DICO(0x4c781d00), DICO(0x53cf7a00), DICO(0x5c7d1280),
+ DICO(0x06e51d98), DICO(0x09eb8d30), DICO(0x0e6683d0), DICO(0x129418a0),
+ DICO(0x1562fc80), DICO(0x1f708660), DICO(0x253f1000), DICO(0x293a16c0),
+ DICO(0x2e7c1d80), DICO(0x316e75c0), DICO(0x35a7fbc0), DICO(0x3bfbf780),
+ DICO(0x416a9200), DICO(0x4be36400), DICO(0x56dc7a80), DICO(0x5d64ea80),
+ DICO(0x0574d0c8), DICO(0x0748efd0), DICO(0x0b510860), DICO(0x0e219e00),
+ DICO(0x1299cc00), DICO(0x1ef706a0), DICO(0x22ca38c0), DICO(0x28820a00),
+ DICO(0x2cc635c0), DICO(0x31ef4740), DICO(0x3a5e89c0), DICO(0x42acaa00),
+ DICO(0x4b2bf500), DICO(0x515e0980), DICO(0x57949400), DICO(0x5d002500),
+ DICO(0x07c715d0), DICO(0x0b3fa110), DICO(0x0e745370), DICO(0x11e93560),
+ DICO(0x14bad680), DICO(0x189a0400), DICO(0x240b1240), DICO(0x2a6b3580),
+ DICO(0x2e5e1380), DICO(0x352072c0), DICO(0x3a5037c0), DICO(0x3e3726c0),
+ DICO(0x4725ed80), DICO(0x4f885900), DICO(0x54c8d580), DICO(0x5b261680),
+ DICO(0x075f02a8), DICO(0x0a214900), DICO(0x0e189de0), DICO(0x1376d5a0),
+ DICO(0x163d5c80), DICO(0x1a94b3e0), DICO(0x21376980), DICO(0x259c3140),
+ DICO(0x2e663bc0), DICO(0x337884c0), DICO(0x3a035c00), DICO(0x40b32c00),
+ DICO(0x4b21de00), DICO(0x53298f00), DICO(0x58788080), DICO(0x5cfa7c00),
+ DICO(0x05658988), DICO(0x0797f470), DICO(0x0d250810), DICO(0x102fc2a0),
+ DICO(0x13738fe0), DICO(0x1740bbc0), DICO(0x2491b380), DICO(0x28bc5800),
+ DICO(0x2c75a940), DICO(0x325cb500), DICO(0x37944740), DICO(0x405f2d80),
+ DICO(0x48eb8f00), DICO(0x50676f80), DICO(0x56f70380), DICO(0x5d62c000),
+ DICO(0x0531b540), DICO(0x06ae64c0), DICO(0x0cf7ad30), DICO(0x11c83000),
+ DICO(0x14edc980), DICO(0x18d436c0), DICO(0x1e184080), DICO(0x2603bb80),
+ DICO(0x2a2f2f80), DICO(0x33bdbe00), DICO(0x3a1066c0), DICO(0x42b9ff00),
+ DICO(0x4a617580), DICO(0x51619480), DICO(0x57ccd500), DICO(0x5d4d1600),
+ DICO(0x03e40bac), DICO(0x05f53158), DICO(0x0e76d3b0), DICO(0x17c157a0),
+ DICO(0x1ccb5bc0), DICO(0x250129c0), DICO(0x2b7d9d00), DICO(0x33224d80),
+ DICO(0x3966f600), DICO(0x3f399480), DICO(0x4449fc80), DICO(0x49401b80),
+ DICO(0x4e2ab580), DICO(0x53117000), DICO(0x5848e080), DICO(0x5d66a280),
+ DICO(0x041d4f60), DICO(0x070e8080), DICO(0x1390ec40), DICO(0x177c42c0),
+ DICO(0x1beb1400), DICO(0x208b0580), DICO(0x264cbb40), DICO(0x2bd30940),
+ DICO(0x30b30880), DICO(0x36978e80), DICO(0x3cb2a140), DICO(0x43f6b080),
+ DICO(0x4a881000), DICO(0x505ca780), DICO(0x569a5d80), DICO(0x5cae3580),
+ DICO(0x03f3c760), DICO(0x05564e08), DICO(0x09e310d0), DICO(0x1b9b3d00),
+ DICO(0x20909ac0), DICO(0x2382eec0), DICO(0x278c6700), DICO(0x2b34d500),
+ DICO(0x30fa2ac0), DICO(0x34d27d40), DICO(0x38e334c0), DICO(0x3d732440),
+ DICO(0x46d07800), DICO(0x51f4d400), DICO(0x57744f80), DICO(0x5d56bb80),
+ DICO(0x03abfdd8), DICO(0x0512b140), DICO(0x135f7500), DICO(0x19fcc4c0),
+ DICO(0x1d0b1b80), DICO(0x21eca540), DICO(0x258f8700), DICO(0x29e292c0),
+ DICO(0x2c51fe80), DICO(0x31e2a180), DICO(0x3c638640), DICO(0x44873a00),
+ DICO(0x4bb7e800), DICO(0x5078f700), DICO(0x57fc9b80), DICO(0x5def1c00),
+ DICO(0x04721ef0), DICO(0x06688158), DICO(0x0f65a5d0), DICO(0x14499840),
+ DICO(0x1bf5b8c0), DICO(0x1f33b700), DICO(0x264b6900), DICO(0x2c3e6780),
+ DICO(0x2ec8d440), DICO(0x323885c0), DICO(0x37143300), DICO(0x3bafa800),
+ DICO(0x49030480), DICO(0x54c16b00), DICO(0x58ec4b00), DICO(0x5d713d00),
+ DICO(0x03d114e4), DICO(0x067e5b40), DICO(0x10393420), DICO(0x14961300),
+ DICO(0x1a59cfa0), DICO(0x20854240), DICO(0x26b3f300), DICO(0x2e3e2840),
+ DICO(0x323bd300), DICO(0x37c49280), DICO(0x3d79e500), DICO(0x4352d880),
+ DICO(0x49e17980), DICO(0x4fc72f80), DICO(0x55c0c680), DICO(0x5c53c700),
+ DICO(0x053f5de8), DICO(0x075162b8), DICO(0x0fae8050), DICO(0x13ec0ee0),
+ DICO(0x17f92440), DICO(0x1f054440), DICO(0x24b15d40), DICO(0x2add4480),
+ DICO(0x2e306300), DICO(0x35420680), DICO(0x3c6b6e00), DICO(0x42fc0380),
+ DICO(0x4732e380), DICO(0x4ceb2200), DICO(0x522efe00), DICO(0x5aa12680),
+ DICO(0x06111728), DICO(0x08183c80), DICO(0x0d026650), DICO(0x14b41940),
+ DICO(0x17e37320), DICO(0x1c40b160), DICO(0x219c5400), DICO(0x26d88840),
+ DICO(0x2bfdfe00), DICO(0x315a2800), DICO(0x38cd7140), DICO(0x3de22740),
+ DICO(0x48ff1300), DICO(0x53ef4180), DICO(0x5a479380), DICO(0x5ea1e380),
+ DICO(0x07ea0fa8), DICO(0x0a844ef0), DICO(0x0e1023c0), DICO(0x1208d980),
+ DICO(0x15891360), DICO(0x1bebc380), DICO(0x2087da40), DICO(0x257ac940),
+ DICO(0x2caefa00), DICO(0x300defc0), DICO(0x376aa000), DICO(0x438aad80),
+ DICO(0x49f00500), DICO(0x4e023780), DICO(0x524e5800), DICO(0x5abcb980),
+ DICO(0x079cfc88), DICO(0x0a367240), DICO(0x0f224330), DICO(0x15b51540),
+ DICO(0x19065420), DICO(0x1ddbe0a0), DICO(0x23a99d80), DICO(0x28c2d340),
+ DICO(0x2f627e40), DICO(0x3487e080), DICO(0x38b76bc0), DICO(0x3d135580),
+ DICO(0x43799a80), DICO(0x489a5000), DICO(0x4ece6280), DICO(0x5a82f500),
+ DICO(0x06c37e40), DICO(0x093f0540), DICO(0x0e0d0c30), DICO(0x17487860),
+ DICO(0x1bf78020), DICO(0x20318000), DICO(0x260b8300), DICO(0x2c615980),
+ DICO(0x30c88440), DICO(0x36433b40), DICO(0x3bdb8c40), DICO(0x40050c80),
+ DICO(0x44062f80), DICO(0x48a8d480), DICO(0x4dd64d00), DICO(0x55abd380),
+ DICO(0x05e9e828), DICO(0x07f24330), DICO(0x0c8b4fe0), DICO(0x0ecd2820),
+ DICO(0x17f05c00), DICO(0x1fdb4560), DICO(0x24b4c940), DICO(0x2968d0c0),
+ DICO(0x2cbf3500), DICO(0x381eadc0), DICO(0x3d3baf40), DICO(0x42828080),
+ DICO(0x47f36300), DICO(0x4c8c6600), DICO(0x51d66f00), DICO(0x5a7e0300),
+ DICO(0x065c5cf8), DICO(0x08882540), DICO(0x0d887c70), DICO(0x112ac560),
+ DICO(0x150ccdc0), DICO(0x19e49c20), DICO(0x1eb65680), DICO(0x2a76e040),
+ DICO(0x2f65fc00), DICO(0x36d79cc0), DICO(0x3c85a900), DICO(0x408dc680),
+ DICO(0x44964700), DICO(0x4a98eb00), DICO(0x5528b500), DICO(0x5d660f80),
+ DICO(0x06b56230), DICO(0x08e340f0), DICO(0x0e1e4380), DICO(0x112d2d40),
+ DICO(0x158dfde0), DICO(0x227e6040), DICO(0x26bff7c0), DICO(0x2b73a100),
+ DICO(0x32199580), DICO(0x3585a240), DICO(0x398a5d40), DICO(0x3db8c6c0),
+ DICO(0x43905600), DICO(0x4945f800), DICO(0x4f310380), DICO(0x5a6d2400),
+ DICO(0x05cfc6f8), DICO(0x0832e650), DICO(0x0de82f80), DICO(0x1a1afe80),
+ DICO(0x1e9a1f80), DICO(0x221acd80), DICO(0x27fa00c0), DICO(0x2c4df980),
+ DICO(0x31e04bc0), DICO(0x38c9ed40), DICO(0x3db86080), DICO(0x428ec800),
+ DICO(0x48500500), DICO(0x4e1ca580), DICO(0x53d3f500), DICO(0x5aa6be00),
+ DICO(0x050cc4d0), DICO(0x070c2180), DICO(0x0c4ca980), DICO(0x0fce9f40),
+ DICO(0x14af4160), DICO(0x2206a780), DICO(0x25848e80), DICO(0x2c2b84c0),
+ DICO(0x35a39980), DICO(0x3914bd80), DICO(0x3caff580), DICO(0x3fcb0600),
+ DICO(0x4426b380), DICO(0x486c9700), DICO(0x4f730480), DICO(0x5afd3980),
+ DICO(0x05e40640), DICO(0x0830df50), DICO(0x0b9e83e0), DICO(0x158bacc0),
+ DICO(0x1d0692e0), DICO(0x2021e0c0), DICO(0x26572e00), DICO(0x2d58cc40),
+ DICO(0x30dd0f80), DICO(0x361d68c0), DICO(0x3e3086c0), DICO(0x42450800),
+ DICO(0x46c25800), DICO(0x4c45cf00), DICO(0x51dd4200), DICO(0x57326500),
+ DICO(0x04d32fa0), DICO(0x064ed2c0), DICO(0x0b07cd70), DICO(0x1c7f6da0),
+ DICO(0x213bc140), DICO(0x25051fc0), DICO(0x295cd1c0), DICO(0x2c9f4f80),
+ DICO(0x32271540), DICO(0x36a8ec80), DICO(0x3a8e6b40), DICO(0x3e137580),
+ DICO(0x42795480), DICO(0x4779b780), DICO(0x4f7d9600), DICO(0x5c09b000),
+ DICO(0x044b0748), DICO(0x05fee680), DICO(0x08f66960), DICO(0x11db5940),
+ DICO(0x219ede80), DICO(0x27fb96c0), DICO(0x2affc980), DICO(0x2eadc3c0),
+ DICO(0x32895700), DICO(0x37180d00), DICO(0x3d4bf880), DICO(0x41741980),
+ DICO(0x460d8280), DICO(0x4c34be80), DICO(0x54531e80), DICO(0x5c874000),
+ DICO(0x03e25dcc), DICO(0x069e8170), DICO(0x13b3d9c0), DICO(0x1a803260),
+ DICO(0x1ed3a4a0), DICO(0x23ea6380), DICO(0x2883b900), DICO(0x2e0ceac0),
+ DICO(0x3308e400), DICO(0x38796dc0), DICO(0x3e318e80), DICO(0x441da080),
+ DICO(0x4a892300), DICO(0x509b9f80), DICO(0x56caa380), DICO(0x5cc39e00),
+ DICO(0x05023038), DICO(0x06b6b4d8), DICO(0x0a449370), DICO(0x15b86ea0),
+ DICO(0x224a9200), DICO(0x272e6f40), DICO(0x2a617700), DICO(0x2e915d00),
+ DICO(0x3240ac40), DICO(0x37636300), DICO(0x3dd3ea80), DICO(0x420e1f80),
+ DICO(0x45bf0680), DICO(0x4a26d980), DICO(0x4f82a900), DICO(0x56576800),
+ DICO(0x03d630f4), DICO(0x082140a0), DICO(0x12644700), DICO(0x16b80cc0),
+ DICO(0x1ba90c40), DICO(0x21c38300), DICO(0x27dd1480), DICO(0x2e18ee00),
+ DICO(0x33fb72c0), DICO(0x39f9d980), DICO(0x40219300), DICO(0x4607fd00),
+ DICO(0x4c07e500), DICO(0x51ba8f00), DICO(0x57a24280), DICO(0x5d367700),
+ DICO(0x080a5880), DICO(0x0ef3f570), DICO(0x141fd6c0), DICO(0x17c163a0),
+ DICO(0x1c2840a0), DICO(0x2111fe00), DICO(0x27376bc0), DICO(0x2cc7edc0),
+ DICO(0x329b0100), DICO(0x386d3e40), DICO(0x3ec1bdc0), DICO(0x453f6200),
+ DICO(0x4bf16080), DICO(0x51bded00), DICO(0x57ba6800), DICO(0x5d2ffd80),
+ DICO(0x08643590), DICO(0x0e911f00), DICO(0x15911380), DICO(0x1ab5e180),
+ DICO(0x207ff600), DICO(0x26399b00), DICO(0x2cadae80), DICO(0x3276ca40),
+ DICO(0x389d9cc0), DICO(0x3eb22180), DICO(0x44570700), DICO(0x49d15800),
+ DICO(0x4f591300), DICO(0x54566a80), DICO(0x5967db00), DICO(0x5e307780),
+ DICO(0x07120fa8), DICO(0x0c791c60), DICO(0x112d3b60), DICO(0x149452a0),
+ DICO(0x19d2c100), DICO(0x202f1540), DICO(0x269c10c0), DICO(0x2be22880),
+ DICO(0x312a07c0), DICO(0x36984fc0), DICO(0x3c7ac3c0), DICO(0x435b5000),
+ DICO(0x4aa60280), DICO(0x50f50c00), DICO(0x5719f700), DICO(0x5cb98680),
+ DICO(0x05517c88), DICO(0x06ba0a70), DICO(0x0da167c0), DICO(0x19918440),
+ DICO(0x1bb37220), DICO(0x20681080), DICO(0x23dc6740), DICO(0x2a1403c0),
+ DICO(0x31a71580), DICO(0x34ff0600), DICO(0x395b7cc0), DICO(0x42019200),
+ DICO(0x4c818d00), DICO(0x513ff400), DICO(0x5731ce00), DICO(0x5c5f1180),
+ DICO(0x04f74ec0), DICO(0x067b4628), DICO(0x0dc4c9c0), DICO(0x19e9fa40),
+ DICO(0x1cf00a00), DICO(0x21602a80), DICO(0x25334a80), DICO(0x29b3a800),
+ DICO(0x2f9b3600), DICO(0x338c0540), DICO(0x370c3cc0), DICO(0x3abbc3c0),
+ DICO(0x4053a000), DICO(0x4f14d980), DICO(0x57e0b600), DICO(0x5d95e780),
+ DICO(0x05d844b8), DICO(0x07a05608), DICO(0x0b7837f0), DICO(0x161fb460),
+ DICO(0x19c31d00), DICO(0x1cf36280), DICO(0x20ccc200), DICO(0x24ae3980),
+ DICO(0x2e2b5800), DICO(0x3316af80), DICO(0x37432b00), DICO(0x4050b280),
+ DICO(0x4605be00), DICO(0x4cc78900), DICO(0x556d2080), DICO(0x5c578300),
+ DICO(0x0551b768), DICO(0x07024f60), DICO(0x1045fde0), DICO(0x16480120),
+ DICO(0x19974420), DICO(0x1ec2b280), DICO(0x228b30c0), DICO(0x295e0ec0),
+ DICO(0x2d8775c0), DICO(0x30ef1440), DICO(0x35978080), DICO(0x3a2ab480),
+ DICO(0x40229780), DICO(0x4da40980), DICO(0x5718e480), DICO(0x5d68d400),
+ DICO(0x03f903e4), DICO(0x06731580), DICO(0x0ecf4850), DICO(0x12e57920),
+ DICO(0x1a69ece0), DICO(0x1fe32700), DICO(0x2585b9c0), DICO(0x2aa006c0),
+ DICO(0x2f20ea80), DICO(0x37298bc0), DICO(0x3df2a000), DICO(0x44a6c600),
+ DICO(0x4b10de00), DICO(0x510fb880), DICO(0x5749c280), DICO(0x5d0b9480),
+ DICO(0x03c418fc), DICO(0x056c4cd0), DICO(0x0d0cf070), DICO(0x1907a2c0),
+ DICO(0x1be9bc00), DICO(0x21599480), DICO(0x25700e40), DICO(0x2c83e280),
+ DICO(0x329fa7c0), DICO(0x389f4cc0), DICO(0x3ef60900), DICO(0x44c19300),
+ DICO(0x4af56d00), DICO(0x512eec80), DICO(0x5772ad00), DICO(0x5d37f380),
+ DICO(0x04d57920), DICO(0x0716b5e0), DICO(0x0cb3bcc0), DICO(0x1197f740),
+ DICO(0x163e5fc0), DICO(0x2194e400), DICO(0x274bb600), DICO(0x2f5d7080),
+ DICO(0x361ee340), DICO(0x3b3b22c0), DICO(0x3f800400), DICO(0x4327ef80),
+ DICO(0x48b5d200), DICO(0x5116d300), DICO(0x59652e80), DICO(0x5e444d00),
+ DICO(0x0755b6b0), DICO(0x0b68c2c0), DICO(0x0f3441d0), DICO(0x124a01a0),
+ DICO(0x18910600), DICO(0x20911b80), DICO(0x281f7100), DICO(0x2e4dd640),
+ DICO(0x335bd8c0), DICO(0x37f14a80), DICO(0x3cab7b80), DICO(0x43be3180),
+ DICO(0x4beee100), DICO(0x52292180), DICO(0x57efea00), DICO(0x5d177300),
+ DICO(0x071a7748), DICO(0x0c6cf1b0), DICO(0x10db1500), DICO(0x143bca00),
+ DICO(0x1b86a900), DICO(0x22ed1d80), DICO(0x2a1f61c0), DICO(0x305f1400),
+ DICO(0x3645f580), DICO(0x3be45b00), DICO(0x4166ea80), DICO(0x46c3f200),
+ DICO(0x4c740400), DICO(0x51e30d00), DICO(0x57a37000), DICO(0x5cfc4980),
+ DICO(0x08cdd5b0), DICO(0x0daf9840), DICO(0x11cc02a0), DICO(0x1588ed40),
+ DICO(0x1cfef5e0), DICO(0x239f12c0), DICO(0x296d3b40), DICO(0x2e61c240),
+ DICO(0x333dc800), DICO(0x385d0000), DICO(0x3e1e5180), DICO(0x44196e00),
+ DICO(0x4a833000), DICO(0x503d7b80), DICO(0x56556680), DICO(0x5c410c00),
+ DICO(0x07372408), DICO(0x0d5c41f0), DICO(0x155dc140), DICO(0x1a9a3cc0),
+ DICO(0x21740980), DICO(0x27139f40), DICO(0x2c977040), DICO(0x30cfe5c0),
+ DICO(0x35381240), DICO(0x39b83140), DICO(0x3ef3fe80), DICO(0x44547200),
+ DICO(0x4a812800), DICO(0x5046c200), DICO(0x56957d00), DICO(0x5c85cd80),
+ DICO(0x06da6990), DICO(0x0bc41250), DICO(0x13d54800), DICO(0x1979c220),
+ DICO(0x1fad2f00), DICO(0x24bbe0c0), DICO(0x29c08f00), DICO(0x2e34b940),
+ DICO(0x32c89e40), DICO(0x376a2040), DICO(0x3cd81080), DICO(0x4267bd00),
+ DICO(0x48e8e800), DICO(0x4f150280), DICO(0x55cb1980), DICO(0x5c428b80),
+ DICO(0x087d45d0), DICO(0x0cf1ef20), DICO(0x135cba20), DICO(0x16fc7420),
+ DICO(0x1b2772e0), DICO(0x1fd4fe60), DICO(0x260a0b80), DICO(0x2bc54c00),
+ DICO(0x31694cc0), DICO(0x36d08080), DICO(0x3c245c80), DICO(0x41170900),
+ DICO(0x47b18600), DICO(0x4e706180), DICO(0x558d2000), DICO(0x5c428d00),
+ DICO(0x081e6490), DICO(0x0d16a7d0), DICO(0x124ccd20), DICO(0x154c20c0),
+ DICO(0x1945d8c0), DICO(0x1ee0b700), DICO(0x26a01f00), DICO(0x2d554e40),
+ DICO(0x3432eb80), DICO(0x3a605500), DICO(0x401d8980), DICO(0x45737680),
+ DICO(0x4b03cb00), DICO(0x50666780), DICO(0x56a0cd00), DICO(0x5cb46480),
+ DICO(0x06c58278), DICO(0x091b10b0), DICO(0x0e0e74f0), DICO(0x11faf980),
+ DICO(0x14a48600), DICO(0x1e6f7500), DICO(0x27f77100), DICO(0x2ab49940),
+ DICO(0x32a1f680), DICO(0x38cb2a80), DICO(0x3c3ff140), DICO(0x3f681cc0),
+ DICO(0x44310700), DICO(0x4fa21700), DICO(0x586c6180), DICO(0x5df74200),
+ DICO(0x06a3e478), DICO(0x09714400), DICO(0x0d90b7a0), DICO(0x12df2720),
+ DICO(0x1618f320), DICO(0x1ac52840), DICO(0x27612900), DICO(0x2e438e00),
+ DICO(0x322b6ac0), DICO(0x38022940), DICO(0x3d2a5180), DICO(0x40d76b80),
+ DICO(0x46671500), DICO(0x4c5bd480), DICO(0x517a2500), DICO(0x57775b00),
+ DICO(0x056c2230), DICO(0x07b8f9d8), DICO(0x0bc6e060), DICO(0x16ac2c80),
+ DICO(0x1a92fc00), DICO(0x1e15f000), DICO(0x28b73200), DICO(0x2cd9e5c0),
+ DICO(0x3196ecc0), DICO(0x3abae340), DICO(0x4040c580), DICO(0x44c18d80),
+ DICO(0x4c086800), DICO(0x50b78500), DICO(0x54e42600), DICO(0x5a549a80),
+ DICO(0x04f9fa10), DICO(0x07419358), DICO(0x0c3e15f0), DICO(0x174c1800),
+ DICO(0x1ab1fe60), DICO(0x23a12680), DICO(0x27955780), DICO(0x2d14b1c0),
+ DICO(0x35cefb00), DICO(0x39576700), DICO(0x3e82b780), DICO(0x42b6a680),
+ DICO(0x476d1880), DICO(0x4b6cdd00), DICO(0x52758680), DICO(0x5b69e500),
+ DICO(0x060b7ab0), DICO(0x081c05c0), DICO(0x0b540300), DICO(0x0f564270),
+ DICO(0x1210aa80), DICO(0x1771e060), DICO(0x25d73280), DICO(0x2e49e380),
+ DICO(0x319c1100), DICO(0x3771e700), DICO(0x3c532f40), DICO(0x40c9a900),
+ DICO(0x48cbf580), DICO(0x4f819980), DICO(0x566f9400), DICO(0x5cfdd980),
+ DICO(0x04efb7b8), DICO(0x0b8a3710), DICO(0x124fd520), DICO(0x1846dde0),
+ DICO(0x1e77a9e0), DICO(0x243ea800), DICO(0x2a4e3280), DICO(0x2ff532c0),
+ DICO(0x35d27680), DICO(0x3b8cdb00), DICO(0x41463000), DICO(0x4706c700),
+ DICO(0x4ca42d80), DICO(0x525d9200), DICO(0x57dabb80), DICO(0x5d59a800),
+ DICO(0x03620dec), DICO(0x095872e0), DICO(0x108d4920), DICO(0x16e9ea00),
+ DICO(0x1d60b2e0), DICO(0x235e9d00), DICO(0x29893b80), DICO(0x2f59a3c0),
+ DICO(0x3556b880), DICO(0x3b10bdc0), DICO(0x40f49500), DICO(0x469cc480),
+ DICO(0x4c762d00), DICO(0x51f16980), DICO(0x578c6d00), DICO(0x5c9b5a00),
+ DICO(0x05dd9bc0), DICO(0x079c5b20), DICO(0x0d319af0), DICO(0x18997040),
+ DICO(0x1c0a1980), DICO(0x20e926c0), DICO(0x25ca1640), DICO(0x29879340),
+ DICO(0x30b27040), DICO(0x36077340), DICO(0x39ac3d00), DICO(0x3d686cc0),
+ DICO(0x428e5f00), DICO(0x47c1bf80), DICO(0x4e720800), DICO(0x5b419880),
+ DICO(0x07694258), DICO(0x0b50db90), DICO(0x0f384950), DICO(0x140dac40),
+ DICO(0x17c50d80), DICO(0x1b49b300), DICO(0x24746200), DICO(0x2ce92fc0),
+ DICO(0x309fdac0), DICO(0x35c02a00), DICO(0x3aa3df00), DICO(0x3e1edb00),
+ DICO(0x431ad280), DICO(0x4b57f500), DICO(0x51463980), DICO(0x586b5200),
+ DICO(0x06401dd0), DICO(0x08d3d9b0), DICO(0x0ca0f510), DICO(0x10ed1920),
+ DICO(0x1451c2e0), DICO(0x2082f640), DICO(0x2872c0c0), DICO(0x2ca9da00),
+ DICO(0x3219cd00), DICO(0x35977300), DICO(0x3a8ba1c0), DICO(0x43d5f280),
+ DICO(0x49a51f00), DICO(0x4de9b400), DICO(0x5362ef80), DICO(0x59387300),
+ DICO(0x0589c430), DICO(0x07809918), DICO(0x0d086f80), DICO(0x10371c20),
+ DICO(0x151842c0), DICO(0x1bfcb1c0), DICO(0x22441040), DICO(0x2722b5c0),
+ DICO(0x2b603fc0), DICO(0x314465c0), DICO(0x40308b00), DICO(0x47d5a200),
+ DICO(0x4bf7e000), DICO(0x4f937200), DICO(0x5584eb00), DICO(0x5cb02200),
+ DICO(0x03b592f0), DICO(0x056ba738), DICO(0x0a8e2250), DICO(0x172436c0),
+ DICO(0x1ad35da0), DICO(0x1d72dc80), DICO(0x20cd3900), DICO(0x2a962940),
+ DICO(0x2f3b6700), DICO(0x33312b40), DICO(0x38dc6680), DICO(0x41659200),
+ DICO(0x4d36a380), DICO(0x52b00980), DICO(0x58c82800), DICO(0x5d741600),
+ DICO(0x05bdfe10), DICO(0x0756da20), DICO(0x0cd31fe0), DICO(0x130f1820),
+ DICO(0x1561caa0), DICO(0x1962ab20), DICO(0x1c310840), DICO(0x28bf6f80),
+ DICO(0x2d2d4500), DICO(0x3230f900), DICO(0x3ac2ea80), DICO(0x3ebe71c0),
+ DICO(0x48280700), DICO(0x50254900), DICO(0x5850a200), DICO(0x5e687200),
+ DICO(0x04e2b7e8), DICO(0x067f5430), DICO(0x0a8899a0), DICO(0x0d571560),
+ DICO(0x1c42f440), DICO(0x22e21fc0), DICO(0x27074340), DICO(0x2c493240),
+ DICO(0x2f7ece00), DICO(0x33959ec0), DICO(0x392d3000), DICO(0x459fc800),
+ DICO(0x4ba5f700), DICO(0x4fde7780), DICO(0x55f90380), DICO(0x5c928b00),
+ DICO(0x0557b940), DICO(0x075f0158), DICO(0x0bd8c540), DICO(0x0f4ee370),
+ DICO(0x141dc900), DICO(0x1b241f00), DICO(0x21c32a80), DICO(0x29a23980),
+ DICO(0x2e475380), DICO(0x3616f9c0), DICO(0x3a52a500), DICO(0x40345f00),
+ DICO(0x4763a500), DICO(0x4eb5bb80), DICO(0x561d4480), DICO(0x5d388580),
+ DICO(0x057d7d08), DICO(0x0738c240), DICO(0x0bf46e10), DICO(0x0ec93da0),
+ DICO(0x14ab3cc0), DICO(0x23d0f5c0), DICO(0x271e9900), DICO(0x2c0ee4c0),
+ DICO(0x301d1f00), DICO(0x33868040), DICO(0x37cdde00), DICO(0x3c805440),
+ DICO(0x43c69200), DICO(0x4f5c9a00), DICO(0x56eb3e80), DICO(0x5cdadc80),
+ DICO(0x06cdbab0), DICO(0x0999e600), DICO(0x0df39790), DICO(0x12ffc9a0),
+ DICO(0x15cfe7a0), DICO(0x1c599300), DICO(0x21afd600), DICO(0x26842bc0),
+ DICO(0x32067c00), DICO(0x368bb080), DICO(0x3c350c40), DICO(0x44e8be00),
+ DICO(0x4ac84000), DICO(0x4f9c1280), DICO(0x5449ec00), DICO(0x594d5880),
+ DICO(0x049a6bd0), DICO(0x06849f08), DICO(0x10592b40), DICO(0x168c1940),
+ DICO(0x1992df40), DICO(0x1e91b300), DICO(0x2237e100), DICO(0x2cd73a80),
+ DICO(0x30e7c100), DICO(0x361a45c0), DICO(0x3cdd1f40), DICO(0x41d5d100),
+ DICO(0x46f79480), DICO(0x4e44c880), DICO(0x55830e80), DICO(0x5d7c0680),
+ DICO(0x05087958), DICO(0x06fb7e40), DICO(0x0ac5ace0), DICO(0x14e91d80),
+ DICO(0x19ac68c0), DICO(0x1dbf7600), DICO(0x26f916c0), DICO(0x2bd2c980),
+ DICO(0x307f7900), DICO(0x38e07e40), DICO(0x3df7f1c0), DICO(0x41323d00),
+ DICO(0x44d2f480), DICO(0x48fb0480), DICO(0x51e17900), DICO(0x5c15d700),
+ DICO(0x0346cf40), DICO(0x05423408), DICO(0x0b640ce0), DICO(0x13055060),
+ DICO(0x1a8c0b60), DICO(0x1d8d2280), DICO(0x218b6500), DICO(0x2c385700),
+ DICO(0x30927b40), DICO(0x35d82880), DICO(0x3aa87e00), DICO(0x3da46a40),
+ DICO(0x45ea5280), DICO(0x511ecb80), DICO(0x57b53b00), DICO(0x5d491400),
+ DICO(0x056aa1c8), DICO(0x075a09a0), DICO(0x0a5d61d0), DICO(0x13cb9fe0),
+ DICO(0x1f924dc0), DICO(0x237a11c0), DICO(0x277d6b80), DICO(0x2c2ba440),
+ DICO(0x30195c80), DICO(0x35250cc0), DICO(0x3b718200), DICO(0x40113c80),
+ DICO(0x44df2680), DICO(0x49f0ed80), DICO(0x50791980), DICO(0x5ac10600),
+ DICO(0x046f1e50), DICO(0x061dd758), DICO(0x1236bec0), DICO(0x16c07340),
+ DICO(0x1a7399c0), DICO(0x1f61ee20), DICO(0x244b2280), DICO(0x2b803e40),
+ DICO(0x2eda5300), DICO(0x331210c0), DICO(0x3773bfc0), DICO(0x411c8400),
+ DICO(0x488ff380), DICO(0x4fad2700), DICO(0x55845000), DICO(0x5ca74c00),
+ DICO(0x04b456f0), DICO(0x05fca198), DICO(0x0ad056d0), DICO(0x19c3bfe0),
+ DICO(0x1d446100), DICO(0x20f67200), DICO(0x24a40b40), DICO(0x28d472c0),
+ DICO(0x2da813c0), DICO(0x31880200), DICO(0x35344f40), DICO(0x3ca7f340),
+ DICO(0x4aa94300), DICO(0x4f921500), DICO(0x5516d700), DICO(0x5c832880),
+ DICO(0x07f468c0), DICO(0x0bbb6e90), DICO(0x0f0f8730), DICO(0x143d6180),
+ DICO(0x198b84c0), DICO(0x1c6b30a0), DICO(0x219c8000), DICO(0x28795780),
+ DICO(0x2cce3d00), DICO(0x329b1100), DICO(0x3a8d2240), DICO(0x3f579080),
+ DICO(0x45a74400), DICO(0x4d000f80), DICO(0x52bd6880), DICO(0x5a743a80),
+ DICO(0x06979498), DICO(0x088fecf0), DICO(0x0f1dac90), DICO(0x12077160),
+ DICO(0x16d5b120), DICO(0x1c5465c0), DICO(0x21ad14c0), DICO(0x282be280),
+ DICO(0x2b66a380), DICO(0x2fa3f200), DICO(0x35a06500), DICO(0x3a458d00),
+ DICO(0x44aefc00), DICO(0x4e92f600), DICO(0x55b9fa80), DICO(0x5cfe0280),
+ DICO(0x0552b408), DICO(0x06f6ce38), DICO(0x0e8f8d80), DICO(0x1395e900),
+ DICO(0x17c7b440), DICO(0x1ec64dc0), DICO(0x236e2200), DICO(0x2abc0b80),
+ DICO(0x2e131240), DICO(0x32921100), DICO(0x372633c0), DICO(0x3ca97840),
+ DICO(0x496e5000), DICO(0x4f86a800), DICO(0x54072300), DICO(0x5be31c80),
+ DICO(0x0470c0b8), DICO(0x0662c468), DICO(0x0c493fd0), DICO(0x1a1949c0),
+ DICO(0x1febcc20), DICO(0x2364e900), DICO(0x2a0cce00), DICO(0x2f6f8140),
+ DICO(0x3418b000), DICO(0x3c5c7a40), DICO(0x42d39100), DICO(0x476c2b00),
+ DICO(0x4e11c300), DICO(0x53621500), DICO(0x583fd280), DICO(0x5ce26600),
+ DICO(0x04b006c0), DICO(0x09a1ed40), DICO(0x135aee00), DICO(0x193b5180),
+ DICO(0x1f3679a0), DICO(0x24fdbcc0), DICO(0x2b823e00), DICO(0x31835780),
+ DICO(0x37c74cc0), DICO(0x3df66780), DICO(0x43c18580), DICO(0x49465980),
+ DICO(0x4ed0ce00), DICO(0x53d6fb80), DICO(0x59064300), DICO(0x5deaa100),
+ DICO(0x03cbc49c), DICO(0x07735930), DICO(0x138aaa20), DICO(0x1a1e69a0),
+ DICO(0x21be93c0), DICO(0x2936f780), DICO(0x2fa76f80), DICO(0x34ae6b00),
+ DICO(0x396b7b80), DICO(0x3dbc6700), DICO(0x421a9100), DICO(0x46fd2180),
+ DICO(0x4c5dca80), DICO(0x51923b80), DICO(0x576d1300), DICO(0x5d288680),
+ DICO(0x03cab7d0), DICO(0x052c88b8), DICO(0x09ed24f0), DICO(0x1c261820),
+ DICO(0x209096c0), DICO(0x2361e080), DICO(0x27292800), DICO(0x2bbdc6c0),
+ DICO(0x3292da80), DICO(0x36866a40), DICO(0x3c4d5100), DICO(0x45233400),
+ DICO(0x4d928a00), DICO(0x52ca9d00), DICO(0x5820d000), DICO(0x5d903880),
+ DICO(0x03f83718), DICO(0x0540fa90), DICO(0x13028120), DICO(0x1ad6e160),
+ DICO(0x1d784880), DICO(0x22028900), DICO(0x25976b40), DICO(0x2b293700),
+ DICO(0x2ddb86c0), DICO(0x317c4340), DICO(0x34e62ec0), DICO(0x3b71bd00),
+ DICO(0x4bc34780), DICO(0x52982400), DICO(0x57fa2800), DICO(0x5f19cc00),
+ DICO(0x049ceb50), DICO(0x06a8d4e0), DICO(0x09db2470), DICO(0x120e3e60),
+ DICO(0x1c8ebb80), DICO(0x21221d00), DICO(0x2679bfc0), DICO(0x2b1e7600),
+ DICO(0x2ebbcf80), DICO(0x32d5afc0), DICO(0x3d1bef00), DICO(0x41b11a00),
+ DICO(0x45bb2d80), DICO(0x4cb70300), DICO(0x572fdc80), DICO(0x5d876e80),
+ DICO(0x04abda68), DICO(0x06698cd0), DICO(0x0ca87230), DICO(0x15086a80),
+ DICO(0x176cf4e0), DICO(0x22899440), DICO(0x268fc500), DICO(0x2ba2d940),
+ DICO(0x33505980), DICO(0x36944bc0), DICO(0x3b20c280), DICO(0x437e8f00),
+ DICO(0x4bf29e80), DICO(0x51776a80), DICO(0x57a77800), DICO(0x5cf6c180),
+ DICO(0x06d7f5c0), DICO(0x08fd3cc0), DICO(0x0d8807e0), DICO(0x1140d500),
+ DICO(0x146dfc80), DICO(0x1e9fbaa0), DICO(0x23d7bf00), DICO(0x28b2ae80),
+ DICO(0x2e5a9b00), DICO(0x327005c0), DICO(0x37736640), DICO(0x4001c500),
+ DICO(0x4a862b00), DICO(0x4f7a2e00), DICO(0x54a22080), DICO(0x5b76c380),
+ DICO(0x0671fb68), DICO(0x08e4bf30), DICO(0x0d801250), DICO(0x1176b820),
+ DICO(0x15128860), DICO(0x1ee21180), DICO(0x24799580), DICO(0x29415a40),
+ DICO(0x2efa2380), DICO(0x33fe5040), DICO(0x39bf6d00), DICO(0x3f28b380),
+ DICO(0x442b2280), DICO(0x493de680), DICO(0x54377700), DICO(0x5d3a5480),
+ DICO(0x065b7970), DICO(0x087820b0), DICO(0x0d8d6aa0), DICO(0x16718620),
+ DICO(0x1a3a8f40), DICO(0x1f4099c0), DICO(0x24d87b40), DICO(0x296d85c0),
+ DICO(0x2f887c80), DICO(0x342d1b40), DICO(0x3887fc40), DICO(0x3d758b40),
+ DICO(0x42641c80), DICO(0x47bf6980), DICO(0x55f82900), DICO(0x5e132a00),
+ DICO(0x05ddbc00), DICO(0x081f17a0), DICO(0x0bf23ac0), DICO(0x12fc8d60),
+ DICO(0x172bc440), DICO(0x1a833540), DICO(0x1e942200), DICO(0x21e477c0),
+ DICO(0x2e75da80), DICO(0x399efac0), DICO(0x3dfb6900), DICO(0x428b3780),
+ DICO(0x4922a080), DICO(0x4d4c1700), DICO(0x51bbee00), DICO(0x5b4cfc80),
+ DICO(0x06ecf380), DICO(0x08f83990), DICO(0x0cb55680), DICO(0x140b2860),
+ DICO(0x18084d00), DICO(0x1aff9940), DICO(0x1f5f6f00), DICO(0x224a3d80),
+ DICO(0x2b0f49c0), DICO(0x3613b280), DICO(0x39188f40), DICO(0x3efa3640),
+ DICO(0x4771e400), DICO(0x4ca32380), DICO(0x54627580), DICO(0x5cb91000),
+ DICO(0x069e7f98), DICO(0x0870c760), DICO(0x0d7b73a0), DICO(0x15ab1040),
+ DICO(0x18a4d220), DICO(0x1c4c1f20), DICO(0x1ffaf200), DICO(0x24142580),
+ DICO(0x30e47540), DICO(0x37340200), DICO(0x3a69af40), DICO(0x3ed471c0),
+ DICO(0x44157880), DICO(0x486b7f00), DICO(0x52ed2b00), DICO(0x5ce3a980),
+ DICO(0x047f1080), DICO(0x06463230), DICO(0x0b566e80), DICO(0x0edb9080),
+ DICO(0x128a2fa0), DICO(0x1748b340), DICO(0x210b2b00), DICO(0x28099b80),
+ DICO(0x2f519740), DICO(0x36fe82c0), DICO(0x3d924b80), DICO(0x43cd3c00),
+ DICO(0x4a774680), DICO(0x50d15f00), DICO(0x573b3580), DICO(0x5d4c1c00),
+ DICO(0x05fa6a68), DICO(0x0866e4c0), DICO(0x0d133cc0), DICO(0x156d6b20),
+ DICO(0x18abebe0), DICO(0x1d374900), DICO(0x23d23d00), DICO(0x27b370c0),
+ DICO(0x2f63ef00), DICO(0x352a0600), DICO(0x3a643a40), DICO(0x3f57f980),
+ DICO(0x457a7f00), DICO(0x520f6200), DICO(0x593b2c80), DICO(0x5e192b80),
+ DICO(0x04e4e0c8), DICO(0x067c3450), DICO(0x0acabe70), DICO(0x1865eec0),
+ DICO(0x1c5e9bc0), DICO(0x202facc0), DICO(0x24a609c0), DICO(0x28db7b00),
+ DICO(0x2efbd780), DICO(0x336fe5c0), DICO(0x3819a5c0), DICO(0x3e709b40),
+ DICO(0x4435ff80), DICO(0x4bd5fb80), DICO(0x5564a100), DICO(0x5d0a4980),
+ DICO(0x05a72f00), DICO(0x070199b0), DICO(0x0e654780), DICO(0x14fc7780),
+ DICO(0x174283c0), DICO(0x1b231480), DICO(0x1e7b9000), DICO(0x27a013c0),
+ DICO(0x2b42f500), DICO(0x2fd9ca00), DICO(0x3672a0c0), DICO(0x3cc23f40),
+ DICO(0x48299d80), DICO(0x4f92a800), DICO(0x564d7680), DICO(0x5d3ab580),
+ DICO(0x03e63764), DICO(0x05baa3f0), DICO(0x0ab2a300), DICO(0x12cc5f60),
+ DICO(0x19a8d5e0), DICO(0x1ea788e0), DICO(0x22cd50c0), DICO(0x25d48a00),
+ DICO(0x29924540), DICO(0x32762a00), DICO(0x3bba55c0), DICO(0x4222e800),
+ DICO(0x4aba1280), DICO(0x501d0b80), DICO(0x57091200), DICO(0x5d6bf180),
+ DICO(0x047daeb0), DICO(0x069548b8), DICO(0x0b002410), DICO(0x13ff7060),
+ DICO(0x186aec40), DICO(0x210db240), DICO(0x26f1ce80), DICO(0x2b73c9c0),
+ DICO(0x33d57240), DICO(0x385898c0), DICO(0x3eea8cc0), DICO(0x43c79b00),
+ DICO(0x496ec200), DICO(0x4e150780), DICO(0x54dcb700), DICO(0x5c3f7380),
+ DICO(0x079fd258), DICO(0x0b93bd50), DICO(0x0ff7d8b0), DICO(0x14bd4e00),
+ DICO(0x19536ae0), DICO(0x1d8b1640), DICO(0x23747cc0), DICO(0x2861f280),
+ DICO(0x2d7d2880), DICO(0x3583b040), DICO(0x3c3cab00), DICO(0x41b7b580),
+ DICO(0x498cfc80), DICO(0x506cbd00), DICO(0x57847600), DICO(0x5d05de80),
+ DICO(0x06434ec0), DICO(0x0805ccd0), DICO(0x0c4b4c00), DICO(0x13d551c0),
+ DICO(0x1685abe0), DICO(0x1a83ea60), DICO(0x1ddc3700), DICO(0x22bc4600),
+ DICO(0x2c7ca5c0), DICO(0x30a589c0), DICO(0x395a8700), DICO(0x40c92900),
+ DICO(0x472fae80), DICO(0x4f6f6e80), DICO(0x571b3f80), DICO(0x5d8e6980),
+ DICO(0x05ec21b0), DICO(0x079ee388), DICO(0x0e4b4580), DICO(0x11abf100),
+ DICO(0x16588ec0), DICO(0x1c984ec0), DICO(0x20a384c0), DICO(0x28d6be00),
+ DICO(0x2bcca740), DICO(0x3604b600), DICO(0x3f027280), DICO(0x434af000),
+ DICO(0x48dac280), DICO(0x4d7e8a00), DICO(0x51f61800), DICO(0x5a6d9380),
+ DICO(0x0552c6c0), DICO(0x070c22a0), DICO(0x0a411b50), DICO(0x0e3e5270),
+ DICO(0x1193bb60), DICO(0x1b177e00), DICO(0x275b2500), DICO(0x2b42bd80),
+ DICO(0x322d7e40), DICO(0x3a170880), DICO(0x3d66b580), DICO(0x41413280),
+ DICO(0x46a9ce80), DICO(0x4e4e3800), DICO(0x571f8380), DICO(0x5ddae380),
+ DICO(0x055602c0), DICO(0x06e69118), DICO(0x0c9d13f0), DICO(0x1090d500),
+ DICO(0x138d2280), DICO(0x171bf540), DICO(0x1b585180), DICO(0x288b9740),
+ DICO(0x2db202c0), DICO(0x3525e680), DICO(0x3c303900), DICO(0x4311df80),
+ DICO(0x49b92c00), DICO(0x509de900), DICO(0x56e9a080), DICO(0x5d523a80),
+ DICO(0x04e79810), DICO(0x069626e8), DICO(0x0a6cf680), DICO(0x0da668c0),
+ DICO(0x115872a0), DICO(0x2032eec0), DICO(0x25345dc0), DICO(0x2ae8ea40),
+ DICO(0x30224280), DICO(0x351ff640), DICO(0x3ce65a80), DICO(0x454bff00),
+ DICO(0x4ee08980), DICO(0x543b4280), DICO(0x59c19280), DICO(0x5ddfbb00),
+ DICO(0x03f0bb98), DICO(0x0588f4f0), DICO(0x0a862bc0), DICO(0x14ec76e0),
+ DICO(0x184b8a80), DICO(0x1f7bbd80), DICO(0x23f1a7c0), DICO(0x2c367900),
+ DICO(0x3234af80), DICO(0x35460ac0), DICO(0x38514c00), DICO(0x3d5f3540),
+ DICO(0x48394980), DICO(0x4fbdd380), DICO(0x56de0280), DICO(0x5d4e6500),
+ DICO(0x06050f28), DICO(0x08070af0), DICO(0x0be31240), DICO(0x0f5e53e0),
+ DICO(0x125f1740), DICO(0x215b1fc0), DICO(0x2883d880), DICO(0x2c181080),
+ DICO(0x32810280), DICO(0x35d56800), DICO(0x3a9b0880), DICO(0x3ffaaf80),
+ DICO(0x44c65500), DICO(0x4a45ae80), DICO(0x56b4ed80), DICO(0x5e4adc00),
+ DICO(0x0372bbb4), DICO(0x04ea4848), DICO(0x09b8de70), DICO(0x151b4a40),
+ DICO(0x1be65a00), DICO(0x207655c0), DICO(0x2720dd00), DICO(0x2fc6cc00),
+ DICO(0x35b063c0), DICO(0x39bd30c0), DICO(0x3dc5b580), DICO(0x42af7b00),
+ DICO(0x48d2bf00), DICO(0x4f46bb80), DICO(0x55f7ca80), DICO(0x5ca7e980),
+ DICO(0x033f868c), DICO(0x04d9a0e0), DICO(0x0a18d6d0), DICO(0x13da5580),
+ DICO(0x181ae880), DICO(0x207d8580), DICO(0x262022c0), DICO(0x2c6de040),
+ DICO(0x3321f100), DICO(0x3927f0c0), DICO(0x3f74ce40), DICO(0x4573e980),
+ DICO(0x4ba66c80), DICO(0x51a26100), DICO(0x57d3a800), DICO(0x5d52e780),
+ DICO(0x05189860), DICO(0x07231848), DICO(0x0b915710), DICO(0x0f05d6c0),
+ DICO(0x13bb0820), DICO(0x223adf00), DICO(0x26ce1ec0), DICO(0x2ce1ac00),
+ DICO(0x3401f6c0), DICO(0x3b8c2240), DICO(0x40e4a400), DICO(0x45674f00),
+ DICO(0x4b04b880), DICO(0x4f253200), DICO(0x54168600), DICO(0x58f52780),
+ DICO(0x0338d184), DICO(0x05205790), DICO(0x09abcd80), DICO(0x0f53ff60),
+ DICO(0x1a7fe900), DICO(0x1ef93860), DICO(0x238e2d80), DICO(0x2bd81bc0),
+ DICO(0x33161240), DICO(0x368cfb80), DICO(0x3a28b5c0), DICO(0x40c7a600),
+ DICO(0x4bac7780), DICO(0x524b7880), DICO(0x58638480), DICO(0x5da07b00),
+ DICO(0x04d06f38), DICO(0x065f1518), DICO(0x0c9b31b0), DICO(0x10570d40),
+ DICO(0x15e790a0), DICO(0x20f16380), DICO(0x246f23c0), DICO(0x2e222800),
+ DICO(0x3198bf00), DICO(0x34b84640), DICO(0x38f5b440), DICO(0x4312df80),
+ DICO(0x4d2d3000), DICO(0x5209ee80), DICO(0x579cf180), DICO(0x5cb37680),
+ DICO(0x042e6560), DICO(0x05eaff30), DICO(0x0a090d30), DICO(0x0d9f2ab0),
+ DICO(0x1a6f0260), DICO(0x209e0c00), DICO(0x25dc95c0), DICO(0x29f89840),
+ DICO(0x2f372840), DICO(0x3a301940), DICO(0x3f0e2e80), DICO(0x44465c80),
+ DICO(0x49207780), DICO(0x4dfdab80), DICO(0x532ec000), DICO(0x5acefd00),
+ DICO(0x04e18ad8), DICO(0x06d5b660), DICO(0x0b2a22d0), DICO(0x0e0e4ef0),
+ DICO(0x198304a0), DICO(0x1e4a25c0), DICO(0x23de37c0), DICO(0x290679c0),
+ DICO(0x2d523b00), DICO(0x337df940), DICO(0x37948100), DICO(0x3de07300),
+ DICO(0x49ee6e80), DICO(0x50576100), DICO(0x55fb1e00), DICO(0x5d080500),
+ DICO(0x05312308), DICO(0x070463f0), DICO(0x0daffba0), DICO(0x12d8c3c0),
+ DICO(0x163ab7a0), DICO(0x20c64c40), DICO(0x24c8fe40), DICO(0x2a6f65c0),
+ DICO(0x3055e100), DICO(0x34420d80), DICO(0x389ded00), DICO(0x3cc57640),
+ DICO(0x4280cd00), DICO(0x4e0a4c00), DICO(0x57675f00), DICO(0x5d87d480),
+ DICO(0x047bd598), DICO(0x06cb1498), DICO(0x0c359930), DICO(0x138165e0),
+ DICO(0x1cae3640), DICO(0x21647640), DICO(0x2836fac0), DICO(0x2cd7b840),
+ DICO(0x30d839c0), DICO(0x360c9440), DICO(0x3ae5ca40), DICO(0x40a93b00),
+ DICO(0x49401e80), DICO(0x4f739c80), DICO(0x54f33c00), DICO(0x5c190200),
+ DICO(0x051c0000), DICO(0x06b45258), DICO(0x0a5eee50), DICO(0x0d46fc30),
+ DICO(0x125bbc60), DICO(0x253d8cc0), DICO(0x2a1fd6c0), DICO(0x2df4cf80),
+ DICO(0x3239e3c0), DICO(0x35a683c0), DICO(0x3b0bb980), DICO(0x409b3d00),
+ DICO(0x46633580), DICO(0x4f2b0600), DICO(0x577cea80), DICO(0x5d86ef00),
+ DICO(0x03d19eec), DICO(0x07cce6d0), DICO(0x143b4b00), DICO(0x1a657880),
+ DICO(0x212e0280), DICO(0x2831fbc0), DICO(0x2f8ba080), DICO(0x35db8040),
+ DICO(0x3bf17f00), DICO(0x413eb100), DICO(0x46154900), DICO(0x4ae18080),
+ DICO(0x4f9ba180), DICO(0x5428ba00), DICO(0x590e9080), DICO(0x5de0d880),
+ DICO(0x08c7e720), DICO(0x0ff14810), DICO(0x1758cc40), DICO(0x1cc744c0),
+ DICO(0x23e45cc0), DICO(0x2b527940), DICO(0x32138580), DICO(0x37b77380),
+ DICO(0x3d7da480), DICO(0x4275a800), DICO(0x473ecf00), DICO(0x4bc7dc80),
+ DICO(0x50512400), DICO(0x54d2c600), DICO(0x598ce680), DICO(0x5e1e0800),
+ DICO(0x09167910), DICO(0x107644a0), DICO(0x171a59e0), DICO(0x1be1ea60),
+ DICO(0x21347680), DICO(0x265a5b00), DICO(0x2be41a40), DICO(0x3116e700),
+ DICO(0x368b0300), DICO(0x3c225e80), DICO(0x41a6e880), DICO(0x47631680),
+ DICO(0x4d47d900), DICO(0x52a28400), DICO(0x583f0e80), DICO(0x5d77bc80),
+ DICO(0x040bdf88), DICO(0x05b062a0), DICO(0x0b4a2f70), DICO(0x1b8cd880),
+ DICO(0x1ec58c40), DICO(0x23661880), DICO(0x2790ba80), DICO(0x2d0d6c40),
+ DICO(0x34f0bc40), DICO(0x3a353f80), DICO(0x3fc3bc40), DICO(0x44998700),
+ DICO(0x49b17080), DICO(0x4f31fa00), DICO(0x55311c80), DICO(0x5b5c8f80),
+ DICO(0x043e2bd0), DICO(0x0645b0f0), DICO(0x0ade5b90), DICO(0x0d653a90),
+ DICO(0x1bc224a0), DICO(0x1f623dc0), DICO(0x27e9a840), DICO(0x2c719bc0),
+ DICO(0x2f2ac040), DICO(0x32688300), DICO(0x36695c00), DICO(0x3b8abe40),
+ DICO(0x47153a80), DICO(0x52491b00), DICO(0x57ba7680), DICO(0x5ce6c300),
+ DICO(0x052940b8), DICO(0x06f28228), DICO(0x0a741c90), DICO(0x0daa3110),
+ DICO(0x113bb2e0), DICO(0x2010b640), DICO(0x2610f380), DICO(0x2a5c7740),
+ DICO(0x2f7703c0), DICO(0x3388d080), DICO(0x3ceabe40), DICO(0x42462a80),
+ DICO(0x47fb0e00), DICO(0x4f7ac480), DICO(0x5706f580), DICO(0x5d92b800),
+ DICO(0x03a134a4), DICO(0x05623470), DICO(0x090a0fe0), DICO(0x12f7d3e0),
+ DICO(0x1d63e440), DICO(0x20e6ac80), DICO(0x247da8c0), DICO(0x27d99600),
+ DICO(0x312e99c0), DICO(0x368fb380), DICO(0x3b3e3ec0), DICO(0x40fead80),
+ DICO(0x4888fa00), DICO(0x4fbd5600), DICO(0x5795a480), DICO(0x5d973000),
+ DICO(0x05697990), DICO(0x06f33800), DICO(0x0b298290), DICO(0x0de47a60),
+ DICO(0x12ef62a0), DICO(0x21e30a00), DICO(0x25f8ff00), DICO(0x2b2287c0),
+ DICO(0x2f11fc00), DICO(0x33138000), DICO(0x37b49f80), DICO(0x41325100),
+ DICO(0x4ab62800), DICO(0x501eae80), DICO(0x56228780), DICO(0x5c5d8300),
+ DICO(0x063830d8), DICO(0x08a76a30), DICO(0x0d376890), DICO(0x117d3a00),
+ DICO(0x1476e5c0), DICO(0x1e215720), DICO(0x24bcd680), DICO(0x29674ac0),
+ DICO(0x2faab340), DICO(0x33843a00), DICO(0x3822e900), DICO(0x3d30b6c0),
+ DICO(0x49cd5480), DICO(0x53187d00), DICO(0x591fe100), DICO(0x5db30f80),
+ DICO(0x05cdc378), DICO(0x075c50c8), DICO(0x0e01f830), DICO(0x12b70480),
+ DICO(0x15e333e0), DICO(0x192c9f40), DICO(0x1d2d6b80), DICO(0x2c09ca40),
+ DICO(0x2eea5cc0), DICO(0x32c89380), DICO(0x376a5b40), DICO(0x42a42600),
+ DICO(0x4c695900), DICO(0x5269e380), DICO(0x586d6c80), DICO(0x5cebdb80),
+ DICO(0x052bbb80), DICO(0x0702e268), DICO(0x0ca196d0), DICO(0x0f48cef0),
+ DICO(0x19d28b60), DICO(0x1ec44a40), DICO(0x24d40f00), DICO(0x29e1eac0),
+ DICO(0x2cafaa80), DICO(0x301bd4c0), DICO(0x357ec200), DICO(0x42254480),
+ DICO(0x4be32000), DICO(0x4f7a4a00), DICO(0x5447fc00), DICO(0x5cca6a00),
+ DICO(0x050fdd18), DICO(0x06c77e10), DICO(0x10561140), DICO(0x1564c340),
+ DICO(0x1867abe0), DICO(0x1f00fba0), DICO(0x22c06240), DICO(0x2aed7680),
+ DICO(0x2ecc24c0), DICO(0x32abb300), DICO(0x36b42340), DICO(0x3ed8f480),
+ DICO(0x4bbdfe80), DICO(0x516bf800), DICO(0x58688b00), DICO(0x5dd44980),
+ DICO(0x058aa130), DICO(0x07d69ba8), DICO(0x0d521f40), DICO(0x0ff37ba0),
+ DICO(0x18125ec0), DICO(0x1f3a4520), DICO(0x23349840), DICO(0x2c759580),
+ DICO(0x2fc21c00), DICO(0x33a42fc0), DICO(0x3dc92900), DICO(0x47befd00),
+ DICO(0x4ccd2480), DICO(0x5197a200), DICO(0x56a2ea00), DICO(0x5bdfa900),
+ DICO(0x05ac8640), DICO(0x076aec88), DICO(0x0e2e3230), DICO(0x114b6f40),
+ DICO(0x155d10a0), DICO(0x19bac600), DICO(0x1fbd75c0), DICO(0x2459c0c0),
+ DICO(0x28229b80), DICO(0x2f586fc0), DICO(0x3d0697c0), DICO(0x42a7a500),
+ DICO(0x49b0bb80), DICO(0x4e642e80), DICO(0x55774280), DICO(0x5d1a7900),
+ DICO(0x05efb470), DICO(0x0831c8a0), DICO(0x0d35ece0), DICO(0x13edc400),
+ DICO(0x16c8fec0), DICO(0x1bb25860), DICO(0x204f3140), DICO(0x277b8a40),
+ DICO(0x2fe9a000), DICO(0x33af7c40), DICO(0x3b7d2900), DICO(0x419c9a80),
+ DICO(0x4591dc80), DICO(0x4bdafd00), DICO(0x55638880), DICO(0x5cef2300),
+ DICO(0x05cf4988), DICO(0x078fa8c0), DICO(0x0c291950), DICO(0x12e05320),
+ DICO(0x155997e0), DICO(0x195df540), DICO(0x1c1b82c0), DICO(0x22c29400),
+ DICO(0x307edec0), DICO(0x34e829c0), DICO(0x3b1b5040), DICO(0x434de400),
+ DICO(0x496b9900), DICO(0x4ff88080), DICO(0x5604c480), DICO(0x5c84b080),
+ DICO(0x03679fa4), DICO(0x050d4a20), DICO(0x09feec10), DICO(0x100a21e0),
+ DICO(0x1483b260), DICO(0x1d76c780), DICO(0x24e75c80), DICO(0x2bd62880),
+ DICO(0x32350a40), DICO(0x38be01c0), DICO(0x3f05a280), DICO(0x45295e80),
+ DICO(0x4b554800), DICO(0x51618880), DICO(0x575a1500), DICO(0x5d109d80),
+ DICO(0x034ffd08), DICO(0x04dccea8), DICO(0x07e289b8), DICO(0x0d6950d0),
+ DICO(0x189acec0), DICO(0x1e3bf240), DICO(0x2535aa40), DICO(0x2b88d140),
+ DICO(0x329bbb00), DICO(0x386c3500), DICO(0x3e950800), DICO(0x44c43f00),
+ DICO(0x4b089780), DICO(0x51223280), DICO(0x574c9780), DICO(0x5d366400),
+ DICO(0x036d8db8), DICO(0x04fd88b8), DICO(0x09700a70), DICO(0x116b73c0),
+ DICO(0x17258c40), DICO(0x1fd03000), DICO(0x23fdf400), DICO(0x28e08dc0),
+ DICO(0x32d688c0), DICO(0x37920b00), DICO(0x3daaa080), DICO(0x46a16c00),
+ DICO(0x4f8c3100), DICO(0x54a13700), DICO(0x59d24b80), DICO(0x5cea4d80),
+ DICO(0x05797c88), DICO(0x080dc8f0), DICO(0x0bd21520), DICO(0x1095b540),
+ DICO(0x138fd400), DICO(0x1aed19c0), DICO(0x29fead00), DICO(0x2f70cec0),
+ DICO(0x3327df00), DICO(0x3a812d00), DICO(0x400a8380), DICO(0x449daa00),
+ DICO(0x4cd6b600), DICO(0x51f12400), DICO(0x56bdfd80), DICO(0x5be0a100),
+ DICO(0x04de6d78), DICO(0x072aed40), DICO(0x0c6fc460), DICO(0x0f260220),
+ DICO(0x179d00c0), DICO(0x1e8244e0), DICO(0x23867240), DICO(0x2baf7680),
+ DICO(0x2fa6d240), DICO(0x37e83d40), DICO(0x3d1cbfc0), DICO(0x439d0a00),
+ DICO(0x49fd3e00), DICO(0x50095e80), DICO(0x559f2080), DICO(0x5b889a00),
+ DICO(0x042f5c10), DICO(0x061ab3e8), DICO(0x0dd8f160), DICO(0x126e0b40),
+ DICO(0x16ea9040), DICO(0x20a31700), DICO(0x24608140), DICO(0x2ec65080),
+ DICO(0x334e1a40), DICO(0x38252100), DICO(0x3fff0900), DICO(0x46519a80),
+ DICO(0x4c5e0d80), DICO(0x518c5800), DICO(0x56c5b080), DICO(0x5c6ebb80),
+ DICO(0x045ce230), DICO(0x067547b0), DICO(0x0a21c670), DICO(0x1408b820),
+ DICO(0x1c0505c0), DICO(0x1e806c80), DICO(0x26d3c640), DICO(0x2ca573c0),
+ DICO(0x3014d880), DICO(0x377108c0), DICO(0x3f35cf80), DICO(0x43566100),
+ DICO(0x4a612900), DICO(0x5160c780), DICO(0x57d3e300), DICO(0x5d414b80),
+ DICO(0x04c8eda8), DICO(0x06a32320), DICO(0x09ab2590), DICO(0x14230760),
+ DICO(0x20fb23c0), DICO(0x24aa2880), DICO(0x285a2580), DICO(0x2c464ac0),
+ DICO(0x30098280), DICO(0x36232780), DICO(0x3e428d40), DICO(0x42982280),
+ DICO(0x47e60d80), DICO(0x4e1ecc00), DICO(0x55eb9200), DICO(0x5c81ed00),
+ DICO(0x040d0b90), DICO(0x0586c5c0), DICO(0x0bea2190), DICO(0x1dc8dd60),
+ DICO(0x20a07c40), DICO(0x2437e580), DICO(0x27ca5fc0), DICO(0x2d017980),
+ DICO(0x34100040), DICO(0x38d3afc0), DICO(0x3da9b700), DICO(0x42082480),
+ DICO(0x46586f00), DICO(0x4e3c3d80), DICO(0x55e1ee00), DICO(0x5c938d00),
+ DICO(0x03d18c64), DICO(0x05941d60), DICO(0x116b2560), DICO(0x19cc8820),
+ DICO(0x1ce930c0), DICO(0x22626080), DICO(0x26d2cf80), DICO(0x2ce2c980),
+ DICO(0x305361c0), DICO(0x34b65900), DICO(0x39ee5b40), DICO(0x41508400),
+ DICO(0x47ee1e80), DICO(0x50311180), DICO(0x56cb0c00), DICO(0x5d561680),
+ DICO(0x0af22cf0), DICO(0x154e1c60), DICO(0x1b44ff60), DICO(0x2087d0c0),
+ DICO(0x252f7380), DICO(0x28fe66c0), DICO(0x2d0e9800), DICO(0x30f7ee00),
+ DICO(0x3606d640), DICO(0x3bac0a40), DICO(0x417c3700), DICO(0x470c2900),
+ DICO(0x4cc20d00), DICO(0x51e55e80), DICO(0x576bc200), DICO(0x5caa7080),
+ DICO(0x043314e0), DICO(0x05cb47b0), DICO(0x0985df20), DICO(0x185a22c0),
+ DICO(0x1ea68300), DICO(0x21af9100), DICO(0x25cdcb40), DICO(0x297e0a80),
+ DICO(0x3142ac80), DICO(0x358bb040), DICO(0x3a1345c0), DICO(0x402ca580),
+ DICO(0x4d964780), DICO(0x5420cf80), DICO(0x592adf80), DICO(0x5dfe7a80),
+ DICO(0x04c70e20), DICO(0x062fd6f0), DICO(0x113c60a0), DICO(0x159e9900),
+ DICO(0x1933e5a0), DICO(0x1decffa0), DICO(0x22373400), DICO(0x27ed7180),
+ DICO(0x2a8349c0), DICO(0x2f78f940), DICO(0x3d5c8540), DICO(0x429c3500),
+ DICO(0x4936e300), DICO(0x4de08d00), DICO(0x52627700), DICO(0x5d822680),
+ DICO(0x04982770), DICO(0x06ab1ad8), DICO(0x0cba1090), DICO(0x10839d60),
+ DICO(0x1acd6a60), DICO(0x1f554560), DICO(0x2431c1c0), DICO(0x295db800),
+ DICO(0x2d374c00), DICO(0x31f2fd80), DICO(0x3a200480), DICO(0x416bea80),
+ DICO(0x4ba1ce00), DICO(0x52a88000), DICO(0x58d0db00), DICO(0x5d3e5800),
+ DICO(0x059e0e70), DICO(0x08166ba0), DICO(0x0c9df590), DICO(0x11de5f40),
+ DICO(0x14c08ea0), DICO(0x1c5ad6e0), DICO(0x24178ec0), DICO(0x28eb7640),
+ DICO(0x31626280), DICO(0x35d43100), DICO(0x3cad10c0), DICO(0x422e1480),
+ DICO(0x49baee00), DICO(0x53dd7180), DICO(0x5a17bb80), DICO(0x5e4bb180),
+ DICO(0x03c64d00), DICO(0x05de0b28), DICO(0x0ccb82b0), DICO(0x144b1c00),
+ DICO(0x19e39ec0), DICO(0x21e795c0), DICO(0x28149380), DICO(0x2f1ff7c0),
+ DICO(0x35b7c900), DICO(0x3c5f4800), DICO(0x42799c00), DICO(0x48746180),
+ DICO(0x4e8f4d00), DICO(0x53b98380), DICO(0x58d60000), DICO(0x5d71a000),
+ DICO(0x050a2990), DICO(0x071bdb88), DICO(0x0f0d76b0), DICO(0x17a78de0),
+ DICO(0x1aa20720), DICO(0x22eea3c0), DICO(0x276e9640), DICO(0x2ecc4d80),
+ DICO(0x335f7900), DICO(0x37838640), DICO(0x3c81be80), DICO(0x41a4e400),
+ DICO(0x476fa280), DICO(0x4f2ab780), DICO(0x56e87b80), DICO(0x5cbf2900),
+ DICO(0x06724c98), DICO(0x099f5e20), DICO(0x119bcec0), DICO(0x16be11a0),
+ DICO(0x19d53b00), DICO(0x1eb51360), DICO(0x2302c300), DICO(0x29c20d40),
+ DICO(0x30dd5200), DICO(0x36576a80), DICO(0x3e3e7540), DICO(0x45aa9f80),
+ DICO(0x4c833300), DICO(0x51d7ed00), DICO(0x57a4a380), DICO(0x5cce9100),
+ DICO(0x05588b60), DICO(0x075a70a0), DICO(0x0ef96e30), DICO(0x12ac1100),
+ DICO(0x1649dde0), DICO(0x1a50cdc0), DICO(0x22486140), DICO(0x27c7c800),
+ DICO(0x2e08bd80), DICO(0x355d20c0), DICO(0x3925a9c0), DICO(0x44e2b480),
+ DICO(0x4fa4e680), DICO(0x5470e180), DICO(0x595fee80), DICO(0x5d672f00),
+ DICO(0x04a781c0), DICO(0x060a89f0), DICO(0x111f56a0), DICO(0x16b93be0),
+ DICO(0x19ce9120), DICO(0x1e1fda60), DICO(0x2259f880), DICO(0x285cad80),
+ DICO(0x2b140ec0), DICO(0x2f069940), DICO(0x33bbce40), DICO(0x3dd3e6c0),
+ DICO(0x49154880), DICO(0x5008e380), DICO(0x568c4680), DICO(0x5da43780),
+ DICO(0x053ade38), DICO(0x0708a200), DICO(0x0bad43d0), DICO(0x1860cf40),
+ DICO(0x1c40dbe0), DICO(0x1f5a0120), DICO(0x25bcf7c0), DICO(0x29e0c840),
+ DICO(0x2f223840), DICO(0x390c8940), DICO(0x3e1d7340), DICO(0x41c6a000),
+ DICO(0x46cc2880), DICO(0x5006e280), DICO(0x5744e180), DICO(0x5d297780),
+ DICO(0x0401a3f0), DICO(0x07be4a08), DICO(0x14f5f1a0), DICO(0x1c348080),
+ DICO(0x226753c0), DICO(0x274b1b80), DICO(0x2c11a300), DICO(0x30798c00),
+ DICO(0x35598c80), DICO(0x3aab18c0), DICO(0x4030f380), DICO(0x45c7b400),
+ DICO(0x4be5be00), DICO(0x5180db80), DICO(0x57613b00), DICO(0x5cffff80),
+ DICO(0x084b3090), DICO(0x0fe5b3b0), DICO(0x16dfd480), DICO(0x1d0aa700),
+ DICO(0x24e08180), DICO(0x2b498640), DICO(0x30885b80), DICO(0x34ccc480),
+ DICO(0x38fedec0), DICO(0x3cdf9c40), DICO(0x41737600), DICO(0x46ab9800),
+ DICO(0x4c772e80), DICO(0x51e5b980), DICO(0x57df9900), DICO(0x5d5d7180),
+ DICO(0x09549f00), DICO(0x12b84da0), DICO(0x1aeaf1c0), DICO(0x2142a9c0),
+ DICO(0x275c9a00), DICO(0x2c260c80), DICO(0x3038c700), DICO(0x34081d00),
+ DICO(0x38612f40), DICO(0x3d0bf8c0), DICO(0x42473e00), DICO(0x47ecad80),
+ DICO(0x4db34380), DICO(0x52f0ab00), DICO(0x584cc980), DICO(0x5d62ae80),
+ DICO(0x0aeca1e0), DICO(0x14354700), DICO(0x19955ba0), DICO(0x1de331e0),
+ DICO(0x21cd60c0), DICO(0x25e72d80), DICO(0x2a402880), DICO(0x2efa64c0),
+ DICO(0x3478d9c0), DICO(0x3a889e80), DICO(0x40744e00), DICO(0x4626fe80),
+ DICO(0x4bd80900), DICO(0x51120f00), DICO(0x56d8d280), DICO(0x5c654400),
+ DICO(0x07a40af8), DICO(0x0e65ec20), DICO(0x14c76780), DICO(0x19b35a60),
+ DICO(0x1f76b7c0), DICO(0x24f512c0), DICO(0x2ae89f00), DICO(0x3036c3c0),
+ DICO(0x36041800), DICO(0x3bc4df80), DICO(0x41adb080), DICO(0x477fbb80),
+ DICO(0x4d5aa480), DICO(0x52cb0600), DICO(0x586f7280), DICO(0x5db40180),
+ DICO(0x03997610), DICO(0x06175db0), DICO(0x0ea8c9c0), DICO(0x14397000),
+ DICO(0x1ba34f60), DICO(0x22346680), DICO(0x28958080), DICO(0x2ea76840),
+ DICO(0x33ee68c0), DICO(0x39e769c0), DICO(0x3f862500), DICO(0x4579b080),
+ DICO(0x4b49cd00), DICO(0x5107da80), DICO(0x573cde00), DICO(0x5d090780),
+ DICO(0x046fc2f8), DICO(0x0640dbc0), DICO(0x09da7ab0), DICO(0x174e4220),
+ DICO(0x23dc8cc0), DICO(0x27016200), DICO(0x2a9a5240), DICO(0x2e6cc7c0),
+ DICO(0x321ced40), DICO(0x38ca2d00), DICO(0x41482680), DICO(0x451e3700),
+ DICO(0x4b90d800), DICO(0x50d0ba80), DICO(0x55602e80), DICO(0x5a465200),
+ DICO(0x03ca7e28), DICO(0x057c9dd0), DICO(0x0c9ff0e0), DICO(0x1957fae0),
+ DICO(0x1fef7860), DICO(0x27920c80), DICO(0x2cb233c0), DICO(0x32015c80),
+ DICO(0x36af4f40), DICO(0x3ac18240), DICO(0x3f93d8c0), DICO(0x44eaef80),
+ DICO(0x4aab5d80), DICO(0x50840e80), DICO(0x56c4cc80), DICO(0x5cb26600),
+ DICO(0x038d53f8), DICO(0x050d1118), DICO(0x0bc14690), DICO(0x18918000),
+ DICO(0x1e2a6ee0), DICO(0x24cc0c00), DICO(0x2a767d40), DICO(0x2e614940),
+ DICO(0x32859c40), DICO(0x377fd940), DICO(0x3d3a3e40), DICO(0x43e81380),
+ DICO(0x4aaac080), DICO(0x509e7800), DICO(0x57023a00), DICO(0x5d733c00),
+ DICO(0x04cfa5e0), DICO(0x06deeb38), DICO(0x0a501c40), DICO(0x136d8aa0),
+ DICO(0x17f16e40), DICO(0x1c119300), DICO(0x26154b00), DICO(0x2a0da100),
+ DICO(0x2f5935c0), DICO(0x37108d40), DICO(0x3aef07c0), DICO(0x3fccf340),
+ DICO(0x47e4a080), DICO(0x4d8de100), DICO(0x54eb6980), DICO(0x5cdb5380)};
+
+/* ACELP: table for decoding
+ adaptive codebook gain g_p (left column). Scaled by 2.0f.
+ innovative codebook gain g_c (right column). Scaled by 16.0f.
+*/
+const FIXP_SGL fdk_t_qua_gain7b[128 * 2] = {
+ 204, 441, 464, 1977, 869, 1077, 1072, 3062, 1281, 4759, 1647,
+ 1539, 1845, 7020, 1853, 634, 1995, 2336, 2351, 15400, 2661, 1165,
+ 2702, 3900, 2710, 10133, 3195, 1752, 3498, 2624, 3663, 849, 3984,
+ 5697, 4214, 3399, 4415, 1304, 4695, 2056, 5376, 4558, 5386, 676,
+ 5518, 23554, 5567, 7794, 5644, 3061, 5672, 1513, 5957, 2338, 6533,
+ 1060, 6804, 5998, 6820, 1767, 6937, 3837, 7277, 414, 7305, 2665,
+ 7466, 11304, 7942, 794, 8007, 1982, 8007, 1366, 8326, 3105, 8336,
+ 4810, 8708, 7954, 8989, 2279, 9031, 1055, 9247, 3568, 9283, 1631,
+ 9654, 6311, 9811, 2605, 10120, 683, 10143, 4179, 10245, 1946, 10335,
+ 1218, 10468, 9960, 10651, 3000, 10951, 1530, 10969, 5290, 11203, 2305,
+ 11325, 3562, 11771, 6754, 11839, 1849, 11941, 4495, 11954, 1298, 11975,
+ 15223, 11977, 883, 11986, 2842, 12438, 2141, 12593, 3665, 12636, 8367,
+ 12658, 1594, 12886, 2628, 12984, 4942, 13146, 1115, 13224, 524, 13341,
+ 3163, 13399, 1923, 13549, 5961, 13606, 1401, 13655, 2399, 13782, 3909,
+ 13868, 10923, 14226, 1723, 14232, 2939, 14278, 7528, 14439, 4598, 14451,
+ 984, 14458, 2265, 14792, 1403, 14818, 3445, 14899, 5709, 15017, 15362,
+ 15048, 1946, 15069, 2655, 15405, 9591, 15405, 4079, 15570, 7183, 15687,
+ 2286, 15691, 1624, 15699, 3068, 15772, 5149, 15868, 1205, 15970, 696,
+ 16249, 3584, 16338, 1917, 16424, 2560, 16483, 4438, 16529, 6410, 16620,
+ 11966, 16839, 8780, 17030, 3050, 17033, 18325, 17092, 1568, 17123, 5197,
+ 17351, 2113, 17374, 980, 17566, 26214, 17609, 3912, 17639, 32767, 18151,
+ 7871, 18197, 2516, 18202, 5649, 18679, 3283, 18930, 1370, 19271, 13757,
+ 19317, 4120, 19460, 1973, 19654, 10018, 19764, 6792, 19912, 5135, 20040,
+ 2841, 21234, 19833};
+
+/* ACELP: factor table for interpolation of LPC coeffs in LSP domain */
+const FIXP_SGL lsp_interpol_factor[2][NB_SUBFR] = {
+ {FL2FXCONST_SGL(0.125f), FL2FXCONST_SGL(0.375f), FL2FXCONST_SGL(0.625f),
+ FL2FXCONST_SGL(0.875f)}, /* for coreCoderFrameLength = 1024 */
+ {FL2FXCONST_SGL(0.166667f), FL2FXCONST_SGL(0.5f), FL2FXCONST_SGL(0.833333f),
+ 0x0} /* for coreCoderFrameLength = 768 */
+};
+
+/* For bass post filter */
+#ifndef TABLE_filt_lp
+const FIXP_SGL fdk_dec_filt_lp[1 + L_FILT] = {
+ FL2FXCONST_SGL_FILT(0.088250f), FL2FXCONST_SGL_FILT(0.086410f),
+ FL2FXCONST_SGL_FILT(0.081074f), FL2FXCONST_SGL_FILT(0.072768f),
+ FL2FXCONST_SGL_FILT(0.062294f), FL2FXCONST_SGL_FILT(0.050623f),
+ FL2FXCONST_SGL_FILT(0.038774f), FL2FXCONST_SGL_FILT(0.027692f),
+ FL2FXCONST_SGL_FILT(0.018130f), FL2FXCONST_SGL_FILT(0.010578f),
+ FL2FXCONST_SGL_FILT(0.005221f), FL2FXCONST_SGL_FILT(0.001946f),
+ FL2FXCONST_SGL_FILT(0.000385f)};
+#endif
+
+/* FAC window tables for coreCoderFrameLength = 1024 */
+const FIXP_WTB FacWindowSynth128[] = {
+ WTC(0x7fff6216), WTC(0x7ffa72d1), WTC(0x7ff09478), WTC(0x7fe1c76b),
+ WTC(0x7fce0c3e), WTC(0x7fb563b3), WTC(0x7f97cebd), WTC(0x7f754e80),
+ WTC(0x7f4de451), WTC(0x7f2191b4), WTC(0x7ef05860), WTC(0x7eba3a39),
+ WTC(0x7e7f3957), WTC(0x7e3f57ff), WTC(0x7dfa98a8), WTC(0x7db0fdf8),
+ WTC(0x7d628ac6), WTC(0x7d0f4218), WTC(0x7cb72724), WTC(0x7c5a3d50),
+ WTC(0x7bf88830), WTC(0x7b920b89), WTC(0x7b26cb4f), WTC(0x7ab6cba4),
+ WTC(0x7a4210d8), WTC(0x79c89f6e), WTC(0x794a7c12), WTC(0x78c7aba2),
+ WTC(0x78403329), WTC(0x77b417df), WTC(0x77235f2d), WTC(0x768e0ea6),
+ WTC(0x75f42c0b), WTC(0x7555bd4c), WTC(0x74b2c884), WTC(0x740b53fb),
+ WTC(0x735f6626), WTC(0x72af05a7), WTC(0x71fa3949), WTC(0x71410805),
+ WTC(0x708378ff), WTC(0x6fc19385), WTC(0x6efb5f12), WTC(0x6e30e34a),
+ WTC(0x6d6227fa), WTC(0x6c8f351c), WTC(0x6bb812d1), WTC(0x6adcc964),
+ WTC(0x69fd614a), WTC(0x6919e320), WTC(0x683257ab), WTC(0x6746c7d8),
+ WTC(0x66573cbb), WTC(0x6563bf92), WTC(0x646c59bf), WTC(0x637114cc),
+ WTC(0x6271fa69), WTC(0x616f146c), WTC(0x60686ccf), WTC(0x5f5e0db3),
+ WTC(0x5e50015d), WTC(0x5d3e5237), WTC(0x5c290acc), WTC(0x5b1035cf),
+ WTC(0x59f3de12), WTC(0x58d40e8c), WTC(0x57b0d256), WTC(0x568a34a9),
+ WTC(0x556040e2), WTC(0x5433027d), WTC(0x53028518), WTC(0x51ced46e),
+ WTC(0x5097fc5e), WTC(0x4f5e08e3), WTC(0x4e210617), WTC(0x4ce10034),
+ WTC(0x4b9e0390), WTC(0x4a581c9e), WTC(0x490f57ee), WTC(0x47c3c22f),
+ WTC(0x46756828), WTC(0x452456bd), WTC(0x43d09aed), WTC(0x427a41d0),
+ WTC(0x4121589b), WTC(0x3fc5ec98), WTC(0x3e680b2c), WTC(0x3d07c1d6),
+ WTC(0x3ba51e29), WTC(0x3a402dd2), WTC(0x38d8fe93), WTC(0x376f9e46),
+ WTC(0x36041ad9), WTC(0x34968250), WTC(0x3326e2c3), WTC(0x31b54a5e),
+ WTC(0x3041c761), WTC(0x2ecc681e), WTC(0x2d553afc), WTC(0x2bdc4e6f),
+ WTC(0x2a61b101), WTC(0x28e5714b), WTC(0x27679df4), WTC(0x25e845b6),
+ WTC(0x24677758), WTC(0x22e541af), WTC(0x2161b3a0), WTC(0x1fdcdc1b),
+ WTC(0x1e56ca1e), WTC(0x1ccf8cb3), WTC(0x1b4732ef), WTC(0x19bdcbf3),
+ WTC(0x183366e9), WTC(0x16a81305), WTC(0x151bdf86), WTC(0x138edbb1),
+ WTC(0x120116d5), WTC(0x1072a048), WTC(0x0ee38766), WTC(0x0d53db92),
+ WTC(0x0bc3ac35), WTC(0x0a3308bd), WTC(0x08a2009a), WTC(0x0710a345),
+ WTC(0x057f0035), WTC(0x03ed26e6), WTC(0x025b26d7), WTC(0x00c90f88),
+};
+const FIXP_WTB FacWindowZir128[] = {
+ WTC(0x7f36f078), WTC(0x7da4d929), WTC(0x7c12d91a), WTC(0x7a80ffcb),
+ WTC(0x78ef5cbb), WTC(0x775dff66), WTC(0x75ccf743), WTC(0x743c53cb),
+ WTC(0x72ac246e), WTC(0x711c789a), WTC(0x6f8d5fb8), WTC(0x6dfee92b),
+ WTC(0x6c71244f), WTC(0x6ae4207a), WTC(0x6957ecfb), WTC(0x67cc9917),
+ WTC(0x6642340d), WTC(0x64b8cd11), WTC(0x6330734d), WTC(0x61a935e2),
+ WTC(0x602323e5), WTC(0x5e9e4c60), WTC(0x5d1abe51), WTC(0x5b9888a8),
+ WTC(0x5a17ba4a), WTC(0x5898620c), WTC(0x571a8eb5), WTC(0x559e4eff),
+ WTC(0x5423b191), WTC(0x52aac504), WTC(0x513397e2), WTC(0x4fbe389f),
+ WTC(0x4e4ab5a2), WTC(0x4cd91d3d), WTC(0x4b697db0), WTC(0x49fbe527),
+ WTC(0x489061ba), WTC(0x4727016d), WTC(0x45bfd22e), WTC(0x445ae1d7),
+ WTC(0x42f83e2a), WTC(0x4197f4d4), WTC(0x403a1368), WTC(0x3edea765),
+ WTC(0x3d85be30), WTC(0x3c2f6513), WTC(0x3adba943), WTC(0x398a97d8),
+ WTC(0x383c3dd1), WTC(0x36f0a812), WTC(0x35a7e362), WTC(0x3461fc70),
+ WTC(0x331effcc), WTC(0x31def9e9), WTC(0x30a1f71d), WTC(0x2f6803a2),
+ WTC(0x2e312b92), WTC(0x2cfd7ae8), WTC(0x2bccfd83), WTC(0x2a9fbf1e),
+ WTC(0x2975cb57), WTC(0x284f2daa), WTC(0x272bf174), WTC(0x260c21ee),
+ WTC(0x24efca31), WTC(0x23d6f534), WTC(0x22c1adc9), WTC(0x21affea3),
+ WTC(0x20a1f24d), WTC(0x1f979331), WTC(0x1e90eb94), WTC(0x1d8e0597),
+ WTC(0x1c8eeb34), WTC(0x1b93a641), WTC(0x1a9c406e), WTC(0x19a8c345),
+ WTC(0x18b93828), WTC(0x17cda855), WTC(0x16e61ce0), WTC(0x16029eb6),
+ WTC(0x1523369c), WTC(0x1447ed2f), WTC(0x1370cae4), WTC(0x129dd806),
+ WTC(0x11cf1cb6), WTC(0x1104a0ee), WTC(0x103e6c7b), WTC(0x0f7c8701),
+ WTC(0x0ebef7fb), WTC(0x0e05c6b7), WTC(0x0d50fa59), WTC(0x0ca099da),
+ WTC(0x0bf4ac05), WTC(0x0b4d377c), WTC(0x0aaa42b4), WTC(0x0a0bd3f5),
+ WTC(0x0971f15a), WTC(0x08dca0d3), WTC(0x084be821), WTC(0x07bfccd7),
+ WTC(0x0738545e), WTC(0x06b583ee), WTC(0x06376092), WTC(0x05bdef28),
+ WTC(0x0549345c), WTC(0x04d934b1), WTC(0x046df477), WTC(0x040777d0),
+ WTC(0x03a5c2b0), WTC(0x0348d8dc), WTC(0x02f0bde8), WTC(0x029d753a),
+ WTC(0x024f0208), WTC(0x02056758), WTC(0x01c0a801), WTC(0x0180c6a9),
+ WTC(0x0145c5c7), WTC(0x010fa7a0), WTC(0x00de6e4c), WTC(0x00b21baf),
+ WTC(0x008ab180), WTC(0x00683143), WTC(0x004a9c4d), WTC(0x0031f3c2),
+ WTC(0x001e3895), WTC(0x000f6b88), WTC(0x00058d2f), WTC(0x00009dea),
+};
+const FIXP_WTB FacWindowSynth64[] = {
+ WTC(0x7ffd885a), WTC(0x7fe9cbc0), WTC(0x7fc25596), WTC(0x7f872bf3),
+ WTC(0x7f3857f6), WTC(0x7ed5e5c6), WTC(0x7e5fe493), WTC(0x7dd6668f),
+ WTC(0x7d3980ec), WTC(0x7c894bde), WTC(0x7bc5e290), WTC(0x7aef6323),
+ WTC(0x7a05eead), WTC(0x7909a92d), WTC(0x77fab989), WTC(0x76d94989),
+ WTC(0x75a585cf), WTC(0x745f9dd1), WTC(0x7307c3d0), WTC(0x719e2cd2),
+ WTC(0x7023109a), WTC(0x6e96a99d), WTC(0x6cf934fc), WTC(0x6b4af279),
+ WTC(0x698c246c), WTC(0x67bd0fbd), WTC(0x65ddfbd3), WTC(0x63ef3290),
+ WTC(0x61f1003f), WTC(0x5fe3b38d), WTC(0x5dc79d7c), WTC(0x5b9d1154),
+ WTC(0x59646498), WTC(0x571deefa), WTC(0x54ca0a4b), WTC(0x5269126e),
+ WTC(0x4ffb654d), WTC(0x4d8162c4), WTC(0x4afb6c98), WTC(0x4869e665),
+ WTC(0x45cd358f), WTC(0x4325c135), WTC(0x4073f21d), WTC(0x3db832a6),
+ WTC(0x3af2eeb7), WTC(0x382493b0), WTC(0x354d9057), WTC(0x326e54c7),
+ WTC(0x2f875262), WTC(0x2c98fbba), WTC(0x29a3c485), WTC(0x26a82186),
+ WTC(0x23a6887f), WTC(0x209f701c), WTC(0x1d934fe5), WTC(0x1a82a026),
+ WTC(0x176dd9de), WTC(0x145576b1), WTC(0x1139f0cf), WTC(0x0e1bc2e4),
+ WTC(0x0afb6805), WTC(0x07d95b9e), WTC(0x04b6195d), WTC(0x01921d20),
+};
+const FIXP_WTB FacWindowZir64[] = {
+ WTC(0x7e6de2e0), WTC(0x7b49e6a3), WTC(0x7826a462), WTC(0x750497fb),
+ WTC(0x71e43d1c), WTC(0x6ec60f31), WTC(0x6baa894f), WTC(0x68922622),
+ WTC(0x657d5fda), WTC(0x626cb01b), WTC(0x5f608fe4), WTC(0x5c597781),
+ WTC(0x5957de7a), WTC(0x565c3b7b), WTC(0x53670446), WTC(0x5078ad9e),
+ WTC(0x4d91ab39), WTC(0x4ab26fa9), WTC(0x47db6c50), WTC(0x450d1149),
+ WTC(0x4247cd5a), WTC(0x3f8c0de3), WTC(0x3cda3ecb), WTC(0x3a32ca71),
+ WTC(0x3796199b), WTC(0x35049368), WTC(0x327e9d3c), WTC(0x30049ab3),
+ WTC(0x2d96ed92), WTC(0x2b35f5b5), WTC(0x28e21106), WTC(0x269b9b68),
+ WTC(0x2462eeac), WTC(0x22386284), WTC(0x201c4c73), WTC(0x1e0effc1),
+ WTC(0x1c10cd70), WTC(0x1a22042d), WTC(0x1842f043), WTC(0x1673db94),
+ WTC(0x14b50d87), WTC(0x1306cb04), WTC(0x11695663), WTC(0x0fdcef66),
+ WTC(0x0e61d32e), WTC(0x0cf83c30), WTC(0x0ba0622f), WTC(0x0a5a7a31),
+ WTC(0x0926b677), WTC(0x08054677), WTC(0x06f656d3), WTC(0x05fa1153),
+ WTC(0x05109cdd), WTC(0x043a1d70), WTC(0x0376b422), WTC(0x02c67f14),
+ WTC(0x02299971), WTC(0x01a01b6d), WTC(0x012a1a3a), WTC(0x00c7a80a),
+ WTC(0x0078d40d), WTC(0x003daa6a), WTC(0x00163440), WTC(0x000277a6),
+};
+const FIXP_WTB FacWindowSynth32[] = {
+ WTC(0x7ff62182), WTC(0x7fa736b4), WTC(0x7f0991c4), WTC(0x7e1d93ea),
+ WTC(0x7ce3ceb2), WTC(0x7b5d039e), WTC(0x798a23b1), WTC(0x776c4edb),
+ WTC(0x7504d345), WTC(0x72552c85), WTC(0x6f5f02b2), WTC(0x6c242960),
+ WTC(0x68a69e81), WTC(0x64e88926), WTC(0x60ec3830), WTC(0x5cb420e0),
+ WTC(0x5842dd54), WTC(0x539b2af0), WTC(0x4ebfe8a5), WTC(0x49b41533),
+ WTC(0x447acd50), WTC(0x3f1749b8), WTC(0x398cdd32), WTC(0x33def287),
+ WTC(0x2e110a62), WTC(0x2826b928), WTC(0x2223a4c5), WTC(0x1c0b826a),
+ WTC(0x15e21445), WTC(0x0fab272b), WTC(0x096a9049), WTC(0x03242abf),
+};
+const FIXP_WTB FacWindowZir32[] = {
+ WTC(0x7cdbd541), WTC(0x76956fb7), WTC(0x7054d8d5), WTC(0x6a1debbb),
+ WTC(0x63f47d96), WTC(0x5ddc5b3b), WTC(0x57d946d8), WTC(0x51eef59e),
+ WTC(0x4c210d79), WTC(0x467322ce), WTC(0x40e8b648), WTC(0x3b8532b0),
+ WTC(0x364beacd), WTC(0x3140175b), WTC(0x2c64d510), WTC(0x27bd22ac),
+ WTC(0x234bdf20), WTC(0x1f13c7d0), WTC(0x1b1776da), WTC(0x1759617f),
+ WTC(0x13dbd6a0), WTC(0x10a0fd4e), WTC(0x0daad37b), WTC(0x0afb2cbb),
+ WTC(0x0893b125), WTC(0x0675dc4f), WTC(0x04a2fc62), WTC(0x031c314e),
+ WTC(0x01e26c16), WTC(0x00f66e3c), WTC(0x0058c94c), WTC(0x0009de7e),
+};
+
+/* FAC window tables for coreCoderFrameLength = 768 */
+const FIXP_WTB FacWindowSynth96[] = {
+ WTC(0x7ffee744), WTC(0x7ff62182), WTC(0x7fe49698), WTC(0x7fca47b9),
+ WTC(0x7fa736b4), WTC(0x7f7b65ef), WTC(0x7f46d86c), WTC(0x7f0991c4),
+ WTC(0x7ec3962a), WTC(0x7e74ea6a), WTC(0x7e1d93ea), WTC(0x7dbd98a4),
+ WTC(0x7d54ff2e), WTC(0x7ce3ceb2), WTC(0x7c6a0ef2), WTC(0x7be7c847),
+ WTC(0x7b5d039e), WTC(0x7ac9ca7a), WTC(0x7a2e26f2), WTC(0x798a23b1),
+ WTC(0x78ddcbf5), WTC(0x78292b8d), WTC(0x776c4edb), WTC(0x76a742d1),
+ WTC(0x75da14ef), WTC(0x7504d345), WTC(0x74278c72), WTC(0x73424fa0),
+ WTC(0x72552c85), WTC(0x71603361), WTC(0x706374ff), WTC(0x6f5f02b2),
+ WTC(0x6e52ee52), WTC(0x6d3f4a40), WTC(0x6c242960), WTC(0x6b019f1a),
+ WTC(0x69d7bf57), WTC(0x68a69e81), WTC(0x676e5183), WTC(0x662eedc3),
+ WTC(0x64e88926), WTC(0x639b3a0b), WTC(0x62471749), WTC(0x60ec3830),
+ WTC(0x5f8ab487), WTC(0x5e22a487), WTC(0x5cb420e0), WTC(0x5b3f42ae),
+ WTC(0x59c42381), WTC(0x5842dd54), WTC(0x56bb8a90), WTC(0x552e4605),
+ WTC(0x539b2af0), WTC(0x520254ef), WTC(0x5063e008), WTC(0x4ebfe8a5),
+ WTC(0x4d168b8b), WTC(0x4b67e5e4), WTC(0x49b41533), WTC(0x47fb3757),
+ WTC(0x463d6a87), WTC(0x447acd50), WTC(0x42b37e96), WTC(0x40e79d8c),
+ WTC(0x3f1749b8), WTC(0x3d42a2ec), WTC(0x3b69c947), WTC(0x398cdd32),
+ WTC(0x37abff5d), WTC(0x35c750bc), WTC(0x33def287), WTC(0x31f30638),
+ WTC(0x3003ad85), WTC(0x2e110a62), WTC(0x2c1b3efb), WTC(0x2a226db5),
+ WTC(0x2826b928), WTC(0x26284422), WTC(0x2427319d), WTC(0x2223a4c5),
+ WTC(0x201dc0ef), WTC(0x1e15a99a), WTC(0x1c0b826a), WTC(0x19ff6f2a),
+ WTC(0x17f193c5), WTC(0x15e21445), WTC(0x13d114d0), WTC(0x11beb9aa),
+ WTC(0x0fab272b), WTC(0x0d9681c2), WTC(0x0b80edf1), WTC(0x096a9049),
+ WTC(0x07538d6b), WTC(0x053c0a01), WTC(0x03242abf), WTC(0x010c1460),
+};
+const FIXP_WTB FacWindowZir96[] = {
+ WTC(0x7ef3eba0), WTC(0x7cdbd541), WTC(0x7ac3f5ff), WTC(0x78ac7295),
+ WTC(0x76956fb7), WTC(0x747f120f), WTC(0x72697e3e), WTC(0x7054d8d5),
+ WTC(0x6e414656), WTC(0x6c2eeb30), WTC(0x6a1debbb), WTC(0x680e6c3b),
+ WTC(0x660090d6), WTC(0x63f47d96), WTC(0x61ea5666), WTC(0x5fe23f11),
+ WTC(0x5ddc5b3b), WTC(0x5bd8ce63), WTC(0x59d7bbde), WTC(0x57d946d8),
+ WTC(0x55dd924b), WTC(0x53e4c105), WTC(0x51eef59e), WTC(0x4ffc527b),
+ WTC(0x4e0cf9c8), WTC(0x4c210d79), WTC(0x4a38af44), WTC(0x485400a3),
+ WTC(0x467322ce), WTC(0x449636b9), WTC(0x42bd5d14), WTC(0x40e8b648),
+ WTC(0x3f186274), WTC(0x3d4c816a), WTC(0x3b8532b0), WTC(0x39c29579),
+ WTC(0x3804c8a9), WTC(0x364beacd), WTC(0x34981a1c), WTC(0x32e97475),
+ WTC(0x3140175b), WTC(0x2f9c1ff8), WTC(0x2dfdab11), WTC(0x2c64d510),
+ WTC(0x2ad1b9fb), WTC(0x29447570), WTC(0x27bd22ac), WTC(0x263bdc7f),
+ WTC(0x24c0bd52), WTC(0x234bdf20), WTC(0x21dd5b79), WTC(0x20754b79),
+ WTC(0x1f13c7d0), WTC(0x1db8e8b7), WTC(0x1c64c5f5), WTC(0x1b1776da),
+ WTC(0x19d1123d), WTC(0x1891ae7d), WTC(0x1759617f), WTC(0x162840a9),
+ WTC(0x14fe60e6), WTC(0x13dbd6a0), WTC(0x12c0b5c0), WTC(0x11ad11ae),
+ WTC(0x10a0fd4e), WTC(0x0f9c8b01), WTC(0x0e9fcc9f), WTC(0x0daad37b),
+ WTC(0x0cbdb060), WTC(0x0bd8738e), WTC(0x0afb2cbb), WTC(0x0a25eb11),
+ WTC(0x0958bd2f), WTC(0x0893b125), WTC(0x07d6d473), WTC(0x0722340b),
+ WTC(0x0675dc4f), WTC(0x05d1d90e), WTC(0x05363586), WTC(0x04a2fc62),
+ WTC(0x041837b9), WTC(0x0395f10e), WTC(0x031c314e), WTC(0x02ab00d2),
+ WTC(0x0242675c), WTC(0x01e26c16), WTC(0x018b1596), WTC(0x013c69d6),
+ WTC(0x00f66e3c), WTC(0x00b92794), WTC(0x00849a11), WTC(0x0058c94c),
+ WTC(0x0035b847), WTC(0x001b6968), WTC(0x0009de7e), WTC(0x000118bc),
+};
+const FIXP_WTB FacWindowSynth48[] = {
+ WTC(0x7ffb9d15), WTC(0x7fd8878e), WTC(0x7f92661d), WTC(0x7f294bfd),
+ WTC(0x7e9d55fc), WTC(0x7deeaa7a), WTC(0x7d1d7958), WTC(0x7c29fbee),
+ WTC(0x7b1474fd), WTC(0x79dd3098), WTC(0x78848414), WTC(0x770acdec),
+ WTC(0x757075ac), WTC(0x73b5ebd1), WTC(0x71dba9ab), WTC(0x6fe2313c),
+ WTC(0x6dca0d14), WTC(0x6b93d02e), WTC(0x694015c3), WTC(0x66cf8120),
+ WTC(0x6442bd7e), WTC(0x619a7dce), WTC(0x5ed77c8a), WTC(0x5bfa7b82),
+ WTC(0x590443a7), WTC(0x55f5a4d2), WTC(0x52cf758f), WTC(0x4f9292dc),
+ WTC(0x4c3fdff4), WTC(0x48d84609), WTC(0x455cb40c), WTC(0x41ce1e65),
+ WTC(0x3e2d7eb1), WTC(0x3a7bd382), WTC(0x36ba2014), WTC(0x32e96c09),
+ WTC(0x2f0ac320), WTC(0x2b1f34eb), WTC(0x2727d486), WTC(0x2325b847),
+ WTC(0x1f19f97b), WTC(0x1b05b40f), WTC(0x16ea0646), WTC(0x12c8106f),
+ WTC(0x0ea0f48c), WTC(0x0a75d60e), WTC(0x0647d97c), WTC(0x02182427),
+};
+const FIXP_WTB FacWindowZir48[] = {
+ WTC(0x7de7dbd9), WTC(0x79b82684), WTC(0x758a29f2), WTC(0x715f0b74),
+ WTC(0x6d37ef91), WTC(0x6915f9ba), WTC(0x64fa4bf1), WTC(0x60e60685),
+ WTC(0x5cda47b9), WTC(0x58d82b7a), WTC(0x54e0cb15), WTC(0x50f53ce0),
+ WTC(0x4d1693f7), WTC(0x4945dfec), WTC(0x45842c7e), WTC(0x41d2814f),
+ WTC(0x3e31e19b), WTC(0x3aa34bf4), WTC(0x3727b9f7), WTC(0x33c0200c),
+ WTC(0x306d6d24), WTC(0x2d308a71), WTC(0x2a0a5b2e), WTC(0x26fbbc59),
+ WTC(0x2405847e), WTC(0x21288376), WTC(0x1e658232), WTC(0x1bbd4282),
+ WTC(0x19307ee0), WTC(0x16bfea3d), WTC(0x146c2fd2), WTC(0x1235f2ec),
+ WTC(0x101dcec4), WTC(0x0e245655), WTC(0x0c4a142f), WTC(0x0a8f8a54),
+ WTC(0x08f53214), WTC(0x077b7bec), WTC(0x0622cf68), WTC(0x04eb8b03),
+ WTC(0x03d60412), WTC(0x02e286a8), WTC(0x02115586), WTC(0x0162aa04),
+ WTC(0x00d6b403), WTC(0x006d99e3), WTC(0x00277872), WTC(0x000462eb),
+};
diff --git a/fdk-aac/libAACdec/src/usacdec_rom.h b/fdk-aac/libAACdec/src/usacdec_rom.h
new file mode 100644
index 0000000..f969e90
--- /dev/null
+++ b/fdk-aac/libAACdec/src/usacdec_rom.h
@@ -0,0 +1,154 @@
+/* -----------------------------------------------------------------------------
+Software License for The Fraunhofer FDK AAC Codec Library for Android
+
+© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
+Forschung e.V. All rights reserved.
+
+ 1. INTRODUCTION
+The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
+that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
+scheme for digital audio. This FDK AAC Codec software is intended to be used on
+a wide variety of Android devices.
+
+AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
+general perceptual audio codecs. AAC-ELD is considered the best-performing
+full-bandwidth communications codec by independent studies and is widely
+deployed. AAC has been standardized by ISO and IEC as part of the MPEG
+specifications.
+
+Patent licenses for necessary patent claims for the FDK AAC Codec (including
+those of Fraunhofer) may be obtained through Via Licensing
+(www.vialicensing.com) or through the respective patent owners individually for
+the purpose of encoding or decoding bit streams in products that are compliant
+with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
+Android devices already license these patent claims through Via Licensing or
+directly from the patent owners, and therefore FDK AAC Codec software may
+already be covered under those patent licenses when it is used for those
+licensed purposes only.
+
+Commercially-licensed AAC software libraries, including floating-point versions
+with enhanced sound quality, are also available from Fraunhofer. Users are
+encouraged to check the Fraunhofer website for additional applications
+information and documentation.
+
+2. COPYRIGHT LICENSE
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted without payment of copyright license fees provided that you
+satisfy the following conditions:
+
+You must retain the complete text of this software license in redistributions of
+the FDK AAC Codec or your modifications thereto in source code form.
+
+You must retain the complete text of this software license in the documentation
+and/or other materials provided with redistributions of the FDK AAC Codec or
+your modifications thereto in binary form. You must make available free of
+charge copies of the complete source code of the FDK AAC Codec and your
+modifications thereto to recipients of copies in binary form.
+
+The name of Fraunhofer may not be used to endorse or promote products derived
+from this library without prior written permission.
+
+You may not charge copyright license fees for anyone to use, copy or distribute
+the FDK AAC Codec software or your modifications thereto.
+
+Your modified versions of the FDK AAC Codec must carry prominent notices stating
+that you changed the software and the date of any change. For modified versions
+of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
+must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
+AAC Codec Library for Android."
+
+3. NO PATENT LICENSE
+
+NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
+limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
+Fraunhofer provides no warranty of patent non-infringement with respect to this
+software.
+
+You may use this FDK AAC Codec software or modifications thereto only for
+purposes that are authorized by appropriate patent licenses.
+
+4. DISCLAIMER
+
+This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
+holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
+including but not limited to the implied warranties of merchantability and
+fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
+or consequential damages, including but not limited to procurement of substitute
+goods or services; loss of use, data, or profits, or business interruption,
+however caused and on any theory of liability, whether in contract, strict
+liability, or tort (including negligence), arising in any way out of the use of
+this software, even if advised of the possibility of such damage.
+
+5. CONTACT INFORMATION
+
+Fraunhofer Institute for Integrated Circuits IIS
+Attention: Audio and Multimedia Departments - FDK AAC LL
+Am Wolfsmantel 33
+91058 Erlangen, Germany
+
+www.iis.fraunhofer.de/amm
+amm-info@iis.fraunhofer.de
+----------------------------------------------------------------------------- */
+
+/**************************** AAC decoder library ******************************
+
+ Author(s): M. Jander
+
+ Description: re8.h
+
+*******************************************************************************/
+
+#ifndef USACDEC_ROM_H
+#define USACDEC_ROM_H
+
+#include "common_fix.h"
+#include "FDK_lpc.h"
+
+#include "usacdec_const.h"
+
+/* RE8 lattice quantiser constants */
+#define NB_SPHERE 32
+#define NB_LEADER 37
+#define NB_LDSIGN 226
+#define NB_LDQ3 9
+#define NB_LDQ4 28
+
+#define LSF_SCALE 13
+
+/* RE8 lattice quantiser tables */
+extern const UINT fdk_dec_tab_factorial[8];
+extern const UCHAR fdk_dec_Ia[NB_LEADER];
+extern const UCHAR fdk_dec_Ds[NB_LDSIGN];
+extern const USHORT fdk_dec_Is[NB_LDSIGN];
+extern const UCHAR fdk_dec_Ns[], fdk_dec_A3[], fdk_dec_A4[];
+extern const UCHAR fdk_dec_Da[][8];
+extern const USHORT fdk_dec_I3[], fdk_dec_I4[];
+
+/* temp float tables for LPC decoding */
+extern const FIXP_LPC fdk_dec_lsf_init[16];
+extern const FIXP_LPC fdk_dec_dico_lsf_abs_8b[16 * 256];
+
+/* ACELP tables */
+#define SF_QUA_GAIN7B 4
+extern const FIXP_SGL fdk_t_qua_gain7b[128 * 2];
+extern const FIXP_SGL lsp_interpol_factor[2][NB_SUBFR];
+
+/* For bass post filter */
+#define L_FILT 12 /* Delay of up-sampling filter */
+
+extern const FIXP_SGL fdk_dec_filt_lp[1 + L_FILT];
+
+extern const FIXP_WTB FacWindowSynth128[128];
+extern const FIXP_WTB FacWindowZir128[128];
+extern const FIXP_WTB FacWindowSynth64[64];
+extern const FIXP_WTB FacWindowZir64[64];
+extern const FIXP_WTB FacWindowSynth32[32];
+extern const FIXP_WTB FacWindowZir32[32];
+extern const FIXP_WTB FacWindowSynth96[96];
+extern const FIXP_WTB FacWindowZir96[96];
+extern const FIXP_WTB FacWindowSynth48[48];
+extern const FIXP_WTB FacWindowZir48[48];
+
+#endif /* USACDEC_ROM_H */