diff options
Diffstat (limited to 'libAACdec')
64 files changed, 29912 insertions, 13258 deletions
diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index 7ab60f1..e811d04 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,13 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Manuel Jander -******************************************************************************/ + Description: + +*******************************************************************************/ + +#ifndef AACDECODER_LIB_H +#define AACDECODER_LIB_H /** * \file aacdecoder_lib.h @@ -94,166 +110,261 @@ amm-info@iis.fraunhofer.de \page INTRO Introduction + \section SCOPE Scope -This document describes the high-level interface and usage of the ISO/MPEG-2/4 AAC Decoder -library developed by the Fraunhofer Institute for Integrated Circuits (IIS). -Depending on the library configuration, it implements decoding of AAC-LC (Low-Complexity), -HE-AAC (High-Efficiency AAC, v1 and v2), AAC-LD (Low-Delay) and AAC-ELD (Enhanced Low-Delay). +This document describes the high-level application interface and usage of the +ISO/MPEG-2/4 AAC Decoder library developed by the Fraunhofer Institute for +Integrated Circuits (IIS). Depending on the library configuration, decoding of +AAC-LC (Low-Complexity), HE-AAC (High-Efficiency AAC v1 and v2), AAC-LD +(Low-Delay) and AAC-ELD (Enhanced Low-Delay) is implemented. -All references to SBR (Spectral Band Replication) are only applicable to HE-AAC and AAC-ELD -versions of the library. All references to PS (Parametric Stereo) are only applicable to -HE-AAC v2 versions of the library. +All references to SBR (Spectral Band Replication) are only applicable to HE-AAC +and AAC-ELD configurations of the FDK library. All references to PS (Parametric +Stereo) are only applicable to HE-AAC v2 decoder configuration of the library. \section DecoderBasics Decoder Basics -This document can only give a rough overview about the ISO/MPEG-2 and ISO/MPEG-4 AAC audio -coding standard. To understand all the terms in this document, you are encouraged to read -the following documents. - -- ISO/IEC 13818-7 (MPEG-2 AAC), which defines the syntax of MPEG-2 AAC audio bitstreams. -- ISO/IEC 14496-3 (MPEG-4 AAC, subpart 1 and 4), which defines the syntax of MPEG-4 AAC audio bitstreams. -- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec delay", 116th AES Convention, May 8, 2004 - -MPEG Advanced Audio Coding is based on a time-to-frequency mapping of the signal. The signal -is partitioned into overlapping portions and transformed into frequency domain. The spectral -components are then quantized and coded.\n -An MPEG2 or MPEG4 AAC audio bitstream is composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3), -the length of individual frames is not restricted to a fixed number of bytes, but can take on -any length between 1 and 768 bytes. +This document can only give a rough overview about the ISO/MPEG-2, ISO/MPEG-4 +AAC audio and MPEG-D USAC coding standards. To understand all details referenced +in this document, you are encouraged to read the following documents. + +- ISO/IEC 13818-7 (MPEG-2 AAC) Standard, defines the syntax of MPEG-2 AAC audio +bitstreams. +- ISO/IEC 14496-3 (MPEG-4 AAC, subpart 1 and 4) Standard, defines the syntax of +MPEG-4 AAC audio bitstreams. +- ISO/IEC 23003-3 (MPEG-D USAC), defines MPEG-D USAC unified speech and audio +codec. +- Lutzky, Schuller, Gayer, Krämer, Wabnik, "A guideline to audio codec +delay", 116th AES Convention, May 8, 2004 + +In short, MPEG Advanced Audio Coding is based on a time-to-frequency mapping of +the signal. The signal is partitioned into overlapping time portions and +transformed into frequency domain. The spectral components are then quantized +and coded using a highly efficient coding scheme.\n Encoded MPEG-2 and MPEG-4 +AAC audio bitstreams are composed of frames. Contrary to MPEG-1/2 Layer-3 (mp3), +the length of individual frames is not restricted to a fixed number of bytes, +but can take any length between 1 and 768 bytes. + +In addition to the above mentioned frequency domain coding mode, MPEG-D USAC +also employs a time domain Algebraic Code-Excited Linear Prediction (ACELP) +speech coder core. This operating mode is selected by the encoder in order to +achieve the optimum audio quality for different content type. Several +enhancements allow achieving higher quality at lower bit rates compared to +MPEG-4 HE-AAC. \page LIBUSE Library Usage + \section InterfaceDescritpion API Description -All API header files are located in the folder /include of the release package. They are described in -detail in this document. All header files are provided for usage in C/C++ programs. The AAC decoder library -API functions are located at aacdecoder_lib.h. +All API header files are located in the folder /include of the release package. +The contents of each file is described in detail in this document. All header +files are provided for usage in specific C/C++ programs. The main AAC decoder +library API functions are located in aacdecoder_lib.h header file. + +In binary releases the decoder core resides in statically linkable libraries, +for example libAACdec.a. -In binary releases the decoder core resides in statically linkable libraries called for example libAACdec.a, -(Linux) or FDK_aacDec_lib (Microsoft Visual C++). \section Calling_Sequence Calling Sequence -For decoding of ISO/MPEG-2/4 AAC or HE-AAC v2 bitstreams the following sequence is mandatory. Input read -and output write functions as well as the corresponding open and close functions are left out, since they -may be implemented differently according to the user's specific requirements. The example implementation in -main.cpp uses file-based input/output, and in such case call mpegFileRead_Open() to open an input file and -to allocate memory for the required structures, and the corresponding mpegFileRead_Close() to close opened -files and to de-allocate associated structures. mpegFileRead_Open() tries to detect the bitstream format and -in case of MPEG-4 file format or Raw Packets file format (a Fraunhofer IIS proprietary format) reads the Audio -Specific Config data (ASC). An unsuccessful attempt to recognize the bitstream format requires the user to -provide this information manually. For any other bitstream formats that are usually applicable in streaming -applications, the decoder itself will try to synchronize and parse the given bitstream fragment using the -FDK transport library. Hence, for streaming applications (without file access) this step is not necessary. - --# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder instance. -\dontinclude main.cpp -\skipline aacDecoder_Open --# If out-of-band config data (Audio Specific Config (ASC) or Stream Mux Config (SMC)) is available, call -aacDecoder_ConfigRaw() to pass it to the decoder and before the decoding process starts. If this data is -not available in advance, the decoder will get it from the bitstream and configure itself while decoding -with aacDecoder_DecodeFrame(). +The following sequence is necessary for proper decoding of ISO/MPEG-2/4 AAC, +HE-AAC v2, or MPEG-D USAC bitstreams. In the following description, input stream +read and output write function details are left out, since they may be +implemented in a variety of configurations depending on the user's specific +requirements. The example implementation uses file-based input/output, and in +such case one may call mpegFileRead_Open() to open an input file and to allocate +memory for the required structures, and the corresponding mpegFileRead_Close() +to close opened files and to de-allocate associated structures. +mpegFileRead_Open() will attempt to detect the bitstream format and in case of +MPEG-4 file format or Raw Packets file format (a proprietary Fraunhofer IIS file +format suitable only for testing) it will read the Audio Specific Config data +(ASC). An unsuccessful attempt to recognize the bitstream format requires the +user to provide this information manually. For any other bitstream formats that +are usually applicable in streaming applications, the decoder itself will try to +synchronize and parse the given bitstream fragment using the FDK transport +library. Hence, for streaming applications (without file access) this step is +not necessary. + + +-# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder +instance. \code aacDecoderInfo = aacDecoder_Open(transportType, nrOfLayers); +\endcode +-# If out-of-band config data (Audio Specific Config (ASC) or Stream Mux Config +(SMC)) is available, call aacDecoder_ConfigRaw() to pass this data to the +decoder before beginning the decoding process. If this data is not available in +advance, the decoder will configure itself while decoding, during the +aacDecoder_DecodeFrame() function call. -# Begin decoding loop. -\skipline do { --# Read data from bitstream file or stream into a client-supplied input buffer ("inBuffer" in main.cpp). -If it is very small like just 4, aacDecoder_DecodeFrame() will -repeatedly return ::AAC_DEC_NOT_ENOUGH_BITS until enough bits were fed by aacDecoder_Fill(). Only read data -when this buffer has completely been processed and is then empty. For file-based input execute -mpegFileRead_Read() or any other implementation with similar functionality. --# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer with the client-supplied -external bitstream input buffer. -\skipline aacDecoder_Fill --# Call aacDecoder_DecodeFrame() which writes decoded PCM audio data to a client-supplied buffer. It is the -client's responsibility to allocate a buffer which is large enough to hold this output data. -\skipline aacDecoder_DecodeFrame -If the bitstream's configuration (number of channels, sample rate, frame size) is not known in advance, you may -call aacDecoder_GetStreamInfo() to retrieve a structure containing this information and then initialize an audio -output device. In the example main.cpp, if the number of channels or the sample rate has changed since program -start or since the previously decoded frame, the audio output device will be re-initialized. If WAVE file output -is chosen, a new WAVE file for each new configuration will be created. -\skipline aacDecoder_GetStreamInfo --# Repeat steps 5 to 7 until no data to decode is available anymore, or if an error occured. -\skipline } while --# Call aacDecoder_Close() to de-allocate all AAC decoder and transport layer structures. -\skipline aacDecoder_Close +\code +do { +\endcode +-# Read data from bitstream file or stream buffer in to the driver program +working memory (a client-supplied input buffer "inBuffer" in framework). This +buffer will be used to load AAC bitstream data to the decoder. Only when all +data in this buffer has been processed will the decoder signal an empty buffer. +For file-based input, you may invoke mpegFileRead_Read() to acquire new +bitstream data. +-# Call aacDecoder_Fill() to fill the decoder's internal bitstream input buffer +with the client-supplied bitstream input buffer. Note, if the data loaded in to +the internal buffer is not sufficient to decode a frame, +aacDecoder_DecodeFrame() will return ::AAC_DEC_NOT_ENOUGH_BITS until a +sufficient amount of data is loaded in to the internal buffer. For streaming +formats (ADTS, LOAS), it is acceptable to load more than one frame to the +decoder. However, for RAW file format (Fraunhofer IIS proprietary format), only +one frame may be loaded to the decoder per aacDecoder_DecodeFrame() call. For +least amount of communication delay, fill and decode should be performed on a +frame by frame basis. \code ErrorStatus = aacDecoder_Fill(aacDecoderInfo, +inBuffer, bytesRead, bytesValid); \endcode +-# Call aacDecoder_DecodeFrame(). This function decodes one frame and writes +decoded PCM audio data to a client-supplied buffer. It is the client's +responsibility to allocate a buffer which is large enough to hold the decoded +output data. \code ErrorStatus = aacDecoder_DecodeFrame(aacDecoderInfo, +TimeData, OUT_BUF_SIZE, flags); \endcode If the bitstream configuration (number +of channels, sample rate, frame size) is not known a priori, you may call +aacDecoder_GetStreamInfo() to retrieve a structure that contains this +information. You may use this data to initialize an audio output device. In the +example program, if the number of channels or the sample rate has changed since +program start or the previously decoded frame, the audio output device is then +re-initialized. If WAVE file output is chosen, a new WAVE file for each new +stream configuration is be created. \code p_si = +aacDecoder_GetStreamInfo(aacDecoderInfo); \endcode +-# Repeat steps 5 to 7 until no data is available to decode any more, or in case +of error. \code } while (bytesRead[0] > 0 || doFlush || doBsFlush || +forceContinue); \endcode +-# Call aacDecoder_Close() to de-allocate all AAC decoder and transport layer +structures. \code aacDecoder_Close(aacDecoderInfo); \endcode + +\image latex decode.png "Decode calling sequence" width=11cm + +\image latex change_source.png "Change data source sequence" width 5cm + +\image latex conceal.png "Error concealment sequence" width=14cm + +\subsection Error_Concealment_Sequence Error Concealment Sequence + +There are different strategies to handle bit stream errors. Depending on the +system properties the product designer might choose to take different actions in +case a bit error occurs. In many cases the decoder might be able to do +reasonable error concealment without the need of any additional actions from the +system. But in some cases its not even possible to know how many decoded PCM +output samples are required to fill the gap due to the data error, then the +software surrounding the decoder must deal with the situation. The most simple +way would be to just stop audio playback and resume once enough bit stream data +and/or buffered output samples are available. More sophisticated designs might +also be able to deal with sender/receiver clock drifts or data drop outs by +using a closed loop control of FIFO fulness levels. The chosen strategy depends +on the final product requirements. + +The error concealment sequence diagram illustrates the general execution paths +for error handling. + +The macro IS_OUTPUT_VALID(err) can be used to identify if the audio output +buffer contains valid audio either from error free bit stream data or successful +error concealment. In case the result is false, the decoder output buffer does +not contain meaningful audio samples and should not be passed to any output as +it is. Most likely in case that a continuous audio output PCM stream is +required, the output buffer must be filled with audio data from the calling +framework. This might be e.g. an appropriate number of samples all zero. + +If error code ::AAC_DEC_TRANSPORT_SYNC_ERROR is returned by the decoder, under +some particular conditions it is possible to estimate lost frames due to the bit +stream error. In that case the bit stream is required to have a constant +bitrate, and compatible transport type. Audio samples for the lost frames can be +obtained by calling aacDecoder_DecodeFrame() with flag ::AACDEC_CONCEAL set +n-times where n is the count of lost frames. Please note that the decoder has to +have encountered valid configuration data at least once to be able to generate +concealed data, because at the minimum the sampling rate, frame size and amount +of audio channels needs to be known. + +If it is not possible to get an estimation of lost frames then a constant +fullness of the audio output buffer can be achieved by implementing different +FIFO control techniques e.g. just stop taking of samples from the buffer to +avoid underflow or stop filling new data to the buffer to avoid overflow. But +this techniques are out of scope of this document. + +For a detailed description of a specific error code please refer also to +::AAC_DECODER_ERROR. \section BufferSystem Buffer System -There are three main buffers in an AAC decoder application. One external input buffer to hold bitstream -data from file I/O or elsewhere, one decoder-internal input buffer, and one to hold the decoded output -PCM sample data, whereas this output buffer may overlap with the external input buffer. - -The external input buffer is set in the example framework main.cpp and its size is defined by ::IN_BUF_SIZE. -You may freely choose different sizes here. To feed the data to the decoder-internal input buffer, use the -function aacDecoder_Fill(). This function returns important information about how many bytes in the -external input buffer have not yet been copied into the internal input buffer (variable bytesValid). -Once the external buffer has been fully copied, it can be re-filled again. -In case you want to re-fill it when there are still unprocessed bytes (bytesValid is unequal 0), you -would have to additionally perform a memcpy(), so that just means unnecessary computational overhead -and therefore we recommend to re-fill the buffer only when bytesValid is 0. - -\image latex dec_buffer.png "Lifecycle of the external input buffer" width=9cm - -The size of the decoder-internal input buffer is set in tpdec_lib.h (see define ::TRANSPORTDEC_INBUF_SIZE). -You may choose a smaller size under the following considerations: - -- each input channel requires 768 bytes -- the whole buffer must be of size 2^n - -So for example a stereo decoder: - -\f[ -TRANSPORTDEC\_INBUF\_SIZE = 2 * 768 = 1536 => 2048 -\f] - -tpdec_lib.h and TRANSPORTDEC_INBUF_SIZE are not part of the decoder's library interface. Therefore -only source-code clients may change this setting. If you received a library release, please ask us and -we can change this in order to meet your memory requirements. +There are three main buffers in an AAC decoder application. One external input +buffer to hold bitstream data from file I/O or elsewhere, one decoder-internal +input buffer, and one to hold the decoded output PCM sample data. In resource +limited applications, the output buffer may be reused as an external input +buffer prior to the subsequence aacDecoder_Fill() function call. + +The external input buffer is set in the example program and its size is defined +by ::IN_BUF_SIZE. You may freely choose different buffer sizes. To feed the data +to the decoder-internal input buffer, use the function aacDecoder_Fill(). This +function returns important information regarding the number of bytes in the +external input buffer that have not yet been copied into the internal input +buffer (variable bytesValid). Once the external buffer has been fully copied, it +can be completely re-filled again. In case you wish to refill the buffer while +there are unprocessed bytes (bytesValid is unequal 0), you should preserve the +unconsumed data. However, we recommend to refill the buffer only when bytesValid +returns 0. + +The bytesValid parameter is an input and output parameter to the FDK decoder. As +an input, it signals how many valid bytes are available in the external buffer. +After consumption of the external buffer using aacDecoder_Fill() function, the +bytesValid parameter indicates if any of the bytes in the external buffer were +not consumed. + +\image latex dec_buffer.png "Life cycle of the external input buffer" width=9cm \page OutputFormat Decoder audio output \section OutputFormatObtaining Obtaining channel mapping information -The decoded audio output format is indicated by a set of variables of the CStreamInfo structure. -While the members sampleRate, frameSize and numChannels might be quite self explaining, -pChannelType and pChannelIndices might require some more detailed explanation. +The decoded audio output format is indicated by a set of variables of the +CStreamInfo structure. While the struct members sampleRate, frameSize and +numChannels might be self explanatory, pChannelType and pChannelIndices require +some further explanation. -These two arrays indicate what is each output channel supposed to be. Both array have -CStreamInfo::numChannels cells. Each cell of pChannelType indicates the channel type, described in -the enum ::AUDIO_CHANNEL_TYPE defined in FDK_audio.h. The cells of pChannelIndices indicate the sub index -among the channels starting with 0 among all channels of the same audio channel type. +These two arrays indicate the configuration of channel data within the output +buffer. Both arrays have CStreamInfo::numChannels number of cells. Each cell of +pChannelType indicates the channel type, which is described in the enum +::AUDIO_CHANNEL_TYPE (defined in FDK_audio.h). The cells of pChannelIndices +indicate the sub index among the channels starting with 0 among channels of the +same audio channel type. -The indexing scheme is the same as for MPEG-2/4. Thus indices are counted upwards starting from the front -direction (thus a center channel if any, will always be index 0). Then the indices count up, starting always -with the left side, pairwise from front toward back. For detailed explanation, please refer to -ISO/IEC 13818-7:2005(E), chapter 8.5.3.2. +The indexing scheme is structured as defined in MPEG-2/4 Standards. Indices +start from the front direction (a center channel if available, will always be +index 0) and increment, starting with the left side, pairwise (e.g. L, R) and +from front to back (Front L, Front R, Surround L, Surround R). For detailed +explanation, please refer to ISO/IEC 13818-7:2005(E), chapter 8.5.3.2. -In case a Program Config is included in the audio configuration, the channel mapping described within -it will be adopted. +In case a Program Config is included in the audio configuration, the channel +mapping described within it will be adopted. -In case of MPEG-D Surround the channel mapping will follow the same criteria described in ISO/IEC 13818-7:2005(E), -but adding corresponding top channels to the channel types front, side and back, in order to avoid any -loss of information. +In case of MPEG-D Surround the channel mapping will follow the same criteria +described in ISO/IEC 13818-7:2005(E), but adding corresponding top channels (if +available) to the channel types in order to avoid ambiguity. The examples below +explain these aspects in detail. \section OutputFormatChange Changing the audio output format -The channel interleaving scheme and the actual channel order can be changed at runtime through the -parameters ::AAC_PCM_OUTPUT_INTERLEAVED and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING. See the description of those -parameters and the decoder library function aacDecoder_SetParam() for more detail. +For MPEG-4 audio the channel order can be changed at runtime through the +parameter +::AAC_PCM_OUTPUT_CHANNEL_MAPPING. See the description of those +parameters and the decoder library function aacDecoder_SetParam() for more +detail. \section OutputFormatExample Channel mapping examples -The following examples illustrate the location of individual audio samples in the audio buffer that -is passed to aacDecoder_DecodeFrame() and the expected data in the CStreamInfo structure which can be obtained -by calling aacDecoder_GetStreamInfo(). +The following examples illustrate the location of individual audio samples in +the audio buffer that is passed to aacDecoder_DecodeFrame() and the expected +data in the CStreamInfo structure which can be obtained by calling +aacDecoder_GetStreamInfo(). \subsection ExamplesStereo Stereo -In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 0 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, -a AAC-LC bit stream which has channelConfiguration = 2 in its audio specific config would lead -to the following values in CStreamInfo: +In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +a AAC-LC bit stream which has channelConfiguration = 2 in its audio specific +config would lead to the following values in CStreamInfo: CStreamInfo::numChannels = 2 @@ -261,8 +372,7 @@ CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT } CStreamInfo::pChannelIndices = { 0, 1 } -Since ::AAC_PCM_OUTPUT_INTERLEAVED is set to 0, the audio channels will be located as contiguous blocks -in the output buffer as follows: +The output buffer will be formatted as follows: \verbatim <left sample 0> <left sample 1> <left sample 2> ... <left sample N> @@ -273,25 +383,27 @@ Where N equals to CStreamInfo::frameSize . \subsection ExamplesSurround Surround 5.1 -In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 1 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, -a AAC-LC bit stream which has channelConfiguration = 6 in its audio specific config, would lead -to the following values in CStreamInfo: +In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +a AAC-LC bit stream which has channelConfiguration = 6 in its audio specific +config, would lead to the following values in CStreamInfo: CStreamInfo::numChannels = 6 -CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_FRONT, ::ACT_LFE, ::ACT_BACK, ::ACT_BACK } +CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_FRONT, ::ACT_LFE, +::ACT_BACK, ::ACT_BACK } CStreamInfo::pChannelIndices = { 1, 2, 0, 0, 0, 1 } -Since ::AAC_PCM_OUTPUT_CHANNEL_MAPPING is 1, WAV file channel ordering will be used. For a 5.1 channel -scheme, thus the channels would be: front left, front right, center, LFE, surround left, surround right. -Thus the third channel is the center channel, receiving the index 0. The other front channels are -front left, front right being placed as first and second channels with indices 1 and 2 correspondingly. -There is only one LFE, placed as the fourth channel and index 0. Finally both surround -channels get the type definition ACT_BACK, and the indices 0 and 1. +Since ::AAC_PCM_OUTPUT_CHANNEL_MAPPING is 1, WAV file channel ordering will be +used. For a 5.1 channel scheme, thus the channels would be: front left, front +right, center, LFE, surround left, surround right. Thus the third channel is the +center channel, receiving the index 0. The other front channels are front left, +front right being placed as first and second channels with indices 1 and 2 +correspondingly. There is only one LFE, placed as the fourth channel and index +0. Finally both surround channels get the type definition ACT_BACK, and the +indices 0 and 1. -Since ::AAC_PCM_OUTPUT_INTERLEAVED is set to 1, the audio channels will be placed in the output buffer -as follows: +The output buffer will be formatted as follows: \verbatim <front left sample 0> <front right sample 0> @@ -313,13 +425,14 @@ Where N equals to CStreamInfo::frameSize . \subsection ExamplesArib ARIB coding mode 2/1 -In case of ::AAC_PCM_OUTPUT_INTERLEAVED set to 1 and ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, -in case of a ARIB bit stream using coding mode 2/1 as described in ARIB STD-B32 Part 2 Version 2.1-E1, page 61, -would lead to the following values in CStreamInfo: +In case of ::AAC_PCM_OUTPUT_CHANNEL_MAPPING set to 1, +in case of a ARIB bit stream using coding mode 2/1 as described in ARIB STD-B32 +Part 2 Version 2.1-E1, page 61, would lead to the following values in +CStreamInfo: CStreamInfo::numChannels = 3 -CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT,:: ACT_BACK } +CStreamInfo::pChannelType = { ::ACT_FRONT, ::ACT_FRONT, ::ACT_BACK } CStreamInfo::pChannelIndices = { 0, 1, 0 } @@ -340,260 +453,449 @@ Where N equals to CStreamInfo::frameSize . */ -#ifndef AACDECODER_LIB_H -#define AACDECODER_LIB_H - #include "machine_type.h" #include "FDK_audio.h" #include "genericStds.h" - /** * \brief AAC decoder error codes. */ typedef enum { - AAC_DEC_OK = 0x0000, /*!< No error occured. Output buffer is valid and error free. */ - AAC_DEC_OUT_OF_MEMORY = 0x0002, /*!< Heap returned NULL pointer. Output buffer is invalid. */ - AAC_DEC_UNKNOWN = 0x0005, /*!< Error condition is of unknown reason, or from a another module. Output buffer is invalid. */ + AAC_DEC_OK = + 0x0000, /*!< No error occurred. Output buffer is valid and error free. */ + AAC_DEC_OUT_OF_MEMORY = + 0x0002, /*!< Heap returned NULL pointer. Output buffer is invalid. */ + AAC_DEC_UNKNOWN = + 0x0005, /*!< Error condition is of unknown reason, or from a another + module. Output buffer is invalid. */ /* Synchronization errors. Output buffer is invalid. */ - aac_dec_sync_error_start = 0x1000, - AAC_DEC_TRANSPORT_SYNC_ERROR = 0x1001, /*!< The transport decoder had syncronisation problems. Do not exit decoding. Just feed new - bitstream data. */ - AAC_DEC_NOT_ENOUGH_BITS = 0x1002, /*!< The input buffer ran out of bits. */ - aac_dec_sync_error_end = 0x1FFF, + aac_dec_sync_error_start = 0x1000, + AAC_DEC_TRANSPORT_SYNC_ERROR = 0x1001, /*!< The transport decoder had + synchronization problems. Do not + exit decoding. Just feed new + bitstream data. */ + AAC_DEC_NOT_ENOUGH_BITS = 0x1002, /*!< The input buffer ran out of bits. */ + aac_dec_sync_error_end = 0x1FFF, /* Initialization errors. Output buffer is invalid. */ - aac_dec_init_error_start = 0x2000, - AAC_DEC_INVALID_HANDLE = 0x2001, /*!< The handle passed to the function call was invalid (NULL). */ - AAC_DEC_UNSUPPORTED_AOT = 0x2002, /*!< The AOT found in the configuration is not supported. */ - AAC_DEC_UNSUPPORTED_FORMAT = 0x2003, /*!< The bitstream format is not supported. */ - AAC_DEC_UNSUPPORTED_ER_FORMAT = 0x2004, /*!< The error resilience tool format is not supported. */ - AAC_DEC_UNSUPPORTED_EPCONFIG = 0x2005, /*!< The error protection format is not supported. */ - AAC_DEC_UNSUPPORTED_MULTILAYER = 0x2006, /*!< More than one layer for AAC scalable is not supported. */ - AAC_DEC_UNSUPPORTED_CHANNELCONFIG = 0x2007, /*!< The channel configuration (either number or arrangement) is not supported. */ - AAC_DEC_UNSUPPORTED_SAMPLINGRATE = 0x2008, /*!< The sample rate specified in the configuration is not supported. */ - AAC_DEC_INVALID_SBR_CONFIG = 0x2009, /*!< The SBR configuration is not supported. */ - AAC_DEC_SET_PARAM_FAIL = 0x200A, /*!< The parameter could not be set. Either the value was out of range or the parameter does - not exist. */ - AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, since the requiered configuration change cannot be - performed. */ - AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = 0x200C, /*!< The provided output buffer is too small. */ - aac_dec_init_error_end = 0x2FFF, + aac_dec_init_error_start = 0x2000, + AAC_DEC_INVALID_HANDLE = + 0x2001, /*!< The handle passed to the function call was invalid (NULL). */ + AAC_DEC_UNSUPPORTED_AOT = + 0x2002, /*!< The AOT found in the configuration is not supported. */ + AAC_DEC_UNSUPPORTED_FORMAT = + 0x2003, /*!< The bitstream format is not supported. */ + AAC_DEC_UNSUPPORTED_ER_FORMAT = + 0x2004, /*!< The error resilience tool format is not supported. */ + AAC_DEC_UNSUPPORTED_EPCONFIG = + 0x2005, /*!< The error protection format is not supported. */ + AAC_DEC_UNSUPPORTED_MULTILAYER = + 0x2006, /*!< More than one layer for AAC scalable is not supported. */ + AAC_DEC_UNSUPPORTED_CHANNELCONFIG = + 0x2007, /*!< The channel configuration (either number or arrangement) is + not supported. */ + AAC_DEC_UNSUPPORTED_SAMPLINGRATE = 0x2008, /*!< The sample rate specified in + the configuration is not + supported. */ + AAC_DEC_INVALID_SBR_CONFIG = + 0x2009, /*!< The SBR configuration is not supported. */ + AAC_DEC_SET_PARAM_FAIL = 0x200A, /*!< The parameter could not be set. Either + the value was out of range or the + parameter does not exist. */ + AAC_DEC_NEED_TO_RESTART = 0x200B, /*!< The decoder needs to be restarted, + since the required configuration change + cannot be performed. */ + AAC_DEC_OUTPUT_BUFFER_TOO_SMALL = + 0x200C, /*!< The provided output buffer is too small. */ + aac_dec_init_error_end = 0x2FFF, /* Decode errors. Output buffer is valid but concealed. */ - aac_dec_decode_error_start = 0x4000, - AAC_DEC_TRANSPORT_ERROR = 0x4001, /*!< The transport decoder encountered an unexpected error. */ - AAC_DEC_PARSE_ERROR = 0x4002, /*!< Error while parsing the bitstream. Most probably it is corrupted, or the system crashed. */ - AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD = 0x4003, /*!< Error while parsing the extension payload of the bitstream. The extension payload type - found is not supported. */ - AAC_DEC_DECODE_FRAME_ERROR = 0x4004, /*!< The parsed bitstream value is out of range. Most probably the bitstream is corrupt, or - the system crashed. */ - AAC_DEC_CRC_ERROR = 0x4005, /*!< The embedded CRC did not match. */ - AAC_DEC_INVALID_CODE_BOOK = 0x4006, /*!< An invalid codebook was signalled. Most probably the bitstream is corrupt, or the system - crashed. */ - AAC_DEC_UNSUPPORTED_PREDICTION = 0x4007, /*!< Predictor found, but not supported in the AAC Low Complexity profile. Most probably the - bitstream is corrupt, or has a wrong format. */ - AAC_DEC_UNSUPPORTED_CCE = 0x4008, /*!< A CCE element was found which is not supported. Most probably the bitstream is corrupt, or - has a wrong format. */ - AAC_DEC_UNSUPPORTED_LFE = 0x4009, /*!< A LFE element was found which is not supported. Most probably the bitstream is corrupt, or - has a wrong format. */ - AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA = 0x400A, /*!< Gain control data found but not supported. Most probably the bitstream is corrupt, or has - a wrong format. */ - AAC_DEC_UNSUPPORTED_SBA = 0x400B, /*!< SBA found, but currently not supported in the BSAC profile. */ - AAC_DEC_TNS_READ_ERROR = 0x400C, /*!< Error while reading TNS data. Most probably the bitstream is corrupt or the system - crashed. */ - AAC_DEC_RVLC_ERROR = 0x400D, /*!< Error while decoding error resillient data. */ - aac_dec_decode_error_end = 0x4FFF, - + aac_dec_decode_error_start = 0x4000, + AAC_DEC_TRANSPORT_ERROR = + 0x4001, /*!< The transport decoder encountered an unexpected error. */ + AAC_DEC_PARSE_ERROR = 0x4002, /*!< Error while parsing the bitstream. Most + probably it is corrupted, or the system + crashed. */ + AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD = + 0x4003, /*!< Error while parsing the extension payload of the bitstream. + The extension payload type found is not supported. */ + AAC_DEC_DECODE_FRAME_ERROR = 0x4004, /*!< The parsed bitstream value is out of + range. Most probably the bitstream is + corrupt, or the system crashed. */ + AAC_DEC_CRC_ERROR = 0x4005, /*!< The embedded CRC did not match. */ + AAC_DEC_INVALID_CODE_BOOK = 0x4006, /*!< An invalid codebook was signaled. + Most probably the bitstream is corrupt, + or the system crashed. */ + AAC_DEC_UNSUPPORTED_PREDICTION = + 0x4007, /*!< Predictor found, but not supported in the AAC Low Complexity + profile. Most probably the bitstream is corrupt, or has a wrong + format. */ + AAC_DEC_UNSUPPORTED_CCE = 0x4008, /*!< A CCE element was found which is not + supported. Most probably the bitstream is + corrupt, or has a wrong format. */ + AAC_DEC_UNSUPPORTED_LFE = 0x4009, /*!< A LFE element was found which is not + supported. Most probably the bitstream is + corrupt, or has a wrong format. */ + AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA = + 0x400A, /*!< Gain control data found but not supported. Most probably the + bitstream is corrupt, or has a wrong format. */ + AAC_DEC_UNSUPPORTED_SBA = + 0x400B, /*!< SBA found, but currently not supported in the BSAC profile. + */ + AAC_DEC_TNS_READ_ERROR = 0x400C, /*!< Error while reading TNS data. Most + probably the bitstream is corrupt or the + system crashed. */ + AAC_DEC_RVLC_ERROR = + 0x400D, /*!< Error while decoding error resilient data. */ + aac_dec_decode_error_end = 0x4FFF, /* Ancillary data errors. Output buffer is valid. */ - aac_dec_anc_data_error_start = 0x8000, - AAC_DEC_ANC_DATA_ERROR = 0x8001, /*!< Non severe error concerning the ancillary data handling. */ - AAC_DEC_TOO_SMALL_ANC_BUFFER = 0x8002, /*!< The registered ancillary data buffer is too small to receive the parsed data. */ - AAC_DEC_TOO_MANY_ANC_ELEMENTS = 0x8003, /*!< More than the allowed number of ancillary data elements should be written to buffer. */ - aac_dec_anc_data_error_end = 0x8FFF - + aac_dec_anc_data_error_start = 0x8000, + AAC_DEC_ANC_DATA_ERROR = + 0x8001, /*!< Non severe error concerning the ancillary data handling. */ + AAC_DEC_TOO_SMALL_ANC_BUFFER = 0x8002, /*!< The registered ancillary data + buffer is too small to receive the + parsed data. */ + AAC_DEC_TOO_MANY_ANC_ELEMENTS = 0x8003, /*!< More than the allowed number of + ancillary data elements should be + written to buffer. */ + aac_dec_anc_data_error_end = 0x8FFF } AAC_DECODER_ERROR; +/** Macro to identify initialization errors. Output buffer is invalid. */ +#define IS_INIT_ERROR(err) \ + ((((err) >= aac_dec_init_error_start) && ((err) <= aac_dec_init_error_end)) \ + ? 1 \ + : 0) +/** Macro to identify decode errors. Output buffer is valid but concealed. */ +#define IS_DECODE_ERROR(err) \ + ((((err) >= aac_dec_decode_error_start) && \ + ((err) <= aac_dec_decode_error_end)) \ + ? 1 \ + : 0) +/** + * Macro to identify if the audio output buffer contains valid samples after + * calling aacDecoder_DecodeFrame(). Output buffer is valid but can be + * concealed. + */ +#define IS_OUTPUT_VALID(err) (((err) == AAC_DEC_OK) || IS_DECODE_ERROR(err)) -/** Macro to identify initialization errors. */ -#define IS_INIT_ERROR(err) ( (((err)>=aac_dec_init_error_start) && ((err)<=aac_dec_init_error_end)) ? 1 : 0) -/** Macro to identify decode errors. */ -#define IS_DECODE_ERROR(err) ( (((err)>=aac_dec_decode_error_start) && ((err)<=aac_dec_decode_error_end)) ? 1 : 0) -/** Macro to identify if the audio output buffer contains valid samples after calling aacDecoder_DecodeFrame(). */ -#define IS_OUTPUT_VALID(err) ( ((err) == AAC_DEC_OK) || IS_DECODE_ERROR(err) ) +/*! \enum AAC_MD_PROFILE + * \brief The available metadata profiles which are mostly related to downmixing. The values define the arguments + * for the use with parameter ::AAC_METADATA_PROFILE. + */ +typedef enum { + AAC_MD_PROFILE_MPEG_STANDARD = + 0, /*!< The standard profile creates a mixdown signal based on the + advanced downmix metadata (from a DSE). The equations and default + values are defined in ISO/IEC 14496:3 Ammendment 4. Any other + (legacy) downmix metadata will be ignored. No other parameter will + be modified. */ + AAC_MD_PROFILE_MPEG_LEGACY = + 1, /*!< This profile behaves identical to the standard profile if advanced + downmix metadata (from a DSE) is available. If not, the + matrix_mixdown information embedded in the program configuration + element (PCE) will be applied. If neither is the case, the module + creates a mixdown using the default coefficients as defined in + ISO/IEC 14496:3 AMD 4. The profile can be used to support legacy + digital TV (e.g. DVB) streams. */ + AAC_MD_PROFILE_MPEG_LEGACY_PRIO = + 2, /*!< Similar to the ::AAC_MD_PROFILE_MPEG_LEGACY profile but if both + the advanced (ISO/IEC 14496:3 AMD 4) and the legacy (PCE) MPEG + downmix metadata are available the latter will be applied. + */ + AAC_MD_PROFILE_ARIB_JAPAN = + 3 /*!< Downmix creation as described in ABNT NBR 15602-2. But if advanced + downmix metadata (ISO/IEC 14496:3 AMD 4) is available it will be + preferred because of the higher resolutions. In addition the + metadata expiry time will be set to the value defined in the ARIB + standard (see ::AAC_METADATA_EXPIRY_TIME). + */ +} AAC_MD_PROFILE; + +/*! \enum AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS + * \brief Options for handling of DRC parameters, if presentation mode is not indicated in bitstream + */ +typedef enum { + AAC_DRC_PARAMETER_HANDLING_DISABLED = -1, /*!< DRC parameter handling + disabled, all parameters are + applied as requested. */ + AAC_DRC_PARAMETER_HANDLING_ENABLED = + 0, /*!< Apply changes to requested DRC parameters to prevent clipping. */ + AAC_DRC_PRESENTATION_MODE_1_DEFAULT = + 1, /*!< Use DRC presentation mode 1 as default (e.g. for Nordig) */ + AAC_DRC_PRESENTATION_MODE_2_DEFAULT = + 2 /*!< Use DRC presentation mode 2 as default (e.g. for DTG DBook) */ +} AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS; /** * \brief AAC decoder setting parameters */ -typedef enum -{ - AAC_PCM_OUTPUT_INTERLEAVED = 0x0000, /*!< PCM output mode (1: interleaved (default); 0: not interleaved). */ - AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE = 0x0002, /*!< Defines how the decoder processes two channel signals: \n - 0: Leave both signals as they are (default). \n - 1: Create a dual mono output signal from channel 1. \n - 2: Create a dual mono output signal from channel 2. \n - 3: Create a dual mono output signal by mixing both channels (L' = R' = 0.5*Ch1 + 0.5*Ch2). */ - AAC_PCM_OUTPUT_CHANNEL_MAPPING = 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: WAV file channel order (default). */ - AAC_PCM_LIMITER_ENABLE = 0x0004, /*!< Enable signal level limiting. \n - -1: Auto-config. Enable limiter for all non-lowdelay configurations by default. \n - 0: Disable limiter in general. \n - 1: Enable limiter always. - It is recommended to call the decoder with a AACDEC_CLRHIST flag to reset all states when - the limiter switch is changed explicitly. */ - AAC_PCM_LIMITER_ATTACK_TIME = 0x0005, /*!< Signal level limiting attack time in ms. - Default confguration is 15 ms. Adjustable range from 1 ms to 15 ms. */ - AAC_PCM_LIMITER_RELEAS_TIME = 0x0006, /*!< Signal level limiting release time in ms. - Default configuration is 50 ms. Adjustable time must be larger than 0 ms. */ - AAC_PCM_MIN_OUTPUT_CHANNELS = 0x0011, /*!< Minimum number of PCM output channels. If higher than the number of encoded audio channels, - a simple channel extension is applied. \n - -1, 0: Disable channel extenstion feature. The decoder output contains the same number of - channels as the encoded bitstream. \n - 1: This value is currently needed only together with the mix-down feature. See - ::AAC_PCM_MAX_OUTPUT_CHANNELS and note 2 below. \n - 2: Encoded mono signals will be duplicated to achieve a 2/0/0.0 channel output - configuration. \n - 6: The decoder trys to reorder encoded signals with less than six channels to achieve - a 3/0/2.1 channel output signal. Missing channels will be filled with a zero signal. - If reordering is not possible the empty channels will simply be appended. Only - available if instance is configured to support multichannel output. \n - 8: The decoder trys to reorder encoded signals with less than eight channels to - achieve a 3/0/4.1 channel output signal. Missing channels will be filled with a - zero signal. If reordering is not possible the empty channels will simply be - appended. Only available if instance is configured to support multichannel output.\n - NOTE: \n - 1. The channel signalling (CStreamInfo::pChannelType and CStreamInfo::pChannelIndices) - will not be modified. Added empty channels will be signalled with channel type - AUDIO_CHANNEL_TYPE::ACT_NONE. \n - 2. If the parameter value is greater than that of ::AAC_PCM_MAX_OUTPUT_CHANNELS both will - be set to the same value. \n - 3. This parameter does not affect MPEG Surround processing. */ - AAC_PCM_MAX_OUTPUT_CHANNELS = 0x0012, /*!< Maximum number of PCM output channels. If lower than the number of encoded audio channels, - downmixing is applied accordingly. If dedicated metadata is available in the stream it - will be used to achieve better mixing results. \n - -1, 0: Disable downmixing feature. The decoder output contains the same number of channels - as the encoded bitstream. \n - 1: All encoded audio configurations with more than one channel will be mixed down to - one mono output signal. \n - 2: The decoder performs a stereo mix-down if the number encoded audio channels is - greater than two. \n - 6: If the number of encoded audio channels is greater than six the decoder performs a - mix-down to meet the target output configuration of 3/0/2.1 channels. Only - available if instance is configured to support multichannel output. \n - 8: This value is currently needed only together with the channel extension feature. - See ::AAC_PCM_MIN_OUTPUT_CHANNELS and note 2 below. Only available if instance is - configured to support multichannel output. \n - NOTE: \n - 1. Down-mixing of any seven or eight channel configuration not defined in ISO/IEC 14496-3 - PDAM 4 is not supported by this software version. \n - 2. If the parameter value is greater than zero but smaller than ::AAC_PCM_MIN_OUTPUT_CHANNELS - both will be set to same value. \n - 3. The operating mode of the MPEG Surround module will be set accordingly. \n - 4. Setting this param with any value will disable the binaural processing of the MPEG - Surround module (::AAC_MPEGS_BINAURAL_ENABLE=0). */ - - AAC_CONCEAL_METHOD = 0x0100, /*!< Error concealment: Processing method. \n - 0: Spectral muting. \n - 1: Noise substitution (see ::CONCEAL_NOISE). \n - 2: Energy interpolation (adds additional signal delay of one frame, see ::CONCEAL_INTER). \n */ - - AAC_DRC_BOOST_FACTOR = 0x0200, /*!< Dynamic Range Control: Scaling factor for boosting gain values. - Defines how the boosting DRC factors (conveyed in the bitstream) will be applied to the - decoded signal. The valid values range from 0 (don't apply boost factors) to 127 (fully - apply all boosting factors). */ - AAC_DRC_ATTENUATION_FACTOR = 0x0201, /*!< Dynamic Range Control: Scaling factor for attenuating gain values. Same as - AAC_DRC_BOOST_FACTOR but for attenuating DRC factors. */ - AAC_DRC_REFERENCE_LEVEL = 0x0202, /*!< Dynamic Range Control: Target reference level. Defines the level below full-scale - (quantized in steps of 0.25dB) to which the output audio signal will be normalized to by - the DRC module. The valid values range from 0 (full-scale) to 127 (31.75 dB below - full-scale). The value smaller than 0 switches off normalization. */ - AAC_DRC_HEAVY_COMPRESSION = 0x0203, /*!< Dynamic Range Control: En-/Disable DVB specific heavy compression (aka RF mode). - If set to 1, the decoder will apply the compression values from the DVB specific ancillary - data field. At the same time the MPEG-4 Dynamic Range Control tool will be disabled. By - default heavy compression is disabled. */ - - AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing mode. \n - -1: Use internal default. Implies MPEG Surround partially complex accordingly. \n - 0: Use complex QMF data mode. \n - 1: Use real (low power) QMF data mode. \n */ - - AAC_MPEGS_ENABLE = 0x0500, /*!< MPEG Surround: Allow/Disable decoding of MPS content. Available only for decoders with MPEG - Surround support. */ - - AAC_TPDEC_CLEAR_BUFFER = 0x0603 /*!< Clear internal bit stream buffer of transport layers. The decoder will start decoding - at new data passed after this event and any previous data is discarded. */ +typedef enum { + AAC_PCM_DUAL_CHANNEL_OUTPUT_MODE = + 0x0002, /*!< Defines how the decoder processes two channel signals: \n + 0: Leave both signals as they are (default). \n + 1: Create a dual mono output signal from channel 1. \n + 2: Create a dual mono output signal from channel 2. \n + 3: Create a dual mono output signal by mixing both channels + (L' = R' = 0.5*Ch1 + 0.5*Ch2). */ + AAC_PCM_OUTPUT_CHANNEL_MAPPING = + 0x0003, /*!< Output buffer channel ordering. 0: MPEG PCE style order, 1: + WAV file channel order (default). */ + AAC_PCM_LIMITER_ENABLE = + 0x0004, /*!< Enable signal level limiting. \n + -1: Auto-config. Enable limiter for all + non-lowdelay configurations by default. \n + 0: Disable limiter in general. \n + 1: Enable limiter always. + It is recommended to call the decoder + with a AACDEC_CLRHIST flag to reset all + states when the limiter switch is changed + explicitly. */ + AAC_PCM_LIMITER_ATTACK_TIME = 0x0005, /*!< Signal level limiting attack time + in ms. Default configuration is 15 + ms. Adjustable range from 1 ms to 15 + ms. */ + AAC_PCM_LIMITER_RELEAS_TIME = 0x0006, /*!< Signal level limiting release time + in ms. Default configuration is 50 + ms. Adjustable time must be larger + than 0 ms. */ + AAC_PCM_MIN_OUTPUT_CHANNELS = + 0x0011, /*!< Minimum number of PCM output channels. If higher than the + number of encoded audio channels, a simple channel extension is + applied (see note 4 for exceptions). \n -1, 0: Disable channel + extension feature. The decoder output contains the same number + of channels as the encoded bitstream. \n 1: This value is + currently needed only together with the mix-down feature. See + ::AAC_PCM_MAX_OUTPUT_CHANNELS and note 2 below. \n + 2: Encoded mono signals will be duplicated to achieve a + 2/0/0.0 channel output configuration. \n 6: The decoder + tries to reorder encoded signals with less than six channels to + achieve a 3/0/2.1 channel output signal. Missing channels will + be filled with a zero signal. If reordering is not possible the + empty channels will simply be appended. Only available if + instance is configured to support multichannel output. \n 8: + The decoder tries to reorder encoded signals with less than + eight channels to achieve a 3/0/4.1 channel output signal. + Missing channels will be filled with a zero signal. If + reordering is not possible the empty channels will simply be + appended. Only available if instance is configured to + support multichannel output.\n NOTE: \n + 1. The channel signaling (CStreamInfo::pChannelType and + CStreamInfo::pChannelIndices) will not be modified. Added empty + channels will be signaled with channel type + AUDIO_CHANNEL_TYPE::ACT_NONE. \n + 2. If the parameter value is greater than that of + ::AAC_PCM_MAX_OUTPUT_CHANNELS both will be set to the same + value. \n + 3. This parameter does not affect MPEG Surround processing. + \n + 4. This parameter will be ignored if the number of encoded + audio channels is greater than 8. */ + AAC_PCM_MAX_OUTPUT_CHANNELS = + 0x0012, /*!< Maximum number of PCM output channels. If lower than the + number of encoded audio channels, downmixing is applied + accordingly (see note 5 for exceptions). If dedicated metadata + is available in the stream it will be used to achieve better + mixing results. \n -1, 0: Disable downmixing feature. The + decoder output contains the same number of channels as the + encoded bitstream. \n 1: All encoded audio configurations + with more than one channel will be mixed down to one mono + output signal. \n 2: The decoder performs a stereo mix-down + if the number encoded audio channels is greater than two. \n 6: + If the number of encoded audio channels is greater than six the + decoder performs a mix-down to meet the target output + configuration of 3/0/2.1 channels. Only available if instance + is configured to support multichannel output. \n 8: This + value is currently needed only together with the channel + extension feature. See ::AAC_PCM_MIN_OUTPUT_CHANNELS and note 2 + below. Only available if instance is configured to support + multichannel output. \n NOTE: \n + 1. Down-mixing of any seven or eight channel configuration + not defined in ISO/IEC 14496-3 PDAM 4 is not supported by this + software version. \n + 2. If the parameter value is greater than zero but smaller + than ::AAC_PCM_MIN_OUTPUT_CHANNELS both will be set to same + value. \n + 3. The operating mode of the MPEG Surround module will be + set accordingly. \n + 4. Setting this parameter with any value will disable the + binaural processing of the MPEG Surround module + 5. This parameter will be ignored if the number of encoded + audio channels is greater than 8. */ + AAC_METADATA_PROFILE = + 0x0020, /*!< See ::AAC_MD_PROFILE for all available values. */ + AAC_METADATA_EXPIRY_TIME = 0x0021, /*!< Defines the time in ms after which all + the bitstream associated meta-data (DRC, + downmix coefficients, ...) will be reset + to default if no update has been + received. Negative values disable the + feature. */ + + AAC_CONCEAL_METHOD = 0x0100, /*!< Error concealment: Processing method. \n + 0: Spectral muting. \n + 1: Noise substitution (see ::CONCEAL_NOISE). + \n 2: Energy interpolation (adds additional + signal delay of one frame, see + ::CONCEAL_INTER. only some AOTs are + supported). \n */ + AAC_DRC_BOOST_FACTOR = + 0x0200, /*!< Dynamic Range Control: Scaling factor for boosting gain + values. Defines how the boosting DRC factors (conveyed in the + bitstream) will be applied to the decoded signal. The valid + values range from 0 (don't apply boost factors) to 127 (fully + apply boost factors). Default value is 0. */ + AAC_DRC_ATTENUATION_FACTOR = + 0x0201, /*!< Dynamic Range Control: Scaling factor for attenuating gain + values. Same as + ::AAC_DRC_BOOST_FACTOR but for attenuating DRC factors. */ + AAC_DRC_REFERENCE_LEVEL = + 0x0202, /*!< Dynamic Range Control (DRC): Target reference level. Defines + the level below full-scale (quantized in steps of 0.25dB) to + which the output audio signal will be normalized to by the DRC + module. The parameter controls loudness normalization for both + MPEG-4 DRC and MPEG-D DRC. The valid values range from 40 (-10 + dBFS) to 127 (-31.75 dBFS). Any value smaller than 0 switches + off loudness normalization and MPEG-4 DRC. By default, loudness + normalization and MPEG-4 DRC is switched off. */ + AAC_DRC_HEAVY_COMPRESSION = + 0x0203, /*!< Dynamic Range Control: En-/Disable DVB specific heavy + compression (aka RF mode). If set to 1, the decoder will apply + the compression values from the DVB specific ancillary data + field. At the same time the MPEG-4 Dynamic Range Control tool + will be disabled. By default, heavy compression is disabled. */ + AAC_DRC_DEFAULT_PRESENTATION_MODE = + 0x0204, /*!< Dynamic Range Control: Default presentation mode (DRC + parameter handling). \n Defines the handling of the DRC + parameters boost factor, attenuation factor and heavy + compression, if no presentation mode is indicated in the + bitstream.\n For options, see + ::AAC_DRC_DEFAULT_PRESENTATION_MODE_OPTIONS.\n Default: + ::AAC_DRC_PARAMETER_HANDLING_DISABLED */ + AAC_DRC_ENC_TARGET_LEVEL = + 0x0205, /*!< Dynamic Range Control: Encoder target level for light (i.e. + not heavy) compression.\n If known, this declares the target + reference level that was assumed at the encoder for calculation + of limiting gains. The valid values range from 0 (full-scale) + to 127 (31.75 dB below full-scale). This parameter is used only + with ::AAC_DRC_PARAMETER_HANDLING_ENABLED and ignored + otherwise.\n Default: 127 (worst-case assumption).\n */ + AAC_QMF_LOWPOWER = 0x0300, /*!< Quadrature Mirror Filter (QMF) Bank processing + mode. \n -1: Use internal default. Implies MPEG + Surround partially complex accordingly. \n 0: + Use complex QMF data mode. \n 1: Use real (low + power) QMF data mode. \n */ + AAC_TPDEC_CLEAR_BUFFER = + 0x0603, /*!< Clear internal bit stream buffer of transport layers. The + decoder will start decoding at new data passed after this event + and any previous data is discarded. */ + AAC_UNIDRC_SET_EFFECT = 0x0903 /*!< MPEG-D DRC: Request a DRC effect type for + selection of a DRC set.\n Supported indices + are:\n -1: DRC off. Completely disables + MPEG-D DRC.\n 0: None (default). Disables + MPEG-D DRC, but automatically enables DRC if + necessary to prevent clipping.\n 1: Late + night\n 2: Noisy environment\n 3: Limited + playback range\n 4: Low playback level\n 5: + Dialog enhancement\n 6: General compression. + Used for generally enabling MPEG-D DRC + without particular request.\n */ } AACDEC_PARAM; /** - * \brief This structure gives information about the currently decoded audio data. - * All fields are read-only. + * \brief This structure gives information about the currently decoded audio + * data. All fields are read-only. */ -typedef struct -{ - /* These five members are the only really relevant ones for the user. */ - INT sampleRate; /*!< The samplerate in Hz of the fully decoded PCM audio signal (after SBR processing). */ - INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n - 1024 or 960 for AAC-LC \n - 2048 or 1920 for HE-AAC (v2) \n - 512 or 480 for AAC-LD and AAC-ELD */ - INT numChannels; /*!< The number of output audio channels in the decoded and interleaved PCM audio signal. */ - AUDIO_CHANNEL_TYPE *pChannelType; /*!< Audio channel type of each output audio channel. */ - UCHAR *pChannelIndices; /*!< Audio channel index for each output audio channel. - See ISO/IEC 13818-7:2005(E), 8.5.3.2 Explicit channel mapping using a program_config_element() */ +typedef struct { + /* These five members are the only really relevant ones for the user. */ + INT sampleRate; /*!< The sample rate in Hz of the decoded PCM audio signal. */ + INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n + Typically this is: \n + 1024 or 960 for AAC-LC \n + 2048 or 1920 for HE-AAC (v2) \n + 512 or 480 for AAC-LD and AAC-ELD \n + 768, 1024, 2048 or 4096 for USAC */ + INT numChannels; /*!< The number of output audio channels before the rendering + module, i.e. the original channel configuration. */ + AUDIO_CHANNEL_TYPE + *pChannelType; /*!< Audio channel type of each output audio channel. */ + UCHAR *pChannelIndices; /*!< Audio channel index for each output audio + channel. See ISO/IEC 13818-7:2005(E), 8.5.3.2 + Explicit channel mapping using a + program_config_element() */ /* Decoder internal members. */ - INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration info). */ - INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. MPEG-4)). */ - AUDIO_OBJECT_TYPE aot; /*!< Audio Object Type (from ASC): is set to the appropriate value for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */ - INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: stereo, ... */ - INT bitRate; /*!< Instantaneous bit rate. */ - INT aacSamplesPerFrame; /*!< Samples per frame for the AAC core (from ASC). \n - 1024 or 960 for AAC-LC \n - 512 or 480 for AAC-LD and AAC-ELD */ - INT aacNumChannels; /*!< The number of audio channels after AAC core processing (before PS or MPS processing). - CAUTION: This are not the final number of output channels! */ - AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */ - INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) */ - - UINT outputDelay; /*!< The number of samples the output is additionally delayed by the decoder. */ - - UINT flags; /*!< Copy of internal flags. Only to be written by the decoder, and only to be read externally. */ - - SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */ - + INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration + info) divided by a (ELD) downscale factor if present. */ + INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g. + MPEG-4)). */ + AUDIO_OBJECT_TYPE + aot; /*!< Audio Object Type (from ASC): is set to the appropriate value + for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */ + INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2: + stereo, ... */ + INT bitRate; /*!< Instantaneous bit rate. */ + INT aacSamplesPerFrame; /*!< Samples per frame for the AAC core (from ASC) + divided by a (ELD) downscale factor if present. \n + Typically this is (with a downscale factor of 1): + \n 1024 or 960 for AAC-LC \n 512 or 480 for + AAC-LD and AAC-ELD */ + INT aacNumChannels; /*!< The number of audio channels after AAC core + processing (before PS or MPS processing). CAUTION: This + are not the final number of output channels! */ + AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */ + INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) divided by + a (ELD) downscale factor if present. */ + + UINT outputDelay; /*!< The number of samples the output is additionally + delayed by.the decoder. */ + UINT flags; /*!< Copy of internal flags. Only to be written by the decoder, + and only to be read externally. */ + + SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1 + means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */ /* Statistics */ - INT numLostAccessUnits; /*!< This integer will reflect the estimated amount of lost access units in case aacDecoder_DecodeFrame() - returns AAC_DEC_TRANSPORT_SYNC_ERROR. It will be < 0 if the estimation failed. */ - - UINT numTotalBytes; /*!< This is the number of total bytes that have passed through the decoder. */ - UINT numBadBytes; /*!< This is the number of total bytes that were considered with errors from numTotalBytes. */ - UINT numTotalAccessUnits; /*!< This is the number of total access units that have passed through the decoder. */ - UINT numBadAccessUnits; /*!< This is the number of total access units that were considered with errors from numTotalBytes. */ + INT numLostAccessUnits; /*!< This integer will reflect the estimated amount of + lost access units in case aacDecoder_DecodeFrame() + returns AAC_DEC_TRANSPORT_SYNC_ERROR. It will be + < 0 if the estimation failed. */ + + UINT numTotalBytes; /*!< This is the number of total bytes that have passed + through the decoder. */ + UINT numBadBytes; /*!< This is the number of total bytes that were considered + with errors from numTotalBytes. */ + UINT numTotalAccessUnits; /*!< This is the number of total access units that + have passed through the decoder. */ + UINT numBadAccessUnits; /*!< This is the number of total access units that + were considered with errors from numTotalBytes. */ /* Metadata */ - SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference level below full-scale. - It is quantized in steps of 0.25dB. The valid values range from 0 (0 dBFS) to 127 (-31.75 dBFS). - It is used to reflect the average loudness of the audio in LKFS accoring to ITU-R BS 1770. - If no level has been found in the bitstream the value is -1. */ - SCHAR drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, this field indicates whether - light (MPEG-4 Dynamic Range Control tool) or heavy compression (DVB heavy compression) - dynamic range control shall take priority on the outputs. - For details, see ETSI TS 101 154, table C.33. Possible values are: \n - -1: No corresponding metadata found in the bitstream \n - 0: DRC presentation mode not indicated \n - 1: DRC presentation mode 1 \n - 2: DRC presentation mode 2 \n - 3: Reserved */ + SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference + level below full-scale. It is quantized in steps of + 0.25dB. The valid values range from 0 (0 dBFS) to 127 + (-31.75 dBFS). It is used to reflect the average + loudness of the audio in LKFS according to ITU-R BS + 1770. If no level has been found in the bitstream the + value is -1. */ + SCHAR + drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, + this field indicates whether light (MPEG-4 Dynamic Range + Control tool) or heavy compression (DVB heavy + compression) dynamic range control shall take priority + on the outputs. For details, see ETSI TS 101 154, table + C.33. Possible values are: \n -1: No corresponding + metadata found in the bitstream \n 0: DRC presentation + mode not indicated \n 1: DRC presentation mode 1 \n 2: + DRC presentation mode 2 \n 3: Reserved */ } CStreamInfo; - -typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER; /*!< Pointer to a AAC decoder instance. */ +typedef struct AAC_DECODER_INSTANCE + *HANDLE_AACDECODER; /*!< Pointer to a AAC decoder instance. */ #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /** @@ -604,25 +906,23 @@ extern "C" * \param size Size of the buffer pointed to by buffer. * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_AncDataInit ( HANDLE_AACDECODER self, - UCHAR *buffer, - int size ); +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_AncDataInit(HANDLE_AACDECODER self, + UCHAR *buffer, int size); /** * \brief Get one ancillary data element. * * \param self AAC decoder handle. * \param index Index of the ancillary data element to get. - * \param ptr Pointer to a buffer receiving a pointer to the requested ancillary data element. - * \param size Pointer to a buffer receiving the length of the requested ancillary data element. + * \param ptr Pointer to a buffer receiving a pointer to the requested + * ancillary data element. + * \param size Pointer to a buffer receiving the length of the requested + * ancillary data element. * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_AncDataGet ( HANDLE_AACDECODER self, - int index, - UCHAR **ptr, - int *size ); +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_AncDataGet(HANDLE_AACDECODER self, + int index, UCHAR **ptr, + int *size); /** * \brief Set one single decoder parameter. @@ -632,106 +932,133 @@ aacDecoder_AncDataGet ( HANDLE_AACDECODER self, * \param value Parameter value. * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_SetParam ( const HANDLE_AACDECODER self, - const AACDEC_PARAM param, - const INT value ); - +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_SetParam(const HANDLE_AACDECODER self, + const AACDEC_PARAM param, + const INT value); /** - * \brief Get free bytes inside decoder internal buffer - * \param self Handle of AAC decoder instance - * \param pFreeBytes Pointer to variable receving amount of free bytes inside decoder internal buffer - * \return Error code + * \brief Get free bytes inside decoder internal buffer. + * \param self Handle of AAC decoder instance. + * \param pFreeBytes Pointer to variable receiving amount of free bytes inside + * decoder internal buffer. + * \return Error code. */ LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_GetFreeBytes ( const HANDLE_AACDECODER self, - UINT *pFreeBytes); +aacDecoder_GetFreeBytes(const HANDLE_AACDECODER self, UINT *pFreeBytes); /** - * \brief Open an AAC decoder instance - * \param transportFmt The transport type to be used - * \return AAC decoder handle + * \brief Open an AAC decoder instance. + * \param transportFmt The transport type to be used. + * \param nrOfLayers Number of transport layers. + * \return AAC decoder handle. */ -LINKSPEC_H HANDLE_AACDECODER -aacDecoder_Open ( TRANSPORT_TYPE transportFmt, UINT nrOfLayers ); +LINKSPEC_H HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, + UINT nrOfLayers); /** - * \brief Explicitly configure the decoder by passing a raw AudioSpecificConfig (ASC) or a StreamMuxConfig (SMC), - * contained in a binary buffer. This is required for MPEG-4 and Raw Packets file format bitstreams - * as well as for LATM bitstreams with no in-band SMC. If the transport format is LATM with or without - * LOAS, configuration is assumed to be an SMC, for all other file formats an ASC. + * \brief Explicitly configure the decoder by passing a raw AudioSpecificConfig + * (ASC) or a StreamMuxConfig (SMC), contained in a binary buffer. This is + * required for MPEG-4 and Raw Packets file format bitstreams as well as for + * LATM bitstreams with no in-band SMC. If the transport format is LATM with or + * without LOAS, configuration is assumed to be an SMC, for all other file + * formats an ASC. * * \param self AAC decoder handle. - * \param conf Pointer to an unsigned char buffer containing the binary configuration buffer (either ASC or SMC). + * \param conf Pointer to an unsigned char buffer containing the binary + * configuration buffer (either ASC or SMC). * \param length Length of the configuration buffer in bytes. * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_ConfigRaw ( HANDLE_AACDECODER self, - UCHAR *conf[], - const UINT length[] ); +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_ConfigRaw(HANDLE_AACDECODER self, + UCHAR *conf[], + const UINT length[]); +/** + * \brief Submit raw ISO base media file format boxes to decoder for parsing + * (only some box types are recognized). + * + * \param self AAC decoder handle. + * \param buffer Pointer to an unsigned char buffer containing the binary box + * data (including size and type, can be a sequence of multiple boxes). + * \param length Length of the data in bytes. + * \return Error code. + */ +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_RawISOBMFFData(HANDLE_AACDECODER self, + UCHAR *buffer, + UINT length); /** - * \brief Fill AAC decoder's internal input buffer with bitstream data from the external input buffer. - * The function only copies such data as long as the decoder-internal input buffer is not full. - * So it grabs whatever it can from pBuffer and returns information (bytesValid) so that at a - * subsequent call of %aacDecoder_Fill(), the right position in pBuffer can be determined to - * grab the next data. + * \brief Fill AAC decoder's internal input buffer with bitstream data from the + * external input buffer. The function only copies such data as long as the + * decoder-internal input buffer is not full. So it grabs whatever it can from + * pBuffer and returns information (bytesValid) so that at a subsequent call of + * %aacDecoder_Fill(), the right position in pBuffer can be determined to grab + * the next data. * * \param self AAC decoder handle. * \param pBuffer Pointer to external input buffer. - * \param bufferSize Size of external input buffer. This argument is required because decoder-internally - * we need the information to calculate the offset to pBuffer, where the next - * available data is, which is then fed into the decoder-internal buffer (as much - * as possible). Our example framework implementation fills the buffer at pBuffer - * again, once it contains no available valid bytes anymore (meaning bytesValid equal 0). - * \param bytesValid Number of bitstream bytes in the external bitstream buffer that have not yet been - * copied into the decoder's internal bitstream buffer by calling this function. - * The value is updated according to the amount of newly copied bytes. + * \param bufferSize Size of external input buffer. This argument is required + * because decoder-internally we need the information to calculate the offset to + * pBuffer, where the next available data is, which is then + * fed into the decoder-internal buffer (as much as + * possible). Our example framework implementation fills the + * buffer at pBuffer again, once it contains no available valid bytes anymore + * (meaning bytesValid equal 0). + * \param bytesValid Number of bitstream bytes in the external bitstream buffer + * that have not yet been copied into the decoder's internal bitstream buffer by + * calling this function. The value is updated according to + * the amount of newly copied bytes. * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_Fill ( HANDLE_AACDECODER self, - UCHAR *pBuffer[], - const UINT bufferSize[], - UINT *bytesValid ); - -#define AACDEC_CONCEAL 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error concealment module \ - to generate a substitute signal for one lost frame. New input data will not be - considered. */ -#define AACDEC_FLUSH 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all delayed audio \ - without having new input data. Thus new input data will not be considered.*/ -#define AACDEC_INTR 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data discontinuity. \ - Resync any internals as necessary. */ -#define AACDEC_CLRHIST 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and history buffers.\ - CAUTION: This can cause discontinuities in the output signal. */ +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self, + UCHAR *pBuffer[], + const UINT bufferSize[], + UINT *bytesValid); + +#define AACDEC_CONCEAL \ + 1 /*!< Flag for aacDecoder_DecodeFrame(): Trigger the built-in error \ + concealment module to generate a substitute signal for one lost frame. \ + New input data will not be considered. */ +#define AACDEC_FLUSH \ + 2 /*!< Flag for aacDecoder_DecodeFrame(): Flush all filterbanks to get all \ + delayed audio without having new input data. Thus new input data will \ + not be considered.*/ +#define AACDEC_INTR \ + 4 /*!< Flag for aacDecoder_DecodeFrame(): Signal an input bit stream data \ + discontinuity. Resync any internals as necessary. */ +#define AACDEC_CLRHIST \ + 8 /*!< Flag for aacDecoder_DecodeFrame(): Clear all signal delay lines and \ + history buffers. CAUTION: This can cause discontinuities in the output \ + signal. */ /** - * \brief Decode one audio frame + * \brief Decode one audio frame * - * \param self AAC decoder handle. - * \param pTimeData Pointer to external output buffer where the decoded PCM samples will be stored into. - * \param flags Bit field with flags for the decoder: \n - * (flags & AACDEC_CONCEAL) == 1: Do concealment. \n - * (flags & AACDEC_FLUSH) == 2: Discard input data. Flush filter banks (output delayed audio). \n - * (flags & AACDEC_INTR) == 4: Input data is discontinuous. Resynchronize any internals as necessary. - * \return Error code. + * \param self AAC decoder handle. + * \param pTimeData Pointer to external output buffer where the decoded PCM + * samples will be stored into. + * \param timeDataSize Size of external output buffer. + * \param flags Bit field with flags for the decoder: \n + * (flags & AACDEC_CONCEAL) == 1: Do concealment. \n + * (flags & AACDEC_FLUSH) == 2: Discard input data. Flush + * filter banks (output delayed audio). \n (flags & AACDEC_INTR) == 4: Input + * data is discontinuous. Resynchronize any internals as + * necessary. \n (flags & AACDEC_CLRHIST) == 8: Clear all signal delay lines and + * history buffers. + * \return Error code. */ -LINKSPEC_H AAC_DECODER_ERROR -aacDecoder_DecodeFrame ( HANDLE_AACDECODER self, - INT_PCM *pTimeData, - const INT timeDataSize, - const UINT flags ); +LINKSPEC_H AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, + INT_PCM *pTimeData, + const INT timeDataSize, + const UINT flags); /** * \brief De-allocate all resources of an AAC decoder instance. * * \param self AAC decoder handle. - * \return void + * \return void. */ -LINKSPEC_H void aacDecoder_Close ( HANDLE_AACDECODER self ); +LINKSPEC_H void aacDecoder_Close(HANDLE_AACDECODER self); /** * \brief Get CStreamInfo handle from decoder. @@ -739,16 +1066,15 @@ LINKSPEC_H void aacDecoder_Close ( HANDLE_AACDECODER self ); * \param self AAC decoder handle. * \return Reference to requested CStreamInfo. */ -LINKSPEC_H CStreamInfo* aacDecoder_GetStreamInfo( HANDLE_AACDECODER self ); +LINKSPEC_H CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self); /** * \brief Get decoder library info. * * \param info Pointer to an allocated LIB_INFO structure. - * \return 0 on success + * \return 0 on success. */ -LINKSPEC_H INT aacDecoder_GetLibInfo( LIB_INFO *info ); - +LINKSPEC_H INT aacDecoder_GetLibInfo(LIB_INFO *info); #ifdef __cplusplus } diff --git a/libAACdec/src/FDK_delay.cpp b/libAACdec/src/FDK_delay.cpp new file mode 100644 index 0000000..0ab1a66 --- /dev/null +++ b/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/libAACdec/src/FDK_delay.h b/libAACdec/src/FDK_delay.h new file mode 100644 index 0000000..f89c3a2 --- /dev/null +++ b/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/libAACdec/src/aac_ram.cpp b/libAACdec/src/aac_ram.cpp index 1ff289b..e13167d 100644 --- a/libAACdec/src/aac_ram.cpp +++ b/libAACdec/src/aac_ram.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,13 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** -/***************************** MPEG-4 AAC Decoder ************************** + Author(s): Josef Hoepfl - Author(s): Josef Hoepfl + Description: -******************************************************************************/ +*******************************************************************************/ #include "aac_ram.h" #include "aac_rom.h" @@ -93,10 +106,17 @@ amm-info@iis.fraunhofer.de #define WORKBUFFER1_TAG 0 #define WORKBUFFER2_TAG 1 -/*! The structure AAC_DECODER_INSTANCE is the top level structure holding all decoder configurations, - handles and structs. +#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, AAC_DECODER_INSTANCE, 1) +C_ALLOC_MEM(AacDecoder, struct AAC_DECODER_INSTANCE, 1) /*! \name StaticAacData @@ -105,21 +125,36 @@ C_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE, 1) */ /* @{ */ -/*! The structure CAacDecoderStaticChannelInfo contains the static sideinfo which is needed - for the decoding of one aac channel. <br> - Dimension: #AacDecoderChannels */ +/*! 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 */ +/*! 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_ALLOC_MEM2(OverlapBuffer, FIXP_DBL, OverlapBufferSize, (8)) +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)) + /* @} */ /*! @@ -128,15 +163,23 @@ C_ALLOC_MEM(DrcInfo, CDrcInfo, 1) Dynamic memory areas, might be reused in other algorithm sections, e.g. the sbr decoder */ -C_ALLOC_MEM_OVERLAY(WorkBufferCore2, FIXP_DBL, ((8)*1024), SECT_DATA_L2, WORKBUFFER2_TAG) - - -C_ALLOC_MEM_OVERLAY(WorkBufferCore1, CWorkBufferCore1, 1, SECT_DATA_L1, WORKBUFFER1_TAG) - -/* @{ */ - - -/* @} */ - - +/* 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/libAACdec/src/aac_ram.h b/libAACdec/src/aac_ram.h index 4527e27..a861e25 100644 --- a/libAACdec/src/aac_ram.h +++ b/libAACdec/src/aac_ram.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: -******************************************************************************/ +*******************************************************************************/ #ifndef AAC_RAM_H #define AAC_RAM_H @@ -97,13 +109,15 @@ amm-info@iis.fraunhofer.de #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 +#define MAX_SYNCHS 10 +#define SAMPL_FREQS 12 H_ALLOC_MEM(AacDecoder, AAC_DECODER_INSTANCE) @@ -113,8 +127,21 @@ 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/libAACdec/src/aac_rom.cpp b/libAACdec/src/aac_rom.cpp index f3c9b5a..cbdffc4 100644 --- a/libAACdec/src/aac_rom.cpp +++ b/libAACdec/src/aac_rom.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,404 +90,433 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** -/***************************** MPEG-4 AAC Decoder ************************** + Author(s): Josef Hoepfl, Tobias Chalupka - Author(s): Josef Hoepfl 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) -} ; +#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 } -} ; - + * \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 -}; +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 -}; +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 -}; +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 -}; +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 -}; + 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 -}; +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 -}; +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 -}; +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 -}; +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 -}; +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 -}; +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 -}; +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_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_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 }, - }, { - { NULL, NULL, 0, 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_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 }, - } -}; - + {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 */ /* @@ -487,1451 +527,2902 @@ const SFB_INFO sfbOffsetTables[5][16] = 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} -}; - - +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 */ -/* --------------------------------------------------------------------------------------------- */ + {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 */ +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 */ + 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}; +/* 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}; +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 */ - +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. + 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 }; +------------------------------------------------------------------------------------------ +*/ +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. + 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. + 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 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) + 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 LowDelaySynthesis480[1440] = { +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), +}; -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) +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 */ + */ +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 */ + 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 */ + 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_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 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) -}; - -/* MPEG like mapping (no change). */ -const UCHAR channelMappingTablePassthrough[15][8] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */ - { 0, 1,255,255,255,255,255,255}, /* mono / PS */ - { 0, 1,255,255,255,255,255,255}, /* stereo */ - { 0, 1, 2,255,255,255,255,255}, /* 3ch */ - { 0, 1, 2, 3,255,255,255,255}, /* 4ch */ - { 0, 1, 2, 3, 4,255,255,255}, /* 5ch */ - { 0, 1, 2, 3, 4, 5,255,255}, /* 5.1ch */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 front */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6,255}, /* 6.1ch */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* 7.1 rear */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6, 7} /* 7.1 top */ -}; - -/* WAV file like mapping (from MPEG mapping). */ -const UCHAR channelMappingTableWAV[15][8] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* fallback */ - { 0, 1,255,255,255,255,255,255}, /* mono / PS */ - { 0, 1,255,255,255,255,255,255}, /* stereo */ - { 2, 0, 1,255,255,255,255,255}, /* 3ch */ - { 2, 0, 1, 3,255,255,255,255}, /* 4ch */ - { 2, 0, 1, 3, 4,255,255,255}, /* 5ch */ - { 2, 0, 1, 4, 5, 3,255,255}, /* 5.1ch */ - { 2, 6, 7, 0, 1, 4, 5, 3}, /* 7.1 front */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 2, 0, 1, 4, 5, 6, 3,255}, /* 6.1ch */ - { 2, 0, 1, 6, 7, 4, 5, 3}, /* 7.1 rear */ - { 0, 1, 2, 3, 4, 5, 6, 7}, /* reserved */ - { 2, 0, 1, 4, 5, 3, 6, 7} /* 7.1 top */ +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[15][7] = -{ - /* 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 */ - /* 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 */ - /* 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 }, /* reserved */ - /* 14 */ { ID_SCE, ID_CPE, ID_CPE, ID_LFE, ID_CPE, ID_EXT, ID_END } /* 8 channels */ +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 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 + */ +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/libAACdec/src/aac_rom.h b/libAACdec/src/aac_rom.h index f314a2d..ffaf951 100644 --- a/libAACdec/src/aac_rom.h +++ b/libAACdec/src/aac_rom.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: Definition of constant tables -******************************************************************************/ +*******************************************************************************/ #ifndef AAC_ROM_H #define AAC_ROM_H @@ -96,13 +108,26 @@ amm-info@iis.fraunhofer.de #include "aacdec_hcr_types.h" #include "aacdec_hcrs.h" -#define AAC_NF_NO_RANDOM_VAL 512 /*!< Size of random number array for noise floor */ +#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] ; +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 @@ -112,6 +137,11 @@ extern const SCHAR ExponentTable [4][14] ; #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; @@ -123,13 +153,9 @@ typedef struct { extern const SFB_INFO sfbOffsetTables[5][16]; /* Huffman tables */ -enum { - HuffmanBits = 2, - HuffmanEntries = (1 << HuffmanBits) -}; +enum { HuffmanBits = 2, HuffmanEntries = (1 << HuffmanBits) }; -typedef struct -{ +typedef struct { const USHORT (*CodeBook)[HuffmanEntries]; UCHAR Dimension; UCHAR numBits; @@ -139,28 +165,26 @@ typedef struct extern const CodeBookDescription AACcodeBookDescriptionTable[13]; extern const CodeBookDescription AACcodeBookDescriptionSCL; +extern const STATEFUNC aStateConstant2State[]; -extern const STATEFUNC aStateConstant2State[]; - -extern const SCHAR aCodebook2StartInt[]; +extern const SCHAR aCodebook2StartInt[]; -extern const UCHAR aMinOfCbPair[]; -extern const UCHAR aMaxOfCbPair[]; +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 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 UINT *aHuffTable[]; +extern const SCHAR *aQuantTable[]; -extern const USHORT aLargestAbsoluteValue[]; - -extern const UINT aHuffTreeRvlcEscape[]; -extern const UINT aHuffTreeRvlCodewds[]; +extern const USHORT aLargestAbsoluteValue[]; +extern const UINT aHuffTreeRvlcEscape[]; +extern const UINT aHuffTreeRvlCodewds[]; extern const UCHAR tns_max_bands_tbl[13][2]; @@ -172,7 +196,10 @@ extern const UCHAR tns_max_bands_tbl_512[13]; extern const FIXP_TCC FDKaacDec_tnsCoeff3[8]; extern const FIXP_TCC FDKaacDec_tnsCoeff4[16]; -extern const USHORT randomSign[AAC_NF_NO_RANDOM_VAL/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]; @@ -183,6 +210,28 @@ 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[15][7]; +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/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index eb8e410..922a09e 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,37 +90,64 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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" +#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_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 MAX_REFERENCE_LEVEL ( 127 ) +#define OFF 0 +#define ON 1 - #define DVB_ANC_DATA_SYNC_BYTE ( 0xBC ) /* DVB ancillary data sync byte. */ +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 @@ -118,9 +156,7 @@ amm-info@iis.fraunhofer.de \return none */ -void aacDecoder_drcInit ( - HANDLE_AAC_DRC self ) -{ +void aacDecoder_drcInit(HANDLE_AAC_DRC self) { CDrcParams *pParams; if (self == NULL) { @@ -128,28 +164,36 @@ void aacDecoder_drcInit ( } /* init control fields */ - self->enable = 0; + 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->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 = 0; - pParams->applyHeavyCompression = 0; + 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 @@ -157,20 +201,17 @@ void aacDecoder_drcInit ( \return none */ -void aacDecoder_drcInitChannelData ( - CDrcChannelData *pDrcChData ) -{ +void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) { if (pDrcChData != NULL) { pDrcChData->expiryCount = 0; - pDrcChData->numBands = 1; - pDrcChData->bandTop[0] = (1024 >> 2) - 1; + 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 @@ -180,141 +221,152 @@ void aacDecoder_drcInitChannelData ( \return an error code. */ -AAC_DECODER_ERROR aacDecoder_drcSetParam ( - HANDLE_AAC_DRC self, - AACDEC_DRC_PARAM param, - INT value ) -{ +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); - if (self->params.applyHeavyCompression == 0) - self->params.cut = self->params.usrCut; - 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); - if (self->params.applyHeavyCompression == 0) - self->params.boost = self->params.usrBoost; - 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 = 0; - self->params.targetRefLevel = -1; - } - else { - /* ref_level must be between 0 and MAX_REFERENCE_LEVEL, inclusive */ - self->params.applyDigitalNorm = 1; - 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. */ + switch (param) { + case DRC_CUT_SCALE: + /* set attenuation scale factor */ + if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) { + return AAC_DEC_SET_PARAM_FAIL; } - } - break; - case APPLY_NORMALIZATION: - if (value < 0 || value > 1) { - 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 < 0 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - if (self->params.applyHeavyCompression != (UCHAR)value) { - if (value == 1) { - /* Disable scaling of DRC values by setting the max values */ - self->params.boost = FL2FXCONST_DBL(1.0f/(float)(1<<DRC_PARAM_SCALE)); - self->params.cut = FL2FXCONST_DBL(1.0f/(float)(1<<DRC_PARAM_SCALE)); + 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 { - /* Restore the user params */ - self->params.boost = self->params.usrBoost; - self->params.cut = self->params.usrCut; + /* 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.applyHeavyCompression = (UCHAR)value; - } - break; - case DRC_BS_DELAY: - if (value < 0 || value > 1) { + 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; - } - 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 = (UINT)value; - break; - default: - return AAC_DEC_SET_PARAM_FAIL; - } /* switch(param) */ - - /* switch on/off processing */ - self->enable = ( (self->params.boost > (FIXP_DBL)0) - || (self->params.cut > (FIXP_DBL)0) - || (self->params.applyHeavyCompression != 0) - || (self->params.targetRefLevel >= 0) ); - + } /* switch(param) */ return ErrorStatus; } - -static int parseExcludedChannels( UINT *excludedChnsMask, - HANDLE_FDK_BITSTREAM bs ) -{ +static int parseExcludedChannels(UINT *excludedChnsMask, + HANDLE_FDK_BITSTREAM bs) { UINT excludeMask = 0; UINT i, j; - int bitCnt = 9; + int bitCnt = 9; - for (i = 0, j = 1; i < 7; i++, j<<=1) { - if (FDKreadBits(bs,1)) { + 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)) { + while (FDKreadBits(bs, 1)) { + for (i = 0; i < 7; i++, j <<= 1) { + if (FDKreadBits(bs, 1)) { excludeMask |= j; } } @@ -327,7 +379,6 @@ static int parseExcludedChannels( UINT *excludedChnsMask, return (bitCnt); } - /*! \brief Save DRC payload bitstream position @@ -336,13 +387,10 @@ static int parseExcludedChannels( UINT *excludedChnsMask, \return The number of DRC payload bits */ -int aacDecoder_drcMarkPayload ( - HANDLE_AAC_DRC self, - HANDLE_FDK_BITSTREAM bs, - AACDEC_DRC_PAYLOAD_TYPE type ) -{ +int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs, + AACDEC_DRC_PAYLOAD_TYPE type) { UINT bsStartPos; - int i, numBands = 1, bitCnt = 0; + int i, numBands = 1, bitCnt = 0; if (self == NULL) { return 0; @@ -351,97 +399,97 @@ int aacDecoder_drcMarkPayload ( bsStartPos = FDKgetValidBits(bs); switch (type) { - case MPEG_DRC_EXT_DATA: - { + 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)) { /* 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)) { /* 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 */ + if (FDKreadBits(bs, 1)) { /* drc_bands_present */ numBands += FDKreadBits(bs, 4); /* drc_band_incr */ - FDKreadBits(bs,4); /* reserved */ - bitCnt+=8; + FDKreadBits(bs, 4); /* reserved */ + bitCnt += 8; for (i = 0; i < numBands; i++) { - FDKreadBits(bs,8); /* drc_band_top[i] */ - bitCnt+=8; + 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; + 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; + FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */ + bitCnt += 8; } - if ( (self->numPayloads < MAX_DRC_THREADS) - && ((INT)FDKgetValidBits(bs) >= 0) ) - { + if ((self->numPayloads < MAX_DRC_THREADS) && + ((INT)FDKgetValidBits(bs) >= 0)) { self->drcPayloadPosition[self->numPayloads++] = bsStartPos; } - } - break; + } break; case DVB_DRC_ANC_DATA: bitCnt += 8; /* check sync word */ - if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) - { + 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; + /* 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; + 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; + 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; + FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */ + bitCnt += 16; } /* coarse grain timecode */ if (coarseGrainTcPresent) { - FDKreadBits(bs, 16); /* coarse_grain_timecode */ - bitCnt+=16; + FDKreadBits(bs, 16); /* coarse_grain_timecode */ + bitCnt += 16; } /* fine grain timecode */ if (fineGrainTcPresent) { - FDKreadBits(bs, 16); /* fine_grain_timecode */ - bitCnt+=16; + FDKreadBits(bs, 16); /* fine_grain_timecode */ + bitCnt += 16; } - if ( !self->dvbAncDataAvailable - && ((INT)FDKgetValidBits(bs) >= 0) ) - { - self->dvbAncDataPosition = bsStartPos; + if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) { + self->dvbAncDataPosition = bsStartPos; self->dvbAncDataAvailable = 1; } } @@ -454,112 +502,101 @@ int aacDecoder_drcMarkPayload ( 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 junk (in) + \payloadPosition Bitstream position of MPEG DRC data chunk (in) - \return Number of bits read (0 in case of a parse error) + \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, bitCnt = 4; +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, FDKgetValidBits(bs)-payloadPosition); + FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition); /* pce_tag_present */ - if (FDKreadBits(bs,1)) - { - pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */ + if (FDKreadBits(bs, 1)) { + pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */ /* only one program supported */ - FDKreadBits(bs, 4); /* drc_tag_reserved_bits */ - bitCnt += 8; + FDKreadBits(bs, 4); /* drc_tag_reserved_bits */ } else { - pDrcBs->pceInstanceTag = -1; /* not present */ + pDrcBs->pceInstanceTag = -1; /* not present */ } - if (FDKreadBits(bs,1)) { /* excluded_chns_present */ + if (FDKreadBits(bs, 1)) { /* excluded_chns_present */ /* get excluded_chn_mask */ - bitCnt += parseExcludedChannels(&pDrcBs->excludedChnsMask, bs); + parseExcludedChannels(&pDrcBs->excludedChnsMask, bs); } else { pDrcBs->excludedChnsMask = 0; } numBands = 1; - if (FDKreadBits(bs,1)) /* drc_bands_present */ + 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 */ - bitCnt += 8; + 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] */ - bitCnt += 8; + for (i = 0; i < numBands; i++) { + pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */ } - } - else { - pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */; + } 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 */ + if (FDKreadBits(bs, 1)) /* prog_ref_level_present */ { - pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */ - FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */ - bitCnt += 8; + 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] */ - bitCnt += 8; + 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 (bitCnt); + return (1); } - /*! - \brief Parse heavy compression value transported in DSEs of DVB streams with MPEG-4 content. + \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 junk + \payloadPosition Bitstream position of DVB ancillary data chunk - \return Number of bits read (0 in case of a parse error) + \return Flag telling whether new DRC data has been found or not. */ -#define DVB_COMPRESSION_SCALE ( 8 ) /* 48,164 dB */ +#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */ -static int aacDecoder_drcReadCompression ( - HANDLE_FDK_BITSTREAM bs, - CDrcPayload *pDrcBs, - UINT payloadPosition ) -{ - int bitCnt = 0; - int dmxLevelsPresent, extensionPresent, compressionPresent; - int coarseGrainTcPresent, fineGrainTcPresent; +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, FDKgetValidBits(bs)-payloadPosition); + FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition); /* Sanity checks */ - if ( FDKgetValidBits(bs) < 24 ) { + if (FDKgetValidBits(bs) < 24) { return 0; } @@ -568,115 +605,87 @@ static int aacDecoder_drcReadCompression ( return 0; } - /* Evaluate bs_info field */ - if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */ + /* 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 */ + 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 */ + 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 */ - bitCnt += 24; + 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 */ - bitCnt += 8; + FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */ } /* audio_coding_mode_and_compression_status */ - if (compressionPresent) - { + if (compressionPresent) { UCHAR compressionOn, compressionValue; /* audio_coding_mode */ - if ( FDKreadBits(bs, 7) != 0 ) { /* The reserved bits shall be set to "0". */ + 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 */ - bitCnt += 16; - - 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] = (1024 >> 2) - 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. */ - } else { - /* No compression value available */ - /* CAUTION: It is not clearly defined by standard how to react in this situation. */ - /* Turn down the compression value to aprox. 0dB */ - pDrcBs->channelData.numBands = 1; /* One band ... */ - pDrcBs->channelData.drcValue[0] = 0x80; /* ... with aprox. 0dB ... */ - pDrcBs->channelData.bandTop[0] = (1024 >> 2) - 1; /* ... comprising the whole spectrum. */ - pDrcBs->channelData.drcDataType = DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */ - - /* If compression_on field is set to "0" the compression_value field shall be "0000 0000". */ - if (compressionValue != 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; } } - /* Read timecodes if available just to get the right amount of bits. */ - if (coarseGrainTcPresent) { - FDKreadBits(bs, 16); /* coarse_grain_timecode */ - bitCnt += 16; - } - if (fineGrainTcPresent) { - FDKreadBits(bs, 16); /* fine_grain_timecode */ - bitCnt += 16; - } - - /* Read extension just to get the right amount of bits. */ - if (extensionPresent) { - int extBits = 8; - - FDKreadBits(bs, 1); /* reserved, set to 0 */ - if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_levels_status */ - if (FDKreadBits(bs, 1)) extBits += 16; /* ext_downmixing_global_gains_status */ - if (FDKreadBits(bs, 1)) extBits += 8; /* ext_downmixing_lfe_level_status */ - - FDKpushFor(bs, extBits - 4); /* skip the extension payload remainder. */ - bitCnt += extBits; - } - - return (bitCnt); + return (foundDrcData); } - -/* - * Prepare DRC processing +/* + * 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]; +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; + CDrcParams *pParams; UINT backupBsPosition; - int i, thread, validThreads = 0; - int numExcludedChns[MAX_DRC_THREADS]; + int result = 0; + int i, thread, validThreads = 0; FDK_ASSERT(self != NULL); FDK_ASSERT(hBs != NULL); @@ -687,45 +696,40 @@ static int aacDecoder_drcExtractAndMap ( self->numThreads = 0; backupBsPosition = FDKgetValidBits(hBs); - for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS; i++) { - int bitsParsed; - - /* 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. */ + 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] = (1024 >> 2) - 1; + threadBs[self->numThreads].channelData.bandTop[0] = + DRC_BLOCK_LEN_DIV_BAND_MULT - 1; /* Extract payload */ - bitsParsed = aacDecoder_drcParse( hBs, - &threadBs[self->numThreads], - self->drcPayloadPosition[i] ); - if (bitsParsed > 0) { - self->numThreads++; - } + 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. */ - int bitsParsed; + 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. */ + /* 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] = (1024 >> 2) - 1; + threadBs[self->numThreads].channelData.bandTop[0] = + DRC_BLOCK_LEN_DIV_BAND_MULT - 1; /* Extract payload */ - bitsParsed = aacDecoder_drcReadCompression( hBs, - &threadBs[self->numThreads], - self->dvbAncDataPosition ); - if (bitsParsed > 0) { - self->numThreads++; - } + self->numThreads += aacDecoder_drcReadCompression( + hBs, &threadBs[self->numThreads], self->dvbAncDataPosition); } self->dvbAncDataAvailable = 0; /* Reset the bitbufffer */ - FDKpushBiDirectional(hBs, FDKgetValidBits(hBs) - backupBsPosition); + FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition); /* calculate number of valid bits in excl_chn_mask */ @@ -744,9 +748,9 @@ static int aacDecoder_drcExtractAndMap ( break; } - if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */ + if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */ if (pThreadBs->pceInstanceTag != pceInstanceTag) { - continue; /* don't accept */ + continue; /* don't accept */ } } @@ -760,44 +764,17 @@ static int aacDecoder_drcExtractAndMap ( } } if (numExclChns < validChannels) { - validThreadBs[validThreads] = pThreadBs; - numExcludedChns[validThreads] = numExclChns; + validThreadBs[validThreads] = pThreadBs; validThreads++; } } - if (validThreads > 1) { - int ch; - - /* check consistency of excl_chn_mask amongst valid DRC threads */ - for (ch = 0; ch < validChannels; ch++) { - int present = 0; - - for (thread = 0; thread < validThreads; thread++) { - CDrcPayload *pThreadBs = validThreadBs[thread]; - - - /* thread applies to this channel */ - if ( (pThreadBs->channelData.drcDataType == MPEG_DRC_EXT_DATA) - && ( (numExcludedChns[thread] == 0) - || (!(pThreadBs->excludedChnsMask & (1<<ch))) ) ) { - present++; - } - } - - - if (present > 1) { - return -1; - } - } - } - /* map DRC bitstream information onto DRC channel information */ - for (thread = 0; thread < validThreads; thread++) - { + 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; + AACDEC_DRC_PAYLOAD_TYPE drcPayloadType = + (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType; int ch; /* last progRefLevel transmitted is the one that is used @@ -806,7 +783,7 @@ static int aacDecoder_drcExtractAndMap ( if (pThreadBs->progRefLevel >= 0) { self->progRefLevel = pThreadBs->progRefLevel; self->progRefLevelPresent = 1; - self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ + self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ } if (drcPayloadType == DVB_DRC_ANC_DATA) { @@ -816,43 +793,51 @@ static int aacDecoder_drcExtractAndMap ( /* SCE, CPE and LFE */ for (ch = 0; ch < validChannels; ch++) { + AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD; int mapedChannel = channelMapping[ch]; - if ( ((exclMask & (1<<mapedChannel)) == 0) - && ( (drcPayloadType == MPEG_DRC_EXT_DATA) - || ((drcPayloadType == DVB_DRC_ANC_DATA) && self->params.applyHeavyCompression) - ) ) { - /* copy thread to channel */ + 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. */ + 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 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, top, bin, numBands; +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; @@ -860,33 +845,35 @@ void aacDecoder_drcApply ( INT max_exponent; FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f); - INT norm_exponent = 1; + INT norm_exponent = 1; FIXP_DBL fact_mantissa[MAX_DRC_BANDS]; - INT fact_exponent[MAX_DRC_BANDS]; + INT fact_exponent[MAX_DRC_BANDS]; - CDrcParams *pParams = &self->params; + CDrcParams *pParams = &self->params; - FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; + 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 ((pParams->expiryFrame > 0) && + (++pDrcChData->expiryCount > + pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */ + aacDecoder_drcInitChannelData(pDrcChData); } - if (!self->enable) { - sbrDecoder_drcDisable( (HANDLE_SBRDECODER)pSbrDec, ch ); + 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. */ + /* 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); + *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale); } else { FDK_ASSERT(0); } @@ -895,9 +882,6 @@ void aacDecoder_drcApply ( } numBands = pDrcChData->numBands; - top = FDKmax(0, numBands-1); - - pDrcChData->bandTop[0] = fixMin(pDrcChData->bandTop[0], (aacFrameSize >> 2) - 1); /* If program reference normalization is done in the digital domain, modify factor to perform normalization. prog_ref_level can @@ -906,45 +890,42 @@ void aacDecoder_drcApply ( reduced DAC SNR (if signal is attenuated) or clipping (if signal is boosted) */ - if (pParams->targetRefLevel >= 0) - { + 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 ); + 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. */ + /* 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); + *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale); } else { FDK_ASSERT(0); } } - if (self->params.applyDigitalNorm == 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++) - { + for (band = 0; band < numBands; band++) { UCHAR drcVal = pDrcChData->drcValue[band]; - top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize); fact_mantissa[band] = FL2FXCONST_DBL(0.5f); fact_exponent[band] = 1; - if ( pParams->applyHeavyCompression - && ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == DVB_DRC_ANC_DATA) ) - { + if ((pParams->applyHeavyCompression == ON) && + ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType == + DVB_DRC_ANC_DATA)) { INT compressionFactorVal_e; int valX, valY; @@ -954,48 +935,44 @@ void aacDecoder_drcApply ( /* 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 ); + 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_mantissa[band] = + fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]); - fact_exponent[band] = DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e; + 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]); } - } 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_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa); fact_exponent[band] += norm_exponent; - - bottom = top; - - } /* end loop over bands */ - + } /* end loop over bands */ /* normalizations */ { @@ -1012,7 +989,8 @@ void aacDecoder_drcApply ( res = CntLeadingZeros(max_mantissa) - 1; /* above topmost DRC band gain factor is 1 */ - if (((pDrcChData->bandTop[numBands-1]+1)<<2) < aacFrameSize) res = 0; + if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize) + res = 0; if (res > 0) { res = fixMin(res, max_exponent); @@ -1020,7 +998,7 @@ void aacDecoder_drcApply ( for (band = 0; band < numBands; band++) { fact_mantissa[band] <<= res; - fact_exponent[band] -= res; + fact_exponent[band] -= res; } } @@ -1039,25 +1017,25 @@ void aacDecoder_drcApply ( } /* apply factor to spectral lines - * short blocks must take care that bands fall on + * short blocks must take care that bands fall on * block boundaries! */ - if (!bSbrPresent) - { + 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. */ + /* 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++) - { - top = fixMin((int)( (pDrcChData->bandTop[band]+1)<<2 ), aacFrameSize); /* ... * DRC_BAND_MULT; */ + } 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]); + pSpectralCoefficient[bin] = + fMult(pSpectralCoefficient[bin], fact_mantissa[band]); } bottom = top; @@ -1066,7 +1044,7 @@ void aacDecoder_drcApply ( /* above topmost DRC band gain factor is 1 */ if (max_exponent > 0) { - for (bin = bottom; bin < aacFrameSize; bin+=1) { + for (bin = bottom; bin < aacFrameSize; bin += 1) { pSpectralCoefficient[bin] >>= max_exponent; } } @@ -1074,105 +1052,294 @@ void aacDecoder_drcApply ( /* adjust scaling */ pSpecScale[0] += max_exponent; - if (winSeq == EightShortSequence) { + if (winSeq == BLOCK_SHORT) { int win; for (win = 1; win < 8; win++) { pSpecScale[win] += max_exponent; } } - } - else { + } else { HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec; - UINT numBands = pDrcChData->numBands; + 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 - ); + 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 err = 0; +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) - { - err = aacDecoder_drcExtractAndMap ( - self, - hBs, - pAacDecoderStaticChannelInfo, - pceInstanceTag, - channelMapping, - validChannels ); + 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 err; + 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 err = 0; +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) - { - err = aacDecoder_drcExtractAndMap ( - self, - hBs, - pAacDecoderStaticChannelInfo, - pceInstanceTag, - channelMapping, - validChannels ); + 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 err; + return result; } /* * Export relevant metadata info from bitstream payload. */ -void aacDecoder_drcGetInfo ( - HANDLE_AAC_DRC self, - SCHAR *pPresMode, - SCHAR *pProgRefLevel ) -{ +void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode, + SCHAR *pProgRefLevel) { if (self != NULL) { if (pPresMode != NULL) { *pPresMode = self->presMode; diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index c850aa5..924ec6f 100644 --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,111 +90,103 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 "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 ( 50 ) /* Default DRC data expiry time in AAC frames */ +#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 -{ +typedef enum { DRC_CUT_SCALE = 0, DRC_BOOST_SCALE, TARGET_REF_LEVEL, DRC_BS_DELAY, DRC_DATA_EXPIRY_FRAME, APPLY_NORMALIZATION, - APPLY_HEAVY_COMPRESSION - + 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 numChannels ); +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. + * \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 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 + * \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 ); +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. + * \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 ); - +void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode, + SCHAR *pProgRefLevel); -#endif /* AACDEC_DRC_H */ +#endif /* AACDEC_DRC_H */ diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index 4c6d163..76c35d0 100644 --- a/libAACdec/src/aacdec_drc_types.h +++ b/libAACdec/src/aacdec_drc_types.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,96 +90,131 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 ( 3 ) /* 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) */ +#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 +typedef enum { + UNKNOWN_PAYLOAD = 0, + MPEG_DRC_EXT_DATA = 1, + DVB_DRC_ANC_DATA = 2 } AACDEC_DRC_PAYLOAD_TYPE; -typedef struct -{ - UINT expiryCount; - UINT numBands; - USHORT bandTop[MAX_DRC_BANDS]; - SHORT drcInterpolationScheme; - UCHAR drcValue[MAX_DRC_BANDS]; - SCHAR drcDataType; +/** + * \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; +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 -{ - FIXP_DBL cut; /* The attenuation scale factor currently used. */ - FIXP_DBL usrCut; /* The latest attenuation scale factor set by user. */ - FIXP_DBL boost; /* The boost scale factor currently used. */ - FIXP_DBL usrBoost; /* The latest boost scale factor set by user. */ +typedef struct { + /* DRC parameters: Latest user requests */ + FIXP_DBL usrCut; + FIXP_DBL usrBoost; + UCHAR usrApplyHeavyCompression; - UINT expiryFrame; - SCHAR targetRefLevel; - UCHAR bsDelayEnable; - UCHAR applyDigitalNorm; - UCHAR applyHeavyCompression; + /* 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 */ -} CDrcParams; - - -typedef struct -{ - CDrcParams params; /* Module parameters that can be set by user (via SetParam API function) */ + UINT expiryFrame; + UCHAR bsDelayEnable; + UCHAR applyDigitalNorm; - UCHAR enable; /* Switch that controls dynamic range processing */ - UCHAR digitalNorm; /* Switch to en-/disable reference level normalization in digital domain */ + AACDEC_DRC_PARAMETER_HANDLING defaultPresentationMode; + UCHAR encoderTargetLevel; - 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. */ +} CDrcParams; - 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 */ +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/libAACdec/src/aacdec_hcr.cpp b/libAACdec/src/aacdec_hcr.cpp index e314e27..84e05b0 100644 --- a/libAACdec/src/aacdec_hcr.cpp +++ b/libAACdec/src/aacdec_hcr.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,11 +90,12 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** AAC decoder library ****************************** Author(s): Robert Weidner (DSP Solutions) + Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo, decode priority codewords (PCWs) @@ -91,8 +103,6 @@ amm-info@iis.fraunhofer.de #include "aacdec_hcr.h" - - #include "aacdec_hcr_types.h" #include "aacdec_hcr_bit.h" #include "aacdec_hcrs.h" @@ -101,263 +111,247 @@ amm-info@iis.fraunhofer.de #include "channel.h" #include "block.h" -#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */ +#include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */ #include "FDK_bitstream.h" extern int mlFileChCurr; -static void errDetectorInHcrSideinfoShrt(SCHAR cb, - SHORT numLine, +static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine, UINT *errorWord); -static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword, - SHORT lengthOfReorderedSpectralData, - UINT *errorWord); +static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword, + SHORT lengthOfReorderedSpectralData, + UINT *errorWord); -static void HcrCalcNumCodeword (H_HCR_INFO pHcr); +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, - INT quantSpecCoef, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ); - -static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, - UINT codebookDim, - const SCHAR *pQuantVal, - FIXP_DBL *pQuantSpecCoef, - int *quantSpecCoefIdx, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ); - -static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, - const UINT *pCurrentTree, - const SCHAR *pQuantValBase, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ); +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, INT quantSpecCoef, + INT *pLeftStartOfSegment, + SCHAR *pRemainingBitsInSegment, + int *pNumDecodedBits); + +static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, 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 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 - ); + 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); -#if CHECK_SEGMENTATION_IMMEDIATELY -static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment, - H_HCR_INFO pHcr, - PCW_TYPE kind, - FIXP_DBL *qsc_base_of_cw, - UCHAR dimension); -#endif - -#if CHECK_SEGMENTATION_FINAL static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr); -#endif /*--------------------------------------------------------------------------------------------- - 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 ) { + 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 ) { + 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 ) { +-------------------------------------------------------------------------------------------- +*/ +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) -{ - INT globalHcrType = getHcrType(&pAacDecoderChannelInfo->pComData->overlay.aac.erHcrInfo); - 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 */ - } + 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 */ - } + } 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 */ - } + /* ------- 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: Sets up HCR ROM-Tables --------------------------------------------------------------------------------------------- */ - -void HcrInitRom(H_HCR_INFO pHcr) -{ - pHcr->cbPairs.pMinOfCbPair = aMinOfCbPair; - pHcr->cbPairs.pMaxOfCbPair = aMaxOfCbPair; - - pHcr->tableInfo.pMaxCwLength = aMaxCwLen; - pHcr->tableInfo.pCbDimension = aDimCb; - pHcr->tableInfo.pCbDimShift = aDimCbShift; - pHcr->tableInfo.pCbSign = aSignCb; - pHcr->tableInfo.pCbPriority = aCbPriority; - pHcr->tableInfo.pLargestAbsVal = aLargestAbsoluteValue; + } } /*--------------------------------------------------------------------------------------------- - 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. + 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, +UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo, const SamplingRateInfo *pSamplingRateInfo, - HANDLE_FDK_BITSTREAM bs) -{ + 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; + 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); + pHcr->nonPcwSideinfo.pResultBase = + SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); FDKsyncCache(bs); - pHcr->decInOut.bitstreamIndex = FDKgetBitCnt(bs); + pHcr->decInOut.bitstreamIndex = FDKgetBitCnt(bs); - if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */ + 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; + 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; - + 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); + 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 = pCodeBook[0]; cb_prev = pCodeBook[0]; - /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new section starts */ + /* 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 (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 = GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); + winGroupLen = (SCHAR)GetWindowGroupLength( + &pAacDecoderChannelInfo->icsInfo, group); for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) { cb = pCodeBook[group * 16 + band]; if (cb != cb_prev) { -#if CHECK_VALID_HCR_INPUT /* short-block 1 of 2 */ - errDetectorInHcrSideinfoShrt(cb,numLine,&pHcr->decInOut.errorLog ); - if (pHcr->decInOut.errorLog != 0 ) { - return ( pHcr->decInOut.errorLog ); + errDetectorInHcrSideinfoShrt(cb, numLine, + &pHcr->decInOut.errorLog); + if (pHcr->decInOut.errorLog != 0) { + return (pHcr->decInOut.errorLog); } -#endif *pCodeBk++ = cb; *pNumLinesInSec++ = numLine; numSection++; cb_prev = cb; numLine = LINES_PER_UNIT; - } - else { + } else { numLine += LINES_PER_UNIT; } } @@ -367,18 +361,16 @@ UINT HcrInit(H_HCR_INFO pHcr, numSection++; -#if CHECK_VALID_HCR_INPUT /* short-block 2 of 2 */ - errDetectorInHcrSideinfoShrt(cb,numLine,&pHcr->decInOut.errorLog ); - if ( numSection <= 0 || numSection > 1024/2 ) { + 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 ); + &pHcr->decInOut.errorLog); + if (pHcr->decInOut.errorLog != 0) { + return (pHcr->decInOut.errorLog); } -#endif *pCodeBk = cb; *pNumLinesInSec = numLine; @@ -386,46 +378,40 @@ UINT HcrInit(H_HCR_INFO pHcr, } else /* end short block prepare SI */ { /* long block */ -#if CHECK_VALID_HCR_INPUT /* long-block 1 of 1 */ errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword, pHcr->decInOut.lengthOfReorderedSpectralData, - &pHcr->decInOut.errorLog); - numSection = pHcr->decInOut.numSection; + &pHcr->decInOut.errorLog); + numSection = pHcr->decInOut.numSection; pNumLinesInSec = pHcr->decInOut.pNumLineInSect; - pCodeBk = pHcr->decInOut.pCodebook; - if ( numSection <= 0 || numSection > 64 ) { + 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-- ) - { + for (i = numSection; i != 0; i--) { cb = *pCodeBk++; - if ( cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL ) { + 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) ) { + 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 ); + if (pHcr->decInOut.errorLog != 0) { + return (pHcr->decInOut.errorLog); } -#endif /* CHECK_VALID_HCR_INPUT */ } pCodeBk = pHcr->decInOut.pCodebook; - for ( i = 0; i < numSection; i++ ) { - if ( - (*pCodeBk == NOISE_HCB) || - (*pCodeBk == INTENSITY_HCB2) || - (*pCodeBk == INTENSITY_HCB)) - { + for (i = 0; i < numSection; i++) { + if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) || + (*pCodeBk == INTENSITY_HCB)) { *pCodeBk = 0; } pCodeBk++; @@ -433,54 +419,24 @@ UINT HcrInit(H_HCR_INFO pHcr, /* HCR-sideinfo-input is complete and seems to be valid */ - - - return ( pHcr->decInOut.errorLog ); -} - - - - -#if USE_HCR_DUMMY - -/*--------------------------------------------------------------------------------------------- - - description: This HCR - dummy - function writes only a dirac-sequence in output buffer - --------------------------------------------------------------------------------------------- */ -UINT HcrDecoder(H_HCR_INFO pHcr, - const CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) -{ - for (SHORT i=0; i < 1024; i++ ) { - pHcr->decInOut.pQuantizedSpectralCoefficients->Long[i] = FL2FXCONST_DBL(0.0f); - if ( i % 30 == 0) { - pHcr->decInOut.pQuantizedSpectralCoefficients->Long[i] = (FIXP_DBL)HCR_DIRAC; - } - } - return 0; + return (pHcr->decInOut.errorLog); } -#else /* USE_HCR_DUMMY */ - /*--------------------------------------------------------------------------------------------- - 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) -{ + 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; -#if DETECT_TOO_LONG_CW_READS - int pTmp5; -#endif + int pTmp5; - INT bitCntOffst; - UINT saveBitCnt = FDKgetBitCnt(bs); /* save bitstream position */ + INT bitCntOffst; + INT saveBitCnt = FDKgetBitCnt(bs); /* save bitstream position */ HcrCalcNumCodeword(pHcr); @@ -490,244 +446,240 @@ UINT HcrDecoder(H_HCR_INFO 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 */ + 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); + 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; -#if DETECT_TOO_LONG_CW_READS pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx; -#endif /* ------- decode meaningful PCWs ------ */ DecodePCWs(bs, pHcr); - if (( pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK ) == 0 ) { + if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) { /* ------ decode the non-PCWs -------- */ DecodeNonPCWs(bs, pHcr); } - -#if CHECK_SEGMENTATION_FINAL errDetectWithinSegmentationFinal(pHcr); -#endif /* restore */ pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1; - pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4; -#if DETECT_TOO_LONG_CW_READS - pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5; -#endif + pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2; + pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3; + pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4; + pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5; - HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo, pSamplingRateInfo); + HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo, + pSamplingRateInfo); /* restore bitstream position */ bitCntOffst = saveBitCnt - FDKgetBitCnt(bs); - if( bitCntOffst ) { + if (bitCntOffst) { FDKpushBiDirectional(bs, bitCntOffst); } - return ( pHcr->decInOut.errorLog ); + return (pHcr->decInOut.errorLog); } - -#endif /* USE_HCR_DUMMY */ - - - - /*--------------------------------------------------------------------------------------------- - 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 + 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). --------------------------------------------------------------------------------------------- */ + 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; + 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 = pHcr->tableInfo.pCbDimShift; - const USHORT *pLargestAbsVal = pHcr->tableInfo.pLargestAbsVal; - UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook; - USHORT *pNumSortedCodewordInSection = pHcr->sectionInfo.pNumSortedCodewordInSection; - USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset; - FIXP_DBL *pTempValues = pHcr->segmentInfo.pTempValues; - FIXP_DBL *pBak = pHcr->segmentInfo.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]; + 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-- ) { + for (j = numSpectralValuesInSection; j != 0; j--) { qsc = *pQuantizedSpectralCoefficients++; - abs_qsc = FDKabs(qsc); -#if VALID_LAV_ERROR_TRIGGER - 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; + 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; } } -#else - if ( abs_qsc <= pLargestAbsVal[*pSortedCodebook] ) { - *pTeVa++ = qsc; - } - else { - *pTeVa++ = Q_VALUE_INVALID; - lavErrorCnt += 1; - } -#endif } pSortedCodebook++; } - if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) - { + 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 = pHcr->segmentInfo.pTempValues; + 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-- ) { + 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) */ + /* 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); + numSfbTransm = + GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); for (group = 0; group < numWinGroup; group++) { - winGroupLen = GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,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); + pBak = SPEC(pQuantizedSpectralCoefficientsBase, window, + pAacDecoderChannelInfo->granuleLength); locMax = FL2FXCONST_DBL(0.0f); - for (index = BandOffsets[band]; index < BandOffsets[band+1]; index += LINES_PER_UNIT) { + 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); + 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 ) { + 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 */ + pSfbSclHcr[window * 16 + band] = + msb - GetScaleFromValue( + locMax, lsb); /* save global scale maxima in this sfb */ } } - groupoffset += GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); + groupoffset += + GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group); } - } else - { + } else { /* copy straight for long-blocks */ - pQuantizedSpectralCoefficients = SPEC_LONG(pQuantizedSpectralCoefficientsBase); - for ( i = 1024; i != 0; i-- ) { + pQuantizedSpectralCoefficients = + SPEC_LONG(pQuantizedSpectralCoefficientsBase); + for (i = 1024; i != 0; i--) { *pQuantizedSpectralCoefficients++ = *pBak++; } } - if ( lavErrorCnt != 0 ) { + 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. + 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; -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; - UINT numSection = pHcr->decInOut.numSection; - UCHAR *pCodebook = pHcr->decInOut.pCodebook; - SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect; - const UCHAR *pCbDimShift = pHcr->tableInfo.pCbDimShift; - USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection; + USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection; numCodeword = 0; - for ( hcrSection = numSection; hcrSection != 0; hcrSection-- ) { + for (hcrSection = numSection; hcrSection != 0; hcrSection--) { *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook]; - if ( *pCodebook != 0 ) { + if (*pCodebook != 0) { numCodeword += *pNumCodewordInSection; } pNumCodewordInSection++; @@ -736,61 +688,63 @@ static void HcrCalcNumCodeword(H_HCR_INFO pHcr) 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 = pHcr->tableInfo.pCbPriority; - const UCHAR *pMinOfCbPair = pHcr->cbPairs.pMinOfCbPair; - const UCHAR *pMaxOfCbPair = pHcr->cbPairs.pMaxOfCbPair; - const UCHAR *pCbDimShift = pHcr->tableInfo.pCbDimShift; + 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 */ + /* calculate *pNumSortedSection and store the priorities in array + * pSortedCdebook */ pDest = pSortedCodebook; numZeroSection = 0; - for ( i=numSection; i != 0; i-- ) { - if ( pCbPriority[*pCodebook] == 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 */ + 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 ) { + if (numSectionDec > 0) { counter = numSectionDec; - for ( j=numSectionDec; j != 0; j-- ) { - for ( i=0; i < counter; i++ ) { + 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; + if (pSortedCodebook[i + 1] > pSortedCodebook[i]) { + temp = pSortedCodebook[i]; + pSortedCodebook[i] = pSortedCodebook[i + 1]; + pSortedCodebook[i + 1] = temp; } } counter -= 1; @@ -798,28 +752,33 @@ static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) } /* clear codebookSwitch array */ - for ( i = numSection; i != 0; i--) { + 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] )) { + /* 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 */ + pSortedCodebook[j] = pCodebook[i]; /* sort codebook */ + pNumSortedCodewordInSection[j] = + pNumCodewordInSection[i]; /* sort NumCodewordInSection */ startOffset = 0; - for ( k = 0; k < i; k++ ) { /* make entry in pReorderOffst */ + for (k = 0; k < i; k++) { /* make entry in pReorderOffst */ startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]]; } - pReorderOffset[j] = startOffset; /* offset for reordering the codewords */ + pReorderOffset[j] = + startOffset; /* offset for reordering the codewords */ - if(i == searchStart) { - UINT k = i; - while(pCodebookSwitch[k++] == 1) searchStart++; + if (i == searchStart) { + k = i; + while (pCodebookSwitch[k++] == 1) searchStart++; } break; } @@ -827,45 +786,49 @@ static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) } } - /*--------------------------------------------------------------------------------------------- - 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; - USHORT segmentStart = 0; - UCHAR segmentWidth; - UCHAR lastSegmentWidth; - UCHAR sortedCodebook; - UCHAR endFlag = 0; - USHORT 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; - USHORT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - USHORT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment; - SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; - USHORT bitstreamIndex = pHcr->decInOut.bitstreamIndex; - const UCHAR *pMaxCwLength = pHcr->tableInfo.pMaxCwLength; - - for ( i=numSortedSection; i != 0; i-- ) { + 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; + INT bitstreamIndex = pHcr->decInOut.bitstreamIndex; + const UCHAR *pMaxCwLength = aMaxCwLen; + + for (i = numSortedSection; i != 0; i--) { sortedCodebook = *pSortedCodebook++; - segmentWidth = FDKmin(pMaxCwLength[sortedCodebook],lengthOfLongestCodeword); + segmentWidth = + fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword); - for ( j = *pNumSortedCodewordInSection; j != 0 ; j-- ) { + for (j = *pNumSortedCodewordInSection; j != 0; j--) { /* width allows a new segment */ intermediateResult = bitstreamIndex + segmentStart; - if ( (segmentStart + segmentWidth) <= lengthOfReorderedSpectralData ) { - /* store segment start, segment length and increment the number of segments */ + if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) { + /* store segment start, segment length and increment the number of + * segments */ *pLeftStartOfSegment++ = intermediateResult; *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1; *pRemainingBitsInSegment++ = segmentWidth; @@ -882,7 +845,8 @@ static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart; *pRemainingBitsInSegment = lastSegmentWidth; - *pRightStartOfSegment = bitstreamIndex + segmentStart + lastSegmentWidth - 1; + *pRightStartOfSegment = + bitstreamIndex + segmentStart + lastSegmentWidth - 1; endFlag = 1; break; } @@ -893,52 +857,50 @@ static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) } } 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; -#if DETECT_TOO_LONG_CW_READS - UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec; - SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword; - const UCHAR *pMaxCwLength = pHcr->tableInfo.pMaxCwLength; -#endif + 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) { + /* data of a sorted section was not integrated in extended sorted section + */ + } else if (inSegmentRemainNumCW == remainNumCwInSortSec) { pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW; pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt]; @@ -946,74 +908,66 @@ static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt]; inSegmentRemainNumCW = numSegment; /* data of a sorted section was integrated in extended sorted section */ - } - else { /* inSegmentRemainNumCW > remainNumCwInSortSec */ + } 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 */ } -#if DETECT_TOO_LONG_CW_READS - pMaxLenOfCbInExtSrtSec[xSrtScCnt] = FDKmin(pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],lengthOfLongestCodeword); -#endif - - + pMaxLenOfCbInExtSrtSec[xSrtScCnt] = + fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]], + (INT)lengthOfLongestCodeword); xSrtScCnt += 1; - if ( xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS) ) { + 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 + 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; + 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) - { + while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) { cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx]; numExtendedSortedCodewordInSectionIdx++; - if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR+MAX_HCR_SETS)) { + if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { return; } if (cwSum > numSegment) { return; } counter++; - if (counter > 1024/4) { + if (counter > 1024 / 4) { return; } - if ( cwSum == numSegment ) { + if (cwSum == numSegment) { pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter; numExtendedSortedSectionsInSetsIdx++; if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) { @@ -1023,99 +977,109 @@ static void DeriveNumberOfExtendedSortedSectionsInSets(UINT numSegment, cwSum = 0; } } - pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter; /* save last entry for the last - probably shorter - set */ + 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; + 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; - USHORT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment; - SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment; -#if DETECT_TOO_LONG_CW_READS - UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec; - int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx; - UCHAR maxAllowedCwLen; - int numDecodedBits; -#endif - const UCHAR *pCbDimension = pHcr->tableInfo.pCbDimension; - const UCHAR *pCbSign = pHcr->tableInfo.pCbSign; + 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 */ - //pQSC = &pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx]; - //pQSC = *pQuantizedSpectralCoefficients; - - FDKmemclear(pQuantizedSpectralCoefficients+quantizedSpectralCoefficientsIdx,1024*sizeof(FIXP_DBL)); + 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 */ + 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)) { + 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 */ -#if DETECT_TOO_LONG_CW_READS + 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)) { + if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) { return; } -#endif /* switch for decoding with different codebooks: */ - if ( pCbSign[codebook] == 0 ) { /* no sign bits follow after the codeword-body */ + if (pCbSign[codebook] == + 0) { /* no sign bits follow after the codeword-body */ /* PCW_BodyONLY */ /*==============*/ - for ( curExtSortCwInSec = pNumExtendedSortedCodewordInSection[numExtendedSortedCodewordInSectionIdx] ; curExtSortCwInSec != 0; curExtSortCwInSec--) { + for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection + [numExtendedSortedCodewordInSectionIdx]; + curExtSortCwInSec != 0; curExtSortCwInSec--) { numDecodedBits = 0; /* decode PCW_BODY */ - pQuantVal = DecodePCW_Body(bs, - pCurrentTree, - pQuantValBase, - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); + pQuantVal = + DecodePCW_Body(bs, 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 */ + 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; @@ -1124,94 +1088,83 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) /* one more PCW should be decoded */ -#if DETECT_TOO_LONG_CW_READS - if ( maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG) ) { + if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) { pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED; } -#endif -#if CHECK_SEGMENTATION_IMMEDIATELY - if (1 == errDetectPcwSegmentation(*pRemainingBitsInSegment-ERROR_PCW_BODY,pHcr,PCW_BODY,pQuantizedSpectralCoefficients+quantizedSpectralCoefficientsIdx-dimension,dimension)) { + if (1 == errDetectPcwSegmentation( + *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY, + pQuantizedSpectralCoefficients + + quantizedSpectralCoefficientsIdx - dimension, + dimension)) { return; } -#endif - pLeftStartOfSegment++; /* update pointer for decoding the next PCW */ - pRemainingBitsInSegment++; /* update pointer for decoding the next PCW */ + pLeftStartOfSegment++; /* update pointer for decoding the next PCW */ + pRemainingBitsInSegment++; /* update pointer for decoding the next PCW + */ } - } - else if (( pCbSign[codebook] == 1 ) && ( codebook < 11 )) { /* possibly there follow 1,2,3 or 4 sign bits after the codeword-body */ + } 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--) - { + for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection + [numExtendedSortedCodewordInSectionIdx]; + curExtSortCwInSec != 0; curExtSortCwInSec--) { int err; - numDecodedBits = 0; - - pQuantVal = DecodePCW_Body(bs, - pCurrentTree, - pQuantValBase, - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); - - err = DecodePCW_Sign( bs, - dimension, - pQuantVal, - pQuantizedSpectralCoefficients, - &quantizedSpectralCoefficientsIdx, - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); + numDecodedBits = 0; + + pQuantVal = + DecodePCW_Body(bs, pCurrentTree, pQuantValBase, pLeftStartOfSegment, + pRemainingBitsInSegment, &numDecodedBits); + + err = DecodePCW_Sign( + bs, dimension, pQuantVal, pQuantizedSpectralCoefficients, + &quantizedSpectralCoefficientsIdx, pLeftStartOfSegment, + pRemainingBitsInSegment, &numDecodedBits); if (err != 0) { return; } /* one more PCW should be decoded */ -#if DETECT_TOO_LONG_CW_READS - if ( maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG) ) { + if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) { pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED; } -#endif -#if CHECK_SEGMENTATION_IMMEDIATELY - if (1 == errDetectPcwSegmentation(*pRemainingBitsInSegment-ERROR_PCW_BODY_SIGN,pHcr,PCW_BODY_SIGN, pQuantizedSpectralCoefficients+quantizedSpectralCoefficientsIdx-dimension,dimension)) { + if (1 == errDetectPcwSegmentation( + *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr, + PCW_BODY_SIGN, + pQuantizedSpectralCoefficients + + quantizedSpectralCoefficientsIdx - dimension, + dimension)) { return; } -#endif 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 */ + } 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--) - { + for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection + [numExtendedSortedCodewordInSectionIdx]; + curExtSortCwInSec != 0; curExtSortCwInSec--) { int err; - numDecodedBits = 0; + numDecodedBits = 0; /* decode PCW_BODY */ - pQuantVal = DecodePCW_Body(bs, - pCurrentTree, - pQuantValBase, - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); - - err = DecodePCW_Sign( bs, - dimension, - pQuantVal, - pQuantizedSpectralCoefficients, - &quantizedSpectralCoefficientsIdx, - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); + pQuantVal = + DecodePCW_Body(bs, pCurrentTree, pQuantValBase, pLeftStartOfSegment, + pRemainingBitsInSegment, &numDecodedBits); + + err = DecodePCW_Sign( + bs, dimension, pQuantVal, pQuantizedSpectralCoefficients, + &quantizedSpectralCoefficientsIdx, pLeftStartOfSegment, + pRemainingBitsInSegment, &numDecodedBits); if (err != 0) { return; } @@ -1219,26 +1172,32 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) /* 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, - pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); + if (fixp_abs(pQuantizedSpectralCoefficients + [quantizedSpectralCoefficientsIdx]) == + (FIXP_DBL)ESCAPE_VALUE) { + pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] = + (FIXP_DBL)DecodeEscapeSequence( + bs, + 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, - pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx], - pLeftStartOfSegment, - pRemainingBitsInSegment, - &numDecodedBits - ); + if (fixp_abs(pQuantizedSpectralCoefficients + [quantizedSpectralCoefficientsIdx]) == + (FIXP_DBL)ESCAPE_VALUE) { + pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] = + (FIXP_DBL)DecodeEscapeSequence( + bs, + pQuantizedSpectralCoefficients + [quantizedSpectralCoefficientsIdx], + pLeftStartOfSegment, pRemainingBitsInSegment, + &numDecodedBits); } quantizedSpectralCoefficientsIdx++; if (quantizedSpectralCoefficientsIdx >= 1024) { @@ -1247,17 +1206,20 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) /* one more PCW should be decoded */ -#if DETECT_TOO_LONG_CW_READS - if ( maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG) ) { + if (maxAllowedCwLen < + (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) { pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED; } -#endif -#if CHECK_SEGMENTATION_IMMEDIATELY - if (1 == errDetectPcwSegmentation(*pRemainingBitsInSegment-ERROR_PCW_BODY_SIGN_ESC,pHcr,PCW_BODY_SIGN_ESC,pQuantizedSpectralCoefficients+quantizedSpectralCoefficientsIdx-DIMENSION_OF_ESCAPE_CODEBOOK,DIMENSION_OF_ESCAPE_CODEBOOK)) { + 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; } -#endif pLeftStartOfSegment++; pRemainingBitsInSegment++; } @@ -1265,7 +1227,7 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) /* all PCWs belonging to this extended section should be decoded */ numExtendedSortedCodewordInSectionIdx++; - if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR+MAX_HCR_SETS) { + if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) { return; } } @@ -1277,66 +1239,65 @@ static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) } /* Write back indexes into structure */ - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = numExtendedSortedCodewordInSectionIdx; + pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = + numExtendedSortedCodewordInSectionIdx; pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = numExtendedSortedSectionsInSetsIdx; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = quantizedSpectralCoefficientsIdx; + pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = + numExtendedSortedSectionsInSetsIdx; + pHcr->decInOut.quantizedSpectralCoefficientsIdx = + quantizedSpectralCoefficientsIdx; pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx; } -#if CHECK_SEGMENTATION_IMMEDIATELY /*--------------------------------------------------------------------------------------------- - 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 + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +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 ) { + if (remainingBitsInSegment < 0) { /* log the error */ switch (kind) { - case PCW_BODY: + case PCW_BODY: pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY; break; - case PCW_BODY_SIGN: + case PCW_BODY_SIGN: pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN; break; - case PCW_BODY_SIGN_ESC: + 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; + for (i = dimension; i != 0; i--) { + *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID; } return 1; } return 0; } -#endif -#if CHECK_SEGMENTATION_FINAL /*--------------------------------------------------------------------------------------------- - 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--) { + 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; } @@ -1345,125 +1306,114 @@ static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR; } } -#endif /*--------------------------------------------------------------------------------------------- - 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) -{ + 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 */ + *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) */ + *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 UINT *pCurrentTree, - const SCHAR *pQuantValBase, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ) -{ + return: - return value is pointer to first of two or four quantized +spectral coefficients +-------------------------------------------------------------------------------------------- +*/ +static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, + const UINT *pCurrentTree, + const SCHAR *pQuantValBase, + INT *pLeftStartOfSegment, + SCHAR *pRemainingBitsInSegment, + int *pNumDecodedBits) { UCHAR carryBit; - UINT branchNode; - UINT treeNode; - UINT branchValue; - const SCHAR *pQuantVal; + UINT branchNode; + UINT treeNode; + UINT branchValue; + const SCHAR *pQuantVal; /* decode PCW_BODY */ - treeNode = *pCurrentTree; /* get first node of current tree belonging to current codebook */ + treeNode = *pCurrentTree; /* get first node of current tree belonging to + current codebook */ /* decode whole PCW-codeword-body */ while (1) { - - carryBit = HcrGetABitFromBitstream(bs, - pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ + carryBit = HcrGetABitFromBitstream(bs, pLeftStartOfSegment, + pLeftStartOfSegment, /* dummy */ FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; - CarryBitToBranchValue(carryBit, - treeNode, - &branchValue, - &branchNode); + 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 */ + 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 */ + 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: + 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, - INT quantSpecCoef, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ) -{ - UINT i; - INT sign; - UINT escapeOnesCounter = 0; - UINT carryBit; - INT escape_word = 0; +-------------------------------------------------------------------------------------------- +*/ + +static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, 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, - pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ + carryBit = HcrGetABitFromBitstream(bs, pLeftStartOfSegment, + pLeftStartOfSegment, /* dummy */ FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; if (carryBit != 0) { escapeOnesCounter += 1; - } - else { + } else { escapeOnesCounter += 4; break; } } /* decode escape word */ - for( i=escapeOnesCounter; i != 0 ; i-- ) { - carryBit = HcrGetABitFromBitstream(bs, - pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ + for (i = escapeOnesCounter; i != 0; i--) { + carryBit = HcrGetABitFromBitstream(bs, pLeftStartOfSegment, + pLeftStartOfSegment, /* dummy */ FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; @@ -1474,61 +1424,54 @@ static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, sign = (quantSpecCoef >= 0) ? 1 : -1; - quantSpecCoef = sign * (((INT ) 1 << escapeOnesCounter) + escape_word); + 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 + 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) + 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, - UINT codebookDim, - const SCHAR *pQuantVal, - FIXP_DBL *pQuantSpecCoef, - int *quantSpecCoefIdx, - USHORT *pLeftStartOfSegment, - SCHAR *pRemainingBitsInSegment, - int *pNumDecodedBits - ) -{ - UINT i; - UINT carryBit; - INT quantSpecCoef; - - for( i=codebookDim; i != 0 ; i-- ) { + return: - updated pQuantSpecCoef pointer (to next empty storage for a +line) +-------------------------------------------------------------------------------------------- +*/ +static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, 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, - pLeftStartOfSegment, - pLeftStartOfSegment, /* dummy */ + carryBit = HcrGetABitFromBitstream(bs, pLeftStartOfSegment, + pLeftStartOfSegment, /* dummy */ FROM_LEFT_TO_RIGHT); *pRemainingBitsInSegment -= 1; *pNumDecodedBits += 1; - if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024>>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] = (FIXP_DBL)quantSpecCoef; - } - } - else { + } else { pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f); } - *quantSpecCoefIdx += 1 ; + *quantSpecCoefIdx += 1; if (*quantSpecCoefIdx >= 1024) { return -1; } @@ -1536,56 +1479,20 @@ static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, return 0; } - /*--------------------------------------------------------------------------------------------- - description: Mutes spectral lines which have been marked as erroneous (Q_VALUE_INVALID) --------------------------------------------------------------------------------------------- */ -void HcrMuteErroneousLines(H_HCR_INFO hHcr) -{ + 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); + 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) { -#if HCR_LISTEN_TO_MUTED_LINES - pLong[c] = (FIXP_DBL)HCR_DIRAC; /* marking */ -#else - pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */ -#endif + pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */ } } } - - -/*--------------------------------------------------------------------------------------------- - description: Sets global HCR type --------------------------------------------------------------------------------------------- */ -void setHcrType(H_HCR_INFO hHcr, MP4_ELEMENT_ID type) -{ - switch (type) { - case ID_SCE: - hHcr->globalHcrType = 0; - break; - case ID_CPE: - hHcr->globalHcrType = 1; - break; - default: - break; - } -} - - -/*--------------------------------------------------------------------------------------------- - description: Gets HCR type from the HCR data structure ------------------------------------------------------------------------------------------------ - return: - global HCR type --------------------------------------------------------------------------------------------- */ -INT getHcrType(H_HCR_INFO hHcr) -{ - return hHcr->globalHcrType; -} - - - - diff --git a/libAACdec/src/aacdec_hcr.h b/libAACdec/src/aacdec_hcr.h index 6fc527b..be21144 100644 --- a/libAACdec/src/aacdec_hcr.h +++ b/libAACdec/src/aacdec_hcr.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,48 +90,39 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** 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_ - - +#ifndef AACDEC_HCR_H +#define AACDEC_HCR_H #include "channelinfo.h" #include "FDK_bitstream.h" -void HcrInitRom (H_HCR_INFO hHcr); -UINT HcrInit(H_HCR_INFO pHcr, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, +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); -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_ */ + 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/libAACdec/src/aacdec_hcr_bit.cpp b/libAACdec/src/aacdec_hcr_bit.cpp index df2685b..a53ef16 100644 --- a/libAACdec/src/aacdec_hcr_bit.cpp +++ b/libAACdec/src/aacdec_hcr_bit.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,39 +90,38 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** 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 ) { +-------------------------------------------------------------------------------------------- +*/ +UCHAR ToggleReadDirection(UCHAR readDirection) { + if (readDirection == FROM_LEFT_TO_RIGHT) { return FROM_RIGHT_TO_LEFT; - } - else { + } 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). + 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 @@ -120,28 +130,25 @@ UCHAR ToggleReadDirection(UCHAR readDirection) - readDirection ----------------------------------------------------------------------------------------------- return: - bit from bitstream --------------------------------------------------------------------------------------------- */ -UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, - USHORT *pLeftStartOfSegment, - USHORT *pRightStartOfSegment, - UCHAR readDirection) -{ - UINT bit; - INT readBitOffset; +-------------------------------------------------------------------------------------------- +*/ +UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, INT *pLeftStartOfSegment, + INT *pRightStartOfSegment, UCHAR readDirection) { + UINT bit; + INT readBitOffset; if (readDirection == FROM_LEFT_TO_RIGHT) { - readBitOffset = *pLeftStartOfSegment-FDKgetBitCnt(bs); - if( readBitOffset ) { + readBitOffset = *pLeftStartOfSegment - FDKgetBitCnt(bs); + if (readBitOffset) { FDKpushBiDirectional(bs, readBitOffset); } bit = FDKreadBits(bs, 1); *pLeftStartOfSegment += 1; - } - else { - readBitOffset = *pRightStartOfSegment-FDKgetBitCnt(bs); - if( readBitOffset ) { + } else { + readBitOffset = *pRightStartOfSegment - FDKgetBitCnt(bs); + if (readBitOffset) { FDKpushBiDirectional(bs, readBitOffset); } @@ -152,14 +159,5 @@ UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, *pRightStartOfSegment -= 1; } - -#if ERROR_GENERATOR_BIT_STREAM_HCR - static int a; - if ((++a % MODULO_DIVISOR_HCR) == 0) { - bit = (bit == 0) ? 1 : 0; - } -#endif - return (bit); } - diff --git a/libAACdec/src/aacdec_hcr_bit.h b/libAACdec/src/aacdec_hcr_bit.h index 8994ff1..7a57c8c 100644 --- a/libAACdec/src/aacdec_hcr_bit.h +++ b/libAACdec/src/aacdec_hcr_bit.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,28 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** 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_ - - +#ifndef AACDEC_HCR_BIT_H +#define AACDEC_HCR_BIT_H #include "aacdec_hcr.h" UCHAR ToggleReadDirection(UCHAR readDirection); -UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, - USHORT *pLeftStartOfSegment, - USHORT *pRightStartOfSegment, - UCHAR readDirection); - +UINT HcrGetABitFromBitstream(HANDLE_FDK_BITSTREAM bs, INT *pLeftStartOfSegment, + INT *pRightStartOfSegment, UCHAR readDirection); -#endif /* _AACDEC_HCR_BIT_H_ */ +#endif /* AACDEC_HCR_BIT_H */ diff --git a/libAACdec/src/aacdec_hcr_types.h b/libAACdec/src/aacdec_hcr_types.h index 323ec4e..d550bc2 100644 --- a/libAACdec/src/aacdec_hcr_types.h +++ b/libAACdec/src/aacdec_hcr_types.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,20 +90,19 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** 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_ - - +#ifndef AACDEC_HCR_TYPES_H +#define AACDEC_HCR_TYPES_H #include "FDK_bitstream.h" #include "overlapadd.h" @@ -100,186 +110,249 @@ amm-info@iis.fraunhofer.de /* ------------------------------------------------ */ /* ------------------------------------------------ */ -#define LINES_PER_UNIT 4 +#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 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 FROM_LEFT_TO_RIGHT 0 +#define FROM_RIGHT_TO_LEFT 1 -#define MAX_CB_PAIRS 23 -#define MAX_HCR_SETS 14 +#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 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 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 MAX_CB_CHECK \ + 32 /* support for VCB11 available -- is more general, could therefore used \ + in both cases */ -#define NUMBER_OF_BIT_IN_WORD 32 +#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 +#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 +#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 */ +#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 +#define MASK_LEFT 0xFFF000 +#define MASK_RIGHT 0xFFF +#define CLR_BIT_10 0x3FF +#define TEST_BIT_10 0x400 -/* 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 */ -#define USE_HCR_DUMMY 0 +#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 ERROR_GENERATOR_BIT_STREAM_HCR 0 /* modify every <MODULO_DIVISOR_HCR>-bit when reading from bitstream */ /* !!! BEWARE!!! if RVLC is active, also RVLC data at ESC2 will be modified !!! */ -#define MODULO_DIVISOR_HCR 30 - +/* 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 */ -#define CHECK_VALID_HCR_INPUT 1 /* it is highly recommended to check input data */ - - /* during decoding */ -#define CHECK_SEGMENTATION_IMMEDIATELY 1 /* the 2 or 4 lines of a detected PCW-decoding-error is marked */ - -#define CHECK_SEGMENTATION_FINAL 1 /* all the segments are checked -- therefore -- if this check passes, its a kind of evidence that the - decoded PCWs and non-PCWs are fine */ - -#define DETECT_TOO_LONG_CW_READS 1 /* 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. */ - -#define STATE_MACHINE_ERROR_CHECK 1 /* 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 */ -#define VALID_LAV_ERROR_TRIGGER 1 /* 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. */ - -#define HCR_LISTEN_TO_MUTED_LINES 0 /* listen to the "error-concealment" for testing */ +/* 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 */ - +#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: +// 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; - +// 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; - USHORT bitstreamIndex; - SCHAR lengthOfLongestCodeword; - UCHAR *pCodebook; + UINT errorLog; + SPECTRAL_PTR pQuantizedSpectralCoefficientsBase; + int quantizedSpectralCoefficientsIdx; + SHORT lengthOfReorderedSpectralData; + SHORT numSection; + SHORT *pNumLineInSect; + INT bitstreamIndex; + SCHAR lengthOfLongestCodeword; + UCHAR *pCodebook; } HCR_INPUT_OUTPUT; typedef struct { @@ -287,80 +360,73 @@ typedef struct { const UCHAR *pMaxOfCbPair; } HCR_CB_PAIRS; -typedef struct{ +typedef struct { const USHORT *pLargestAbsVal; - const UCHAR *pMaxCwLength; - const UCHAR *pCbDimension; - const UCHAR *pCbDimShift; - const UCHAR *pCbSign; - const UCHAR *pCbPriority; + 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; - FIXP_DBL pTempValues[1024]; - USHORT pLeftStartOfSegment[1024>>1]; - USHORT pRightStartOfSegment[1024>>1]; - SCHAR pRemainingBitsInSegment[1024>>1]; - UCHAR readDirection; - UCHAR numWordForBitfield; - USHORT pNumBitValidInLastWord; +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; -#if DETECT_TOO_LONG_CW_READS - UCHAR pMaxLenOfCbInExtSrtSec[MAX_SFB_HCR+MAX_HCR_SETS]; - int maxLenOfCbInExtSrtSecIdx; -#endif - UCHAR pCodebookSwitch[MAX_SFB_HCR]; +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 UINT (*STATEFUNC)(HANDLE_FDK_BITSTREAM, void *); -typedef struct{ +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]; + 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_CB_PAIRS cbPairs; - HCR_TABLE_INFO tableInfo; - HCR_SEGMENT_INFO segmentInfo; - HCR_SECTION_INFO sectionInfo; - HCR_NON_PCW_SIDEINFO nonPcwSideinfo; - - INT globalHcrType; +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; -typedef CErHcrInfo *H_HCR_INFO; - - -#endif /* _AACDEC_HCR_TYPES_H_ */ +#endif /* AACDEC_HCR_TYPES_H */ diff --git a/libAACdec/src/aacdec_hcrs.cpp b/libAACdec/src/aacdec_hcrs.cpp index c0b2173..e2b7cd8 100644 --- a/libAACdec/src/aacdec_hcrs.cpp +++ b/libAACdec/src/aacdec_hcrs.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,11 +90,12 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** AAC decoder library ****************************** Author(s): Robert Weidner (DSP Solutions) + Description: HCR Decoder: Prepare decoding of non-PCWs, segmentation- and bitfield-handling, HCR-Statemachine @@ -91,111 +103,113 @@ amm-info@iis.fraunhofer.de #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, +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); - +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; + 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, + 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 ) { + 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++ ) { - - - + 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 */ + 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 */ + /* 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 */ + 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 { + 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 */ + 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; @@ -212,1147 +226,1270 @@ void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) /* loop over trials */ codewordOffsetBase = 0; - for ( trial = *pNumSegment; trial > 0; trial-- ) { - + 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 */ + 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++ ) { + 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]; + 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 ) { - + 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]]; + pHcr->nonPcwSideinfo.pState = + aStateConstant2State[pSta[codewordOffset]]; - while(pHcr->nonPcwSideinfo.pState) { - ret = ((STATEFUNC) pHcr->nonPcwSideinfo.pState)(bs, pHcr); -#if STATE_MACHINE_ERROR_CHECK - if ( ret != 0 ) { + while (pHcr->nonPcwSideinfo.pState) { + ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr); + if (ret != 0) { return; } -#endif } } /* update both offsets */ - segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */ + 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 */ + 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 */ + } 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 */ + 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 */ + 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) */ + /* 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 = 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)); + pCodewordBitfield[*pNumWordForBitfield - 1] = + pCodewordBitfield[*pNumWordForBitfield - 1] & + ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord)); /* rotate last valid word */ - pCodewordBitfield[*pNumWordForBitfield-1] = pCodewordBitfield[*pNumWordForBitfield-1] >> 1; + 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-- ) { + /* 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)); + /* 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; + 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)); + 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); - + 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 */ + /* 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. + 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-1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1; +-------------------------------------------------------------------------------------------- +*/ +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 - 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 */ + /* 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 */ + 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 */ + 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 */ + 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 */ + 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 */ + 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 */ - - + pSegmentBitfield[bitfieldWord] = tempWord; /* store result */ return numValidSegment; } - /*--------------------------------------------------------------------------------------------- - description: This function sets up sideinfo for the non-PCW decoder (for the current set). + 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; - FIXP_DBL *pQuantizedSpectralCoefficients = SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase); - int quantizedSpectralCoefficientsIdx = pHcr->decInOut.quantizedSpectralCoefficientsIdx; - const UCHAR *pCbDimension = pHcr->tableInfo.pCbDimension; +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-- ) { + /* 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)) { + 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 */ + *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)) { + 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)) { + 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.numExtendedSortedCodewordInSectionIdx = + numExtendedSortedCodewordInSectionIdx; pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx; - pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = numExtendedSortedSectionsInSetsIdx; - pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = numExtendedSortedCodewordInSectionIdx; - pHcr->decInOut.quantizedSpectralCoefficientsIdx = quantizedSpectralCoefficientsIdx; + 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. + 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) ) { +-------------------------------------------------------------------------------------------- +*/ +static INT ModuloValue(INT input, INT bufferlength) { + if (input > (bufferlength - 1)) { return (input - bufferlength); } - if ( input < 0 ) { + 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; + 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 */ + 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)); + 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 */ + /* 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. + 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 + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +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; - USHORT *pLeftStartOfSegment; - USHORT *pRightStartOfSegment; - SCHAR *pRemainingBitsInSegment; - UCHAR readDirection; - UCHAR *pCodebook; - UCHAR dimCntr; - const UINT *pCurrentTree; + 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 = pHcr->tableInfo.pCbDimension; - - treeNode = iNode[codewordOffset]; - pCurrentTree = aHuffTable[pCodebook[codewordOffset]]; - - - for ( ; pRemainingBitsInSegment[segmentOffset] > 0 ; pRemainingBitsInSegment[segmentOffset] -= 1 ) { - - carryBit = HcrGetABitFromBitstream( bs, - &pLeftStartOfSegment[segmentOffset], + 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, &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 */ + 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 */ + 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 */ + 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY; - return BODY_ONLY; + return BODY_ONLY; } -#endif } 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. + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *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; + 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 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 = pHcr->tableInfo.pCbDimension; - - treeNode = iNode[codewordOffset]; - pCurrentTree = aHuffTable[pCodebook[codewordOffset]]; - - - for ( ; pRemainingBitsInSegment[segmentOffset] > 0 ; pRemainingBitsInSegment[segmentOffset] -= 1 ) { - - carryBit = HcrGetABitFromBitstream( bs, - &pLeftStartOfSegment[segmentOffset], + 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, &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] */ + 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 ) { + 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 */ + 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 */ } - 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 */ + 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 */ + 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY; - return BODY_SIGN__BODY; + return BODY_SIGN__BODY; } -#endif } 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. + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *pRightStartOfSegment; - UCHAR readDirection; - UINT *pSegmentBitfield; - UINT *pCodewordBitfield; - UINT segmentOffset; - - UCHAR *pCntSign; - FIXP_DBL *pResultBase; - USHORT *iResultPointer; - UINT codewordOffset; - UCHAR carryBit; - UINT iQSC; - UCHAR cntSign; + 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; - - pCntSign = pHcr->nonPcwSideinfo.pCntSign; - pResultBase = pHcr->nonPcwSideinfo.pResultBase; - iResultPointer = pHcr->nonPcwSideinfo.iResultPointer; - codewordOffset = pHcr->nonPcwSideinfo.codewordOffset; - iQSC = iResultPointer[codewordOffset]; - cntSign = pCntSign[codewordOffset]; - - + 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, - &pLeftStartOfSegment[segmentOffset], + for (; pRemainingBitsInSegment[segmentOffset] > 0; + pRemainingBitsInSegment[segmentOffset] -= 1) { + carryBit = HcrGetABitFromBitstream(bs, &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 ) { - iQSC++; /* points to current value different from zero */ - if (iQSC >= 1024) { + 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 */ + /* 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 */ + 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 */ - } + 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 */ + 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN; - return BODY_SIGN__SIGN; + return BODY_SIGN__SIGN; } -#endif } 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 + 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. + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *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; + 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, - &pLeftStartOfSegment[segmentOffset], + 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, &pLeftStartOfSegment[segmentOffset], &pRightStartOfSegment[segmentOffset], - readDirection); + readDirection); /* make a step in tree */ - CarryBitToBranchValue(carryBit, - treeNode, - &branchValue, - &branchNode); + 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 */ + /* 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 */ + /* 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] */ + /* 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 ) { + 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 */ + if (cntSign == 0) { + ClearBitFromBitfield( + &(pHcr->nonPcwSideinfo.pState), segmentOffset, + pCodewordBitfield); /* clear a bit in bitfield and switch off + statemachine */ /* codeword decoded */ - } - else { + } 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 */ + 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 */ + 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY; - return BODY_SIGN_ESC__BODY; + return BODY_SIGN_ESC__BODY; } -#endif } 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. + 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. + 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: + 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 + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *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; + 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]; - + 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, - &pLeftStartOfSegment[segmentOffset], + for (; pRemainingBitsInSegment[segmentOffset] > 0; + pRemainingBitsInSegment[segmentOffset] -= 1) { + carryBit = HcrGetABitFromBitstream(bs, &pLeftStartOfSegment[segmentOffset], &pRightStartOfSegment[segmentOffset], - readDirection); + 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 ) { - iQSC++; + /* 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 */ + /* 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 */ + iQSC++; /* update index to next (maybe valid) value */ iResultPointer[codewordOffset] = iQSC; - if ( cntSign == 0 ) { + if (cntSign == 0) { /* all sign bits are decoded now */ - pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of for loop counter (see above) is done here */ + 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 */ + /* 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 */ + /* 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 = 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 = 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 { + 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 = 0; - flags = flagA << POSITION_OF_FLAG_A; + /* 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 */ + 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 */ + 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 */ + } /* 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 */ + } /* 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN; - return BODY_SIGN_ESC__SIGN; + return BODY_SIGN_ESC__SIGN; } -#endif - } 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. + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *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; + 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, - &pLeftStartOfSegment[segmentOffset], + for (; pRemainingBitsInSegment[segmentOffset] > 0; + pRemainingBitsInSegment[segmentOffset] -= 1) { + carryBit = HcrGetABitFromBitstream(bs, &pLeftStartOfSegment[segmentOffset], &pRightStartOfSegment[segmentOffset], - readDirection); + readDirection); /* count ones and store sum in escapePrefixUp */ - if ( carryBit == 1 ) { - escapePrefixUp += 1; /* update conter for ones */ + 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 */ - escapePrefixUp >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back down */ - - pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */ - pHcr->nonPcwSideinfo.pState = aStateConstant2State[pSta[codewordOffset]]; /* get state from separate array of cw-sideinfo */ + 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX; - return BODY_SIGN_ESC__ESC_PREFIX; + return BODY_SIGN_ESC__ESC_PREFIX; } -#endif } 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. + 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. + 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) -{ +-------------------------------------------------------------------------------------------- +*/ +UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) { H_HCR_INFO pHcr = (H_HCR_INFO)ptr; - SCHAR *pRemainingBitsInSegment; - USHORT *pLeftStartOfSegment; - USHORT *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; + 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; - + 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, - &pLeftStartOfSegment[segmentOffset], + for (; pRemainingBitsInSegment[segmentOffset] > 0; + pRemainingBitsInSegment[segmentOffset] -= 1) { + carryBit = HcrGetABitFromBitstream(bs, &pLeftStartOfSegment[segmentOffset], &pRightStartOfSegment[segmentOffset], - readDirection); + 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 */ + 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 */ + /* 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 */ - + 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 */ - + 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 */ + 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 */ + /* 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 */ + 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; + escapePrefixUp = + (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >> + LSB_ESCAPE_PREFIX_UP; /* step 2 */ /* calculate escape value */ - pResultBase[iQSC] = (FIXP_DBL)(sign * (((INT) 1 << escapePrefixUp) + escapeWord)); + pResultBase[iQSC] = + (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord)); - /* get both flags from sideinfo (flags are not shifted to the lsb-position) */ + /* 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; @@ -1361,49 +1498,51 @@ UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) 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 */ + 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 */ + /* 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 { + 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 */ + 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 */ + } 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) { + ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset, + pSegmentBitfield); /* clear a bit in bitfield and + switch off statemachine */ -#if STATE_MACHINE_ERROR_CHECK - if ( pRemainingBitsInSegment[segmentOffset] < 0 ) { + if (pRemainingBitsInSegment[segmentOffset] < 0) { pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD; - return BODY_SIGN_ESC__ESC_WORD; + return BODY_SIGN_ESC__ESC_WORD; } -#endif } return STOP_THIS_STATE; } - diff --git a/libAACdec/src/aacdec_hcrs.h b/libAACdec/src/aacdec_hcrs.h index 678ba26..acb2f40 100644 --- a/libAACdec/src/aacdec_hcrs.h +++ b/libAACdec/src/aacdec_hcrs.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,75 +90,87 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** 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_ - - +#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] */ +/* 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_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__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; */ +/* 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] */ +/* 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 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_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 +#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_ */ +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/libAACdec/src/aacdec_pns.cpp b/libAACdec/src/aacdec_pns.cpp index 541ef07..432cd4e 100644 --- a/libAACdec/src/aacdec_pns.cpp +++ b/libAACdec/src/aacdec_pns.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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" @@ -99,45 +110,38 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" - -#define NOISE_OFFSET 90 /* cf. ISO 14496-3 p. 175 */ +#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 - ) -{ +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)); + FDKmemclear(pPnsData->pnsUsed, (8 * 16) * sizeof(UCHAR)); + FDKmemclear(pPnsInterChannelData->correlated, (8 * 16) * sizeof(UCHAR)); } /*! - \brief Initialize PNS data + \brief Update PNS noise generator state. - The function initializes the PNS data + 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_InitPns( - CPnsData *pPnsData, - CPnsInterChannelData *pPnsInterChannelData, - INT* currentSeed, INT* randomSeed) -{ - /* save pointer to inter channel data */ - pPnsData->pPnsInterChannelData = pPnsInterChannelData; - +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; + pPnsData->randomSeed = randomSeed; } /*! @@ -148,11 +152,8 @@ void CPns_InitPns( \return PNS used */ -int CPns_IsPnsUsed (const CPnsData *pPnsData, - const int group, - const int band) -{ - unsigned pns_band = group*16+band; +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; } @@ -162,13 +163,10 @@ int CPns_IsPnsUsed (const CPnsData *pPnsData, The function activates the noise correlation between the channel pair */ -void CPns_SetCorrelation(CPnsData *pPnsData, - const int group, - const int band, - const int outofphase) -{ +void CPns_SetCorrelation(CPnsData *pPnsData, const int group, const int band, + const int outofphase) { CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData; - unsigned pns_band = group*16+band; + unsigned pns_band = group * 16 + band; pInterChannelData->correlated[pns_band] = (outofphase) ? 3 : 1; } @@ -181,13 +179,10 @@ void CPns_SetCorrelation(CPnsData *pPnsData, \return PNS is correlated */ -static -int CPns_IsCorrelated(const CPnsData *pPnsData, - const int group, - const int band) -{ +static int CPns_IsCorrelated(const CPnsData *pPnsData, const int group, + const int band) { CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData; - unsigned pns_band = group*16+band; + unsigned pns_band = group * 16 + band; return (pInterChannelData->correlated[pns_band] & 0x01) ? 1 : 0; } @@ -200,13 +195,10 @@ int CPns_IsCorrelated(const CPnsData *pPnsData, \return PNS is out-of-phase */ -static -int CPns_IsOutOfPhase(const CPnsData *pPnsData, - const int group, - const int band) -{ +static int CPns_IsOutOfPhase(const CPnsData *pPnsData, const int group, + const int band) { CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData; - unsigned pns_band = group*16+band; + unsigned pns_band = group * 16 + band; return (pInterChannelData->correlated[pns_band] & 0x02) ? 1 : 0; } @@ -216,36 +208,30 @@ int CPns_IsOutOfPhase(const CPnsData *pPnsData, 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; +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; + delta = CBlock_DecodeHuffmanWord(bs, hcb) - 60; } else { /* First PNS band case */ - int noiseStartValue = FDKreadBits(bs,9); + int noiseStartValue = FDKreadBits(bs, 9); - delta = noiseStartValue - 256 ; + delta = noiseStartValue - 256; pPnsData->PnsActive = 1; pPnsData->CurrentEnergy = global_gain - NOISE_OFFSET; } - pPnsData->CurrentEnergy += delta ; + 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 @@ -254,32 +240,29 @@ void CPns_Read (CPnsData *pPnsData, * \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) -{ +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 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 = (1664525L * randomState) + 1013904223L; // Numerical Recipes - nrg_m = fPow2AddDiv2(nrg_m, (FIXP_DBL)randomState>>GEN_NOISE_NRG_SCALE); + 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; + 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); + invNrg_m = invSqrtNorm2(nrg_m << 1, &invNrg_e); + invNrg_e += -((nrg_e - 1) >> 1); - for (i=size; i--; ) - { + for (i = size; i--;) { spec[i] = fMult(spec[i], invNrg_m); } @@ -289,8 +272,8 @@ static int GenerateRandomVector (FIXP_DBL *RESTRICT spec, return invNrg_e; } -static void ScaleBand (FIXP_DBL *RESTRICT spec, int size, int scaleFactor, int specScale, int noise_e, int out_of_phase) -{ +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; @@ -308,20 +291,19 @@ static void ScaleBand (FIXP_DBL *RESTRICT spec, int size, int scaleFactor, int s 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; + 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; + shift = fixMin(-shift, DFRACT_BITS - 1); + for (i = size; i-- != 0;) { + spec[i] = fMultDiv2(spec[i], sfMatissa) >> shift; } } } - /*! \brief Apply PNS @@ -329,51 +311,48 @@ static void ScaleBand (FIXP_DBL *RESTRICT spec, int size, int scaleFactor, int s 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) -{ +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); + 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++) { + 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 = group*16+band; + 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 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 ; + 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) ; + noise_e = GenerateRandomVector(spectrum + BandOffsets[band], + bandWidth, pPnsData->currentSeed); } - int outOfPhase = CPns_IsOutOfPhase (pPnsData, group, band); + int outOfPhase = CPns_IsOutOfPhase(pPnsData, group, band); - ScaleBand (spectrum + BandOffsets [band], bandWidth, - pScaleFactor[pns_band], - pSpecScale[window], noise_e, outOfPhase) ; + ScaleBand(spectrum + BandOffsets[band], bandWidth, + pScaleFactor[group * 16 + band], pSpecScale[window], + noise_e, outOfPhase); } } } diff --git a/libAACdec/src/aacdec_pns.h b/libAACdec/src/aacdec_pns.h index fc9bdcb..45cd989 100644 --- a/libAACdec/src/aacdec_pns.h +++ b/libAACdec/src/aacdec_pns.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,22 +90,22 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: perceptual noise substitution tool -******************************************************************************/ +*******************************************************************************/ -#ifndef PNS_H -#define PNS_H +#ifndef AACDEC_PNS_H +#define AACDEC_PNS_H #include "common_fix.h" - -#define NO_OFBANDS ((8*16)) +#define NO_OFBANDS ((8 * 16)) typedef struct { UCHAR correlated[NO_OFBANDS]; @@ -102,19 +113,17 @@ typedef struct { typedef struct { CPnsInterChannelData *pPnsInterChannelData; - UCHAR pnsUsed[NO_OFBANDS]; - int CurrentEnergy; - UCHAR PnsActive; - INT *currentSeed; - INT *randomSeed; + UCHAR pnsUsed[NO_OFBANDS]; + int CurrentEnergy; + UCHAR PnsActive; + INT *currentSeed; + INT *randomSeed; } CPnsData; -void CPns_InitPns ( CPnsData *pPnsData, - CPnsInterChannelData *pPnsInterChannelData, - INT* currentSeed, - INT* randomSeed ); - -void CPns_ResetData ( CPnsData *pPnsData, CPnsInterChannelData *pPnsInterChannelData ); +void CPns_UpdateNoiseState(CPnsData *pPnsData, INT *currentSeed, + INT *randomSeed); +void CPns_ResetData(CPnsData *pPnsData, + CPnsInterChannelData *pPnsInterChannelData); -#endif /* #ifndef PNS_H */ +#endif /* #ifndef AACDEC_PNS_H */ diff --git a/libAACdec/src/aacdec_tns.cpp b/libAACdec/src/aacdec_tns.cpp index 352f04a..fb3fe33 100644 --- a/libAACdec/src/aacdec_tns.cpp +++ b/libAACdec/src/aacdec_tns.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,21 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 @@ -102,19 +116,20 @@ amm-info@iis.fraunhofer.de \return none */ -void CTns_Reset(CTnsData *pTnsData) -{ +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)); + 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 */ +void CTns_ReadDataPresentFlag( + HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */ + CTnsData *pTnsData) /*!< pointer to aac decoder channel info */ { - pTnsData->DataPresent = (UCHAR) FDKreadBits(bs,1); + pTnsData->DataPresent = (UCHAR)FDKreadBits(bs, 1); } /*! @@ -125,83 +140,89 @@ void CTns_ReadDataPresentFlag(HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstr \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; +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 = GetWindowsPerFrame(pIcsInfo); - UCHAR isLongFlag = IsLongBlock(pIcsInfo); + UCHAR wins_per_frame; + UCHAR isLongFlag; + UCHAR start_window; AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK; if (!pTnsData->DataPresent) { return ErrorStatus; } - for (window = 0; window < wins_per_frame; window++) { - pTnsData->NumberOfFilters[window] = n_filt = (UCHAR) FDKreadBits(bs, isLongFlag ? 2 : 1); + start_window = 0; + wins_per_frame = GetWindowsPerFrame(pIcsInfo); + isLongFlag = IsLongBlock(pIcsInfo); + } - if (pTnsData->NumberOfFilters[window] > TNS_MAXIMUM_FILTERS){ - pTnsData->NumberOfFilters[window] = n_filt = TNS_MAXIMUM_FILTERS; - } + pTnsData->GainLd = 0; - if (n_filt) - { + 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); + coef_res = (UCHAR)FDKreadBits(bs, 1); nextstopband = GetScaleFactorBandsTotal(pIcsInfo); - for (index=0; index < n_filt; index++) - { + for (index = 0; index < n_filt; index++) { CFilter *filter = &pTnsData->Filter[window][index]; length = (UCHAR)FDKreadBits(bs, isLongFlag ? 6 : 4); - if (length > nextstopband){ + if (length > nextstopband) { length = nextstopband; } filter->StartBand = nextstopband - length; - filter->StopBand = nextstopband; + filter->StopBand = nextstopband; nextstopband = filter->StartBand; - { - filter->Order = order = (UCHAR) FDKreadBits(bs, isLongFlag ? 5 : 3); - } + 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){ - filter->Order = order = TNS_MAXIMUM_ORDER; + if (filter->Order > TNS_MAXIMUM_ORDER) { + ErrorStatus = AAC_DEC_TNS_READ_ERROR; + return ErrorStatus; + } } - if (order) - { - UCHAR coef,s_mask; + 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; + static const UCHAR sgn_mask[] = {0x2, 0x4, 0x8}; + static const SCHAR neg_mask[] = {~0x3, ~0x7, ~0xF}; - coef_compress = (UCHAR) FDKreadBits(bs,1); + 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); + 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; } } } @@ -212,201 +233,129 @@ AAC_DECODER_ERROR CTns_Read(HANDLE_FDK_BITSTREAM bs, 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; -static void CTns_Filter (FIXP_DBL *spec, int size, int inc, FIXP_TCC coeff [], int order) -{ - // - Simple all-pole filter of order "order" defined by - // y(n) = x(n) - a(2)*y(n-1) - ... - a(order+1)*y(n-order) - // - // - The state variables of the filter are initialized to zero every time - // - // - The output data is written over the input data ("in-place operation") - // - // - An input vector of "size" samples is processed and the index increment - // to the next data sample is given by "inc" - - int i,j,N; - FIXP_DBL *pSpec; - FIXP_DBL maxVal=FL2FXCONST_DBL(0.0); - INT s; - - FDK_ASSERT(order <= TNS_MAXIMUM_ORDER); - C_ALLOC_SCRATCH_START(state, FIXP_DBL, TNS_MAXIMUM_ORDER); - FDKmemclear(state, order*sizeof(FIXP_DBL)); - - for (i=0; i<size; i++) { - maxVal = fixMax(maxVal,fixp_abs(spec[i])); + 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; + } + } +} - if ( maxVal > FL2FXCONST_DBL(0.03125*0.70710678118) ) - s = fixMax(CntLeadingZeros(maxVal)-6,0); - else - s = fixMax(CntLeadingZeros(maxVal)-5,0); - - s = fixMin(s,2); - s = s-1; - - if (inc == -1) - pSpec = &spec[size - 1]; - else - pSpec = &spec[0]; - - FIXP_TCC *pCoeff; - -#define FIRST_PART_FLTR \ - FIXP_DBL x, *pState = state; \ - pCoeff = coeff; \ - \ - if (s < 0) \ - x = (pSpec [0]>>1) + fMultDiv2 (*pCoeff++, pState [0]) ; \ - else \ - x = (pSpec [0]<<s) + fMultDiv2 (*pCoeff++, pState [0]) ; - -#define INNER_FLTR_INLINE \ - x = fMultAddDiv2 (x, *pCoeff, pState [1]); \ - pState [0] = pState [1] - (fMultDiv2 (*pCoeff++, x) <<2) ; \ - pState++; - -#define LAST_PART_FLTR \ - if (s < 0) \ - *pSpec = x << 1; \ - else \ - *pSpec = x >> s; \ - *pState =(-x) << 1; \ - pSpec += inc ; - - - if (order>8) - { - N = (order-1)&7; - - for (i = size ; i != 0 ; i--) - { - FIRST_PART_FLTR - - for (j = N; j > 0 ; j--) { INNER_FLTR_INLINE } - - INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE - INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE +/*! + \brief Apply tns to spectral lines - LAST_PART_FLTR - } + The function applies the tns to the spectrum, - } else if (order>4) { + \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; - N = (order-1)&3; + if (pTnsData->Active) { + C_AALLOC_SCRATCH_START(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER) - for (i = size ; i != 0 ; i--) - { - FIRST_PART_FLTR - for (j = N; j > 0 ; j--) { INNER_FLTR_INLINE } + { + start_window = 0; + wins_per_frame = GetWindowsPerFrame(pIcsInfo); + } - INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE INNER_FLTR_INLINE + for (window = start_window; window < wins_per_frame; window++) { + FIXP_DBL *pSpectrum; - LAST_PART_FLTR - } + { pSpectrum = SPEC(pSpectralCoefficient, window, granuleLength); } - } else { + for (index = 0; index < pTnsData->NumberOfFilters[window]; index++) { + CFilter *filter = &pTnsData->Filter[window][index]; - N = order-1; + 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]; + } - for (i = size ; i != 0 ; i--) - { - FIRST_PART_FLTR + 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; + } - for (j = N; j > 0 ; j--) { INNER_FLTR_INLINE } + start = fixMin(fixMin(filter->StartBand, tns_max_bands), nbands); - LAST_PART_FLTR - } - } + start = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[start]; - C_ALLOC_SCRATCH_END(state, FIXP_DBL, TNS_MAXIMUM_ORDER); -} + if (igf_active) { + stop = fixMin(filter->StopBand, nbands); + } else { + stop = fixMin(fixMin(filter->StopBand, tns_max_bands), nbands); + } -/*! - \brief Apply tns to spectral lines + stop = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[stop]; - The function applies the tns to the spectrum, + size = stop - start; - \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 - ) -{ - int window,index,start,stop,size; + 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); - if (pTnsData->Active) - { - C_AALLOC_SCRATCH_START(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER); - - for (window=0; window < GetWindowsPerFrame(pIcsInfo); window++) - { - FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window, granuleLength); - - for (index=0; index < pTnsData->NumberOfFilters[window]; index++) - { - CFilter *RESTRICT filter = &pTnsData->Filter[window][index]; - - if (filter->Order > 0) - { - FIXP_TCC *pCoeff; - int tns_max_bands; - - pCoeff = &coeff[filter->Order-1]; - 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); - break; - } - - start = fixMin( fixMin(filter->StartBand, tns_max_bands), - GetScaleFactorBandsTransmitted(pIcsInfo) ); - - start = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[start]; - - stop = fixMin( fixMin(filter->StopBand, tns_max_bands), - GetScaleFactorBandsTransmitted(pIcsInfo) ); - - stop = GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo)[stop]; - - size = stop - start; - - if (size > 0) { - CTns_Filter(&pSpectrum[start], - size, - filter->Direction, - coeff, - filter->Order ); - } + C_ALLOC_SCRATCH_END(state, FIXP_DBL, TNS_MAXIMUM_ORDER) } } } - C_AALLOC_SCRATCH_END(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER); + } + C_AALLOC_SCRATCH_END(coeff, FIXP_TCC, TNS_MAXIMUM_ORDER) } - } diff --git a/libAACdec/src/aacdec_tns.h b/libAACdec/src/aacdec_tns.h index f029d96..1a63bed 100644 --- a/libAACdec/src/aacdec_tns.h +++ b/libAACdec/src/aacdec_tns.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,29 +90,37 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: temporal noise shaping tool -******************************************************************************/ +*******************************************************************************/ -#ifndef TNS_H -#define TNS_H +#ifndef AACDEC_TNS_H +#define AACDEC_TNS_H #include "common_fix.h" -enum -{ - TNS_MAX_WINDOWS = 8, /* 8 */ - TNS_MAXIMUM_ORDER = 20, /* 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 :( */ +enum { + TNS_MAX_WINDOWS = 8, /* 8 */ TNS_MAXIMUM_FILTERS = 3 }; -typedef struct -{ +/* 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; @@ -113,14 +132,18 @@ typedef struct UCHAR Order; } CFilter; -typedef struct -{ +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 TNS_H */ +#endif /* #ifndef AACDEC_TNS_H */ diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 579e470..64adb56 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,60 +90,68 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl - Description: -******************************************************************************/ + 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. + 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. + 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 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. + 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. + 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, + 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. + 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. + 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 + The filterbank is called using CBlock_FrequencyToTime() using the MDCT module + from the FDK Tools */ - - #include "aacdecoder.h" #include "aac_rom.h" @@ -140,54 +159,155 @@ amm-info@iis.fraunhofer.de #include "channel.h" #include "FDK_audio.h" -#include "FDK_tools_rom.h" - - #include "aacdec_pns.h" - - #include "sbrdecoder.h" +#include "aacdec_pns.h" +#include "sbrdecoder.h" +#include "sac_dec_lib.h" +#include "aacdec_hcr.h" +#include "rvlc.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" +#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) -{ +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 ( self->qmfModeCurr == NOT_DEFINED ) - { - if ( (IS_LOWDELAY(self->streamInfo.aot) && (self->flags & AC_MPS_PRESENT)) - || ( (self->streamInfo.aacNumChannels == 1) - && ( (CAN_DO_PS(self->streamInfo.aot) && !(self->flags & AC_MPS_PRESENT)) - || ( IS_USAC(self->streamInfo.aot) && (self->flags & AC_MPS_PRESENT)) ) ) ) - { + 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; + } + } /* Fall-through: */ + 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) && self->streamInfo.aacNumChannels == 1 && ! (self->flags & AC_MPS_PRESENT))) && self->qmfModeCurr == MODE_HQ ; - FDK_ASSERT( ! ( (self->flags & AC_MPS_PRESENT) && self->psPossible ) ); + 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) -{ +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; } /*! @@ -197,11 +317,9 @@ void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self) \return Error code */ -static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) -{ +static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) { int i; - for (i=0; i<8; i++) - { + for (i = 0; i < 8; i++) { ancData->offset[i] = 0; } ancData->nrElements = 0; @@ -218,8 +336,8 @@ static AAC_DECODER_ERROR CAacDecoder_AncDataReset(CAncData *ancData) \return Error code */ -AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, unsigned char *buffer, int size) -{ +AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, + unsigned char *buffer, int size) { if (size >= 0) { ancData->buffer = buffer; ancData->bufferSize = size; @@ -238,27 +356,26 @@ AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, unsigned char *buff \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 + \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 CAacDecoder_AncDataGet(CAncData *ancData, int index, + unsigned char **ptr, int *size) { AAC_DECODER_ERROR error = AAC_DEC_OK; - *ptr = NULL; + *ptr = NULL; *size = 0; - if (index >= 0 && index < 8 && index < ancData->nrElements) - { - *ptr = &ancData->buffer[ancData->offset[index]]; - *size = ancData->offset[index+1] - ancData->offset[index]; + 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 @@ -268,40 +385,32 @@ AAC_DECODER_ERROR CAacDecoder_AncDataGet(CAncData *ancData, int index, unsigned \return Error code */ -static -AAC_DECODER_ERROR CAacDecoder_AncDataParse ( - CAncData *ancData, - HANDLE_FDK_BITSTREAM hBs, - const int ancBytes ) -{ +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 (ancData->buffer != NULL) { if (ancBytes > 0) { /* write ancillary data to external buffer */ int offset = ancData->offset[ancData->nrElements]; - if ((offset + ancBytes) > ancData->bufferSize) - { + if ((offset + ancBytes) > ancData->bufferSize) { error = AAC_DEC_TOO_SMALL_ANC_BUFFER; - } - else if (ancData->nrElements >= 8-1) - { + } else if (ancData->nrElements >= 8 - 1) { error = AAC_DEC_TOO_MANY_ANC_ELEMENTS; - } - else - { + } else { int i; for (i = 0; i < ancBytes; i++) { - ancData->buffer[i+offset] = FDKreadBits(hBs, 8); + ancData->buffer[i + offset] = FDKreadBits(hBs, 8); readBytes++; } ancData->nrElements++; - ancData->offset[ancData->nrElements] = ancBytes + ancData->offset[ancData->nrElements-1]; + ancData->offset[ancData->nrElements] = + ancBytes + ancData->offset[ancData->nrElements - 1]; } } } @@ -310,7 +419,7 @@ AAC_DECODER_ERROR CAacDecoder_AncDataParse ( if (readBytes > 0) { /* skip data */ - FDKpushFor(hBs, readBytes<<3); + FDKpushFor(hBs, readBytes << 3); } return error; @@ -323,36 +432,29 @@ AAC_DECODER_ERROR CAacDecoder_AncDataParse ( \return Error code */ -static AAC_DECODER_ERROR CDataStreamElement_Read ( - HANDLE_AACDECODER self, - HANDLE_FDK_BITSTREAM bs, - UCHAR *elementInstanceTag, - UINT alignmentAnchor ) -{ - HANDLE_TRANSPORTDEC pTp; - CAncData *ancData; +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 dataStart, dseBits; int dataByteAlignFlag, count; FDK_ASSERT(self != NULL); - ancData = &self->ancData; - pTp = self->hInput; - - int crcReg = transportDec_CrcStartReg(pTp, 0); + int crcReg = transportDec_CrcStartReg(self->hInput, 0); /* Element Instance Tag */ - *elementInstanceTag = FDKreadBits(bs,4); + *elementInstanceTag = FDKreadBits(bs, 4); /* Data Byte Align Flag */ - dataByteAlignFlag = FDKreadBits(bs,1); + dataByteAlignFlag = FDKreadBits(bs, 1); - count = FDKreadBits(bs,8); + count = FDKreadBits(bs, 8); if (count == 255) { - count += FDKreadBits(bs,8); /* EscCount */ + count += FDKreadBits(bs, 8); /* EscCount */ } - dseBits = count*8; + dseBits = count * 8; if (dataByteAlignFlag) { FDKbyteAlign(bs, alignmentAnchor); @@ -360,38 +462,37 @@ static AAC_DECODER_ERROR CDataStreamElement_Read ( dataStart = FDKgetValidBits(bs); - error = CAacDecoder_AncDataParse(ancData, bs, count); - transportDec_CrcEndReg(pTp, crcReg); + error = CAacDecoder_AncDataParse(&self->ancData, bs, count); + transportDec_CrcEndReg(self->hInput, crcReg); { - /* Move to the beginning of the data junk */ - FDKpushBack(bs, dataStart-FDKgetValidBits(bs)); + /* Move to the beginning of the data chunk */ + FDKpushBack(bs, dataStart - FDKgetValidBits(bs)); /* Read Anc data if available */ - aacDecoder_drcMarkPayload( self->hDrcInfo, bs, DVB_DRC_ANC_DATA ); + aacDecoder_drcMarkPayload(self->hDrcInfo, bs, DVB_DRC_ANC_DATA); } { PCMDMX_ERROR dmxErr = PCMDMX_OK; - /* Move to the beginning of the data junk */ - FDKpushBack(bs, dataStart-FDKgetValidBits(bs)); + /* Move to the beginning of the data chunk */ + FDKpushBack(bs, dataStart - FDKgetValidBits(bs)); /* Read DMX meta-data */ - dmxErr = pcmDmx_Parse ( - self->hPcmUtils, - bs, - dseBits, - 0 /* not mpeg2 */ ); + 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, FDKgetValidBits(bs)-dataStart+dseBits); + FDKpushBiDirectional( + bs, (INT)FDKgetValidBits(bs) - (INT)dataStart + (INT)dseBits); return error; } -#ifdef TP_PCE_ENABLE /*! \brief Read Program Config Element @@ -401,15 +502,14 @@ static AAC_DECODER_ERROR CDataStreamElement_Read ( \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). + \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 ) -{ +static int CProgramConfigElement_Read(HANDLE_FDK_BITSTREAM bs, + HANDLE_TRANSPORTDEC pTp, + CProgramConfig *pce, + const UINT channelConfig, + const UINT alignAnchor) { int pceStatus = 0; int crcReg; @@ -417,7 +517,6 @@ static int CProgramConfigElement_Read ( C_ALLOC_SCRATCH_START(tmpPce, CProgramConfig, 1); CProgramConfig_Init(tmpPce); - CProgramConfig_Reset(tmpPce); crcReg = transportDec_CrcStartReg(pTp, 0); @@ -425,35 +524,34 @@ static int CProgramConfigElement_Read ( transportDec_CrcEndReg(pTp, crcReg); - if ( CProgramConfig_IsValid(tmpPce) - && (tmpPce->Profile == 1) ) - { - if ( !pce->isValid && (channelConfig > 0) ) { + 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 ); + CProgramConfig_GetDefault(pce, channelConfig); } - if (pce->isValid) { + 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 */ - if (channelConfig == 0) { - FDKmemcpy(pce, tmpPce, sizeof(CProgramConfig)); /* Store the complete PCE */ - pceStatus = 2; /* Decoder needs re-configuration */ - } - break; - 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; + 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 */ + if (channelConfig == 0) { + FDKmemcpy(pce, tmpPce, + sizeof(CProgramConfig)); /* Store the complete PCE */ + pceStatus = 2; /* Decoder needs re-configuration */ + } + break; + 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; } } } @@ -462,7 +560,243 @@ static int CProgramConfigElement_Read ( return pceStatus; } -#endif /* TP_PCE_ENABLE */ + +/*! + \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 - 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 @@ -473,14 +807,9 @@ static int CProgramConfigElement_Read ( \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) -{ +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; @@ -492,182 +821,274 @@ AAC_DECODER_ERROR CAacDecoder_ExtPayloadParse (HANDLE_AACDECODER self, return AAC_DEC_DECODE_FRAME_ERROR; } - extension_type = (EXT_PAYLOAD_TYPE) FDKreadBits(hBs, 4); /* bs_extension_type */ + extension_type = + (EXT_PAYLOAD_TYPE)FDKreadBits(hBs, 4); /* bs_extension_type */ *count -= 4; - switch (extension_type) - { - case EXT_DYNAMIC_RANGE: - { - INT readBits = aacDecoder_drcMarkPayload( self->hDrcInfo, hBs, MPEG_DRC_EXT_DATA ); + /* 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 */ + } - if (readBits > *count) - { /* Read too much. Something went wrong! */ + 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; + } 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; + } - case EXT_SBR_DATA_CRC: - crcFlag = 1; - case EXT_SBR_DATA: - if (IS_CHANNEL_ELEMENT(previous_element)) { - SBR_ERROR sbrError; + 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; - CAacDecoder_SyncQmfMode(self); + if (self->flags[0] & AC_PS_PRESENT) { + error = AAC_DEC_PARSE_ERROR; + goto bail; + } - sbrError = sbrDecoder_InitElement( - self->hSbrDecoder, - self->streamInfo.aacSampleRate, - self->streamInfo.extSamplingRate, - self->streamInfo.aacSamplesPerFrame, - self->streamInfo.aot, - previous_element, - elIndex - ); - - if (sbrError == SBRDEC_OK) { - sbrError = sbrDecoder_Parse ( - self->hSbrDecoder, - hBs, - count, - *count, - crcFlag, - previous_element, - elIndex, - self->flags & AC_INDEP ); - /* Enable SBR for implicit SBR signalling but only if no severe error happend. */ - if ( (sbrError == SBRDEC_OK) - || (sbrError == SBRDEC_PARSE_ERROR) ) { - self->sbrEnabled = 1; + /* 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; } - } 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); + /* 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; - } 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; + } + break; + + case EXT_SBR_DATA_CRC: + crcFlag = 1; + 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; } - } else { - error = AAC_DEC_PARSE_ERROR; - } - break; + break; - case EXT_FILL_DATA: - { + case EXT_FILL_DATA: { int temp; - temp = FDKreadBits(hBs,4); + temp = FDKreadBits(hBs, 4); bytes--; if (temp != 0) { error = AAC_DEC_PARSE_ERROR; break; } while (bytes > 0) { - temp = FDKreadBits(hBs,8); + temp = FDKreadBits(hBs, 8); bytes--; if (temp != 0xa5) { error = AAC_DEC_PARSE_ERROR; break; } } - *count = bytes<<3; - } - break; + *count = bytes << 3; + } break; - case EXT_DATA_ELEMENT: - { + case EXT_DATA_ELEMENT: { int dataElementVersion; - dataElementVersion = FDKreadBits(hBs,4); + dataElementVersion = FDKreadBits(hBs, 4); *count -= 4; if (dataElementVersion == 0) /* ANC_DATA */ { int temp, dataElementLength = 0; do { - temp = FDKreadBits(hBs,8); + temp = FDKreadBits(hBs, 8); *count -= 8; dataElementLength += temp; - } while (temp == 255 ); + } while (temp == 255); CAacDecoder_AncDataParse(&self->ancData, hBs, dataElementLength); - *count -= (dataElementLength<<3); + *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 & 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; + } 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; + if (add_len == 255) { + len += FDKreadBits(hBs, 16); + *count -= 16; + } } - } - len <<= 3; - bitCnt = len; + 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; - } else { - /* rewind and call myself again. */ - FDKpushBack(hBs, 4); + 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, - 0 ); + error = CAacDecoder_ExtPayloadParse( + self, hBs, &bitCnt, previous_element, elIndex, + 1); /* Treat same as fill element */ - *count -= len - bitCnt; + *count -= len - bitCnt; + } + /* Note: the fall through in case the if statement above is not taken is + * intentional. */ + break; } - /* Note: the fall through in case the if statement above is not taken is intentional. */ - break; - } - case EXT_FIL: + case EXT_FIL: - default: - /* align = 4 */ - FDKpushFor(hBs, *count); - *count = 0; - break; + default: + /* align = 4 */ + FDKpushFor(hBs, *count); + *count = 0; + break; } bail: - if ( (error != AAC_DEC_OK) - && fIsFillElement ) - { /* Skip the remaining extension bytes */ + if ((error != AAC_DEC_OK) && + fIsFillElement) { /* Skip the remaining extension bytes */ FDKpushBiDirectional(hBs, *count); *count = 0; /* Patch error code because decoding can go on. */ @@ -677,15 +1098,107 @@ bail: 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 ((bitCnt > 0) && (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]; + + if (self->flags[0] & AC_USAC) { + chElIdx = numChElements - 1; + } else { + chElIdx = 0; /* ELD case */ + } + + for (; chElIdx < numChElements; chElIdx += 1) { + MP4_ELEMENT_ID sbrType; + 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]; + err = sbrDecoder_Parse(self->hSbrDecoder, bs, self->pDrmBsBuffer, + self->drmBsBufferSize, &bitCnt, -1, + self->flags[0] & AC_SBRCRC, sbrType, chElIdx, + self->flags[0], self->elFlags); + if (err != SBRDEC_OK) { + break; + } + } + 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, bitCnt); + 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. + 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) -{ +static void CStreamInfoInit(CStreamInfo *pStreamInfo) { pStreamInfo->aacSampleRate = 0; pStreamInfo->profile = -1; pStreamInfo->aot = AOT_NONE; @@ -694,12 +1207,12 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo) pStreamInfo->bitRate = 0; pStreamInfo->aacSamplesPerFrame = 0; - pStreamInfo->extAot = AOT_NONE; + pStreamInfo->extAot = AOT_NONE; pStreamInfo->extSamplingRate = 0; pStreamInfo->flags = 0; - pStreamInfo->epConfig = -1; /* default is no ER */ + pStreamInfo->epConfig = -1; /* default: no ER */ pStreamInfo->numChannels = 0; pStreamInfo->sampleRate = 0; @@ -708,21 +1221,24 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo) pStreamInfo->outputDelay = 0; /* DRC */ - pStreamInfo->drcProgRefLev = -1; /* set program reference level to not indicated */ - pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */ + 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 + 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,...). */ +LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open( + TRANSPORT_TYPE bsFormat) /*!< bitstream format (adif,adts,loas,...). */ { HANDLE_AACDECODER self; @@ -731,12 +1247,14 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(TRANSPORT_TYPE bsFormat) /*!< goto bail; } - /* Assign channel mapping info arrays (doing so removes dependency of settings header in API header). */ + 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; - - /* set default output mode */ - self->outputInterleaved = 1; /* interleaved */ + self->downscaleFactor = 1; + self->downscaleFactorInBS = 1; /* initialize anc data */ CAacDecoder_AncDataInit(&self->ancData, NULL, 0); @@ -744,75 +1262,208 @@ LINKSPEC_CPP HANDLE_AACDECODER CAacDecoder_Open(TRANSPORT_TYPE bsFormat) /*!< /* 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 ); + aacDecoder_drcInit(self->hDrcInfo); /* Set default frame delay */ - aacDecoder_drcSetParam ( - self->hDrcInfo, - DRC_BS_DELAY, - CConcealment_GetDelay(&self->concealCommonData) - ); + aacDecoder_drcSetParam(self->hDrcInfo, DRC_BS_DELAY, + CConcealment_GetDelay(&self->concealCommonData)); + self->workBufferCore2 = GetWorkBufferCore2(); + if (self->workBufferCore2 == NULL) goto bail; - self->aacCommonData.workBufferCore1 = GetWorkBufferCore1(); - self->aacCommonData.workBufferCore2 = GetWorkBufferCore2(); - if (self->aacCommonData.workBufferCore1 == NULL - ||self->aacCommonData.workBufferCore2 == NULL ) + /* 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 ); + CAacDecoder_Close(self); return NULL; } -/* Destroy aac decoder */ -LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) -{ +/* 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; - if (self == NULL) - return; + { + self->ascChannels[0] = 0; + self->elements[0] = ID_END; + } - for (ch=0; ch<(8); ch++) { + 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); + FreeOverlapBuffer( + &self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer); } - if (self->pAacDecoderStaticChannelInfo[ch] != NULL) { - FreeAacDecoderStaticChannelInfo (&self->pAacDecoderStaticChannelInfo[ch]); + 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]); + 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); } - if (self->aacCommonData.workBufferCore1 != NULL) { - FreeWorkBufferCore1 (&self->aacCommonData.workBufferCore1); + /* Free WorkBufferCore2 */ + if (self->workBufferCore2 != NULL) { + FreeWorkBufferCore2(&self->workBufferCore2); } - if (self->aacCommonData.workBufferCore2 != NULL) { - FreeWorkBufferCore2 (&self->aacCommonData.workBufferCore2); + if (self->pTimeData2 != NULL) { + FreeWorkBufferCore5(&self->pTimeData2); } - FreeAacDecoder ( &self); -} + FDK_QmfDomain_Close(&self->qmfDomain); + FreeAacDecoder(&self); +} /*! \brief Initialization of decoder instance @@ -821,357 +1472,997 @@ LINKSPEC_CPP void CAacDecoder_Close(HANDLE_AACDECODER self) \return error status: 0 for success, <>0 for unsupported configurations */ -LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, const CSAudioSpecificConfig *asc) -{ +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, ch, ascChanged = 0; + 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; + 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) + // 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; - - 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; - } - - case AOT_SBR: - case AOT_PS: - case AOT_ER_AAC_LD: - case AOT_ER_AAC_ELD: - case AOT_DRM_AAC: - break; - - default: - return AAC_DEC_UNSUPPORTED_AOT; + case AOT_AAC_LC: + self->streamInfo.profile = 1; + 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; + } + 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; } - CProgramConfig_Init(&self->pce); + 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: -#ifdef TP_PCE_ENABLE - /* get channels from program config (ASC) */ - if (CProgramConfig_IsValid(&asc->m_progrConfigElement)) { - ascChannels = asc->m_progrConfigElement.NumChannels; - if (ascChannels > 0) { - int el; - /* valid number of channels -> copy program config element (PCE) from ASC */ - FDKmemcpy(&self->pce, &asc->m_progrConfigElement, sizeof(CProgramConfig)); - /* Built element table */ - el = CProgramConfig_GetElementTable(&asc->m_progrConfigElement, self->elements, (8), &self->chMapIndex); - for (; el<(8); el++) { - self->elements[el] = ID_NONE; - } - } else { - return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + 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; } - } else { - self->chMapIndex = 0; - if (transportDec_GetFormat(self->hInput) == TT_MP4_ADTS) { - /* set default max_channels for memory allocation because in implicit channel mapping mode - we don't know the actual number of channels until we processed at least one raw_data_block(). */ - ascChannels = (8); - } else { - return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + 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; + case 13: /* 22.2 setup */ + ascChannels = 24; + 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 */ + } } } -#else /* TP_PCE_ENABLE */ - return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; -#endif /* TP_PCE_ENABLE */ - 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 (ascChannels > (8)) { - return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + aacChannelsOffset = 0; + aacChannelsOffsetIdx = 0; + elementOffset = 0; + if (configMode & AC_CM_ALLOC_MEM) { + if ((ascChannels <= 0) || + (asc->m_channelConfiguration > AACDEC_MAX_CH_CONF)) { + return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + } + if ((ascChannels + aacChannelsOffsetIdx) > ((8) * 2)) { + return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + } + if ((ascChannels + aacChannelsOffset) > (8)) { + return AAC_DEC_UNSUPPORTED_CHANNELCONFIG; + } } - /* Initialize constant mappings for channel config 1-7 */ - if (asc->m_channelConfiguration > 0) { - int el; - FDKmemcpy(self->elements, elementsTab[asc->m_channelConfiguration-1], sizeof(MP4_ELEMENT_ID)*FDKmin(7,(8))); - for (el=7; el<(8); el++) { - self->elements[el] = ID_NONE; - } - for (ch=0; ch<ascChannels; ch++) { - self->chMapping[ch] = ch; + /* 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; + } } - for (; ch<(8); ch++) { - self->chMapping[ch] = 255; + + { + 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; - } - #ifdef TP_PCE_ENABLE - else { + } 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 ); + pcmDmx_SetMatrixMixdownFromPce( + self->hPcmUtils, asc->m_progrConfigElement.MatrixMixdownIndexPresent, + asc->m_progrConfigElement.MatrixMixdownIndex, + asc->m_progrConfigElement.PseudoSurroundEnable); } } - #endif self->streamInfo.channelConfig = asc->m_channelConfiguration; if (self->streamInfo.aot != asc->m_aot) { - self->streamInfo.aot = asc->m_aot; + if (configMode & AC_CM_ALLOC_MEM) { + self->streamInfo.aot = asc->m_aot; + } ascChanged = 1; } - if (self->streamInfo.aacSamplesPerFrame != (INT)asc->m_samplesPerFrame) { - self->streamInfo.aacSamplesPerFrame = asc->m_samplesPerFrame; + 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; } - self->streamInfo.bitRate = 0; + if ((INT)asc->m_samplesPerFrame % downscaleFactor != 0) { + return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* frameSize/dsf must be an integer + number */ + } - /* Set syntax flags */ - self->flags = 0; + self->streamInfo.bitRate = 0; - self->streamInfo.extAot = asc->m_extensionAudioObjectType; - self->streamInfo.extSamplingRate = asc->m_extensionSamplingFrequency; - self->flags |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; - self->flags |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; - self->sbrEnabled = 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 |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; + self->flags[streamIndex] |= (asc->m_vcb11Flag) ? AC_ER_VCB11 : 0; /* ---------- rvlc ------------ */ - self->flags |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0; + self->flags[streamIndex] |= (asc->m_rvlcFlag) ? AC_ER_RVLC : 0; /* ----------- hcr ------------ */ - self->flags |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; + self->flags[streamIndex] |= (asc->m_hcrFlag) ? AC_ER_HCR : 0; if (asc->m_aot == AOT_ER_AAC_ELD) { - self->flags |= AC_ELD; - self->flags |= (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 |= (asc->m_sc.m_eldSpecificConfig.m_sbrCrcFlag) ? AC_SBRCRC : 0; - self->flags |= (asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) ? AC_LD_MPS : 0; + 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 |= (asc->m_aot == AOT_ER_AAC_LD) ? AC_LD : 0; - self->flags |= (asc->m_epConfig >= 0) ? AC_ER : 0; - if ( asc->m_aot == AOT_DRM_AAC ) { - self->flags |= AC_DRM|AC_SBRCRC|AC_SCALABLE; + 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_AAC_SCAL) - || (asc->m_aot == AOT_ER_AAC_SCAL) ) { - self->flags |= AC_SCALABLE; + if (asc->m_aot == AOT_DRM_AAC) { + self->flags[streamIndex] |= AC_DRM | AC_SBRCRC | AC_SCALABLE; } - - - if (asc->m_sbrPresentFlag) { - self->sbrEnabled = 1; - self->sbrEnabledPrev = 1; + 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_psPresentFlag) { - self->flags |= AC_PS_PRESENT; + 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 */ + 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; + if (asc->m_epConfig > 1) return AAC_DEC_UNSUPPORTED_ER_FORMAT; /* Check if samplerate changed. */ - if (self->streamInfo.aacSampleRate != (INT)asc->m_samplingFrequency) { + if ((self->samplingRateInfo[streamIndex].samplingRate != + asc->m_samplingFrequency) || + (self->streamInfo.aacSamplesPerFrame != + (INT)asc->m_samplesPerFrame / downscaleFactor)) { AAC_DECODER_ERROR error; ascChanged = 1; - /* Update samplerate info. */ - error = getSamplingRateInfo(&self->samplingRateInfo, asc->m_samplesPerFrame, asc->m_samplingFrequencyIndex, asc->m_samplingFrequency); - if (error != AAC_DEC_OK) { - return error; + 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; } - self->streamInfo.aacSampleRate = self->samplingRateInfo.samplingRate; } /* Check if amount of channels has changed. */ - if (self->ascChannels != ascChannels) - { - ascChanged = 1; - - /* Allocate all memory structures for each channel */ - { - for (ch = 0; ch < ascChannels; ch++) { - CAacDecoderDynamicData *aacDecoderDynamicData = &self->aacCommonData.workBufferCore1->pAacDecoderDynamicData[ch%2]; - - /* initialize pointer to CAacDecoderChannelInfo */ - if (self->pAacDecoderChannelInfo[ch] == NULL) { - 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; - } - /* Hook shared work memory into channel data structure */ - self->pAacDecoderChannelInfo[ch]->pDynData = aacDecoderDynamicData; - self->pAacDecoderChannelInfo[ch]->pComData = &self->aacCommonData; - } - - /* Allocate persistent channel memory */ - if (self->pAacDecoderStaticChannelInfo[ch] == NULL) { - 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; - } - self->pAacDecoderChannelInfo[ch]->pSpectralCoefficient = (SPECTRAL_PTR) &self->aacCommonData.workBufferCore2[ch*1024]; - - } - CPns_InitPns(&self->pAacDecoderChannelInfo[ch]->data.aac.PnsData, &self->aacCommonData.pnsInterChannelData, &self->aacCommonData.pnsCurrentSeed, self->aacCommonData.pnsRandomSeed); - } - - if (ascChannels > self->aacChannels) - { - /* Make allocated channel count persistent in decoder context. */ - self->aacChannels = ascChannels; - } - - HcrInitRom(&self->aacCommonData.overlay.aac.erHcrInfo); - setHcrType(&self->aacCommonData.overlay.aac.erHcrInfo, ID_SCE); + 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; + } + if (self->flags[streamIndex] & (AC_ER | AC_LD | AC_ELD)) { + _numElements = (asc->m_channelConfiguration == 7) + ? 8 + : asc->m_channelConfiguration; + } + for (int _el = 0; _el < _numElements; _el++) { + int el_channels = 0; + int el = elementOffset + _el; + + if (self->flags[streamIndex] & + (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) { + FDK_ASSERT(ch < (8) - 1); + 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 = ascChannels; + 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 (ascChanged) { - - /* 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). */ - for (ch = 0; ch < self->aacChannels; 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; - } - mdct_init( &self->pAacDecoderStaticChannelInfo[ch]->IMdct, - self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, - OverlapBufferSize ); - - - /* Reset DRC control data for this channel */ - aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[ch]->drcData ); - - /* 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, - self->streamInfo.aacSamplesPerFrame ); - } + 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; + 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: - aacDecoder_Close( self ); + CAacDecoder_DeInit(self, 0); return AAC_DEC_OUT_OF_MEMORY; } - LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, - const UINT flags, - INT_PCM *pTimeData, - const INT timeDataSize, - const INT interleaved - ) -{ + 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 */ - int chOutMapIdx; /* Output channel mapping index (see comment below) */ + 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 auStartAnchor = (INT)FDKgetValidBits(bs); /* AU start bit buffer position for AU byte alignment */ + INT checkSampleRate = self->streamInfo.aacSampleRate; - self->frameOK = 1; + 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) { + 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++) { + for (ch = 0; ch < (8); ch++) { self->chMapping[ch] = 255; } if (!CProgramConfig_IsValid(pce)) { int el; - for (el=0; el<(8); 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 */ - switch ( self->streamInfo.aacSampleRate ) { + 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 11025: + case 8000: + case 7350: case 48000: case 44100: case 32000: @@ -1179,225 +2470,263 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( case 22050: break; default: - if ( ! (self->flags & (AC_USAC|AC_RSVD50)) ) { + if (!(self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) { return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; } break; } - - if ( flags & AACDEC_CLRHIST ) - { - int ch; - /* Clear history */ - for (ch = 0; ch < self->aacChannels; ch++) { - /* Reset concealment */ - CConcealment_InitChannelData(&self->pAacDecoderStaticChannelInfo[ch]->concealmentInfo, - &self->concealCommonData, - self->streamInfo.aacSamplesPerFrame ); - /* Clear overlap-add buffers to avoid clicks. */ - FDKmemclear(self->pAacDecoderStaticChannelInfo[ch]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL)); - } + 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); + } + } } - - -#ifdef TP_PCE_ENABLE - int pceRead = 0; /* Flag indicating a PCE in the current raw_data_block() */ -#endif - + 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 el_cnt[ID_LAST] = { 0 }; /* element counter ( robustness ) */ - - while ( (type != ID_END) && (! (flags & (AACDEC_CONCEAL | AACDEC_FLUSH))) && self->frameOK ) - { + 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 & (AC_USAC|AC_RSVD50|AC_ELD|AC_SCALABLE|AC_ER))) - type = (MP4_ELEMENT_ID) FDKreadBits(bs,3); - else + if (!(self->flags[0] & + (AC_USAC | AC_RSVD50 | AC_RSV603DA | AC_ELD | AC_SCALABLE | AC_ER))) + type = (MP4_ELEMENT_ID)FDKreadBits(bs, 3); + else type = self->elements[element_count]; - setHcrType(&self->aacCommonData.overlay.aac.erHcrInfo, type); + 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) + if ((INT)FDKgetValidBits(bs) < 0) { self->frameOK = 0; + } - switch (type) - { + 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]); + /* Consistency check - */ - - if (type == ID_CPE) { - el_channels = 2; - } else { - el_channels = 1; - } + */ + { + int totalAscChannels = 0; - if ( (el_cnt[type] >= (self->ascChannels>>(el_channels-1))) || (aacChannels > (self->ascChannels-el_channels)) ) { - ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; - self->frameOK = 0; - break; + 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 & (AC_USAC|AC_RSVD50)) ) { + 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); + 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, - self->flags, - self->streamInfo.aacSamplesPerFrame, - el_channels, - self->streamInfo.epConfig, - self->hInput - ); - if (ErrorStatus) { + 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, + 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, - &previous_element_index, - self->elements, - type) ) - { - if ( !hdaacDecoded ) { - CChannelElement_Decode( - &self->pAacDecoderChannelInfo[aacChannels], - &self->pAacDecoderStaticChannelInfo[aacChannels], - &self->samplingRateInfo, - self->flags, - el_channels - ); - } - aacChannels += 1; - if (type == ID_CPE) { - aacChannels += 1; - } - } - else { + 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 explicitly signaled, because the first frame(s) + and if SBR was implicitly signaled, because the first frame(s) may not contain SBR payload (broken encoder, bit errors). */ - if ( (self->flags & AC_SBR_PRESENT) || (self->sbrEnabled == 1) ) - { + 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 - ); + 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. */ + /* 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 ) { + if (el_cnt[type] > self->ascChannels[streamIndex]) { ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; self->frameOK = 0; break; } - if (self->frameOK) - { + if (self->frameOK) { + CAacDecoderCommonData commonData; + CAacDecoderCommonStaticData commonStaticData; + CWorkBufferCore1 workBufferCore1; + commonStaticData.pWorkBufferCore1 = &workBufferCore1; /* memory for spectral lines temporal on scratch */ - C_ALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024); + C_AALLOC_SCRATCH_START(mdctSpec, FIXP_DBL, 1024); /* create dummy channel for CCE parsing on stack */ - CAacDecoderChannelInfo tmpAacDecoderChannelInfo, *pTmpAacDecoderChannelInfo; + CAacDecoderChannelInfo tmpAacDecoderChannelInfo, + *pTmpAacDecoderChannelInfo; - FDKmemclear(mdctSpec, 1024*sizeof(FIXP_DBL)); + FDKmemclear(mdctSpec, 1024 * sizeof(FIXP_DBL)); - tmpAacDecoderChannelInfo.pDynData = self->aacCommonData.workBufferCore1->pAacDecoderDynamicData; - tmpAacDecoderChannelInfo.pComData = &self->aacCommonData; - tmpAacDecoderChannelInfo.pSpectralCoefficient = (SPECTRAL_PTR)mdctSpec; + tmpAacDecoderChannelInfo.pDynData = commonData.pAacDecoderDynamicData; + tmpAacDecoderChannelInfo.pComData = &commonData; + tmpAacDecoderChannelInfo.pComStaticData = &commonStaticData; + tmpAacDecoderChannelInfo.pSpectralCoefficient = + (SPECTRAL_PTR)mdctSpec; /* Assume AAC-LC */ - tmpAacDecoderChannelInfo.granuleLength = self->streamInfo.aacSamplesPerFrame / 8; - + tmpAacDecoderChannelInfo.granuleLength = + self->streamInfo.aacSamplesPerFrame / 8; /* Reset PNS data. */ - CPns_ResetData(&tmpAacDecoderChannelInfo.data.aac.PnsData, &tmpAacDecoderChannelInfo.pComData->pnsInterChannelData); - + 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, - self->flags, - self->streamInfo.aacSamplesPerFrame, - 1, - self->streamInfo.epConfig, - self->hInput - ); - - C_ALLOC_SCRATCH_END(mdctSpec, FIXP_DBL, 1024); + 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 */ + /* 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, - &previous_element_index, - self->elements, - type) ) - { + 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 { + } else { self->frameOK = 0; } } @@ -1405,156 +2734,145 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( 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, - &previous_element_index, - self->elements, - type) ) - { - /* most likely an error in bitstream occured */ - //self->frameOK = 0; - } - } - break; + case ID_DSE: { + UCHAR element_instance_tag; -#ifdef TP_PCE_ENABLE - 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; + 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; } - else if ( result > 1 ) { - /* Built element table */ - int elIdx = CProgramConfig_GetElementTable(pce, self->elements, (8), &self->chMapIndex); - /* Reset the remaining tabs */ - for ( ; elIdx<(8); elIdx++) { - self->elements[elIdx] = ID_NONE; - } - /* Make new number of channel persistant */ - self->ascChannels = pce->NumChannels; - /* If PCE is not first element conceal this frame to avoid inconsistencies */ - if ( element_count != 0 ) { - self->frameOK = 0; - } + /* 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; -#endif /* TP_PCE_ENABLE */ + pceRead = (result >= 0) ? 1 : 0; + } break; - case ID_FIL: - { - int bitCnt = FDKreadBits(bs,4); /* bs_count */ + 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; - } + if (bitCnt == 15) { + int esc_count = FDKreadBits(bs, 8); /* bs_esc_count */ + bitCnt = esc_count + 14; + } - /* Convert to bits */ - bitCnt <<= 3; + /* 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; - } + 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; + } break; case ID_EXT: - { - INT bitCnt = 0; - - /* get the remaining bits of this frame */ - bitCnt = transportDec_GetAuBitsRemaining(self->hInput, 0); - - if ( (bitCnt > 0) && (self->flags & AC_SBR_PRESENT) && (self->flags & (AC_USAC|AC_RSVD50|AC_ELD|AC_DRM)) ) - { - SBR_ERROR err = SBRDEC_OK; - int elIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE]; + ErrorStatus = aacDecoder_ParseExplicitMpsAndSbr( + self, bs, previous_element, previous_element_index, element_count, + el_cnt); + break; - for (elIdx = 0; elIdx < numChElements; elIdx += 1) - { - err = sbrDecoder_Parse ( - self->hSbrDecoder, - bs, - &bitCnt, - -1, - self->flags & AC_SBRCRC, - self->elements[elIdx], - elIdx, - self->flags & AC_INDEP ); - - if (err != SBRDEC_OK) { - break; - } - } - 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, bitCnt); - bitCnt = 0; - break; - case SBRDEC_OK: - self->sbrEnabled = 1; - break; - default: - self->frameOK = 0; - break; + case ID_USAC_EXT: { + /* 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 = FDKgetValidBits(bs); - if (self->flags & AC_DRM) - { - if ((bitCnt = (INT)FDKgetValidBits(bs)) != 0) { - FDKpushBiDirectional(bs, bitCnt); - } - } + USAC_EXT_ELEMENT_TYPE usacExtElementType = + self->pUsacConfig[streamIndex] + ->element[element_count - element_count_prev_streams] + .extElement.usacExtElementType; - if ( ! (self->flags & (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; + 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 - FDKgetValidBits(bs)); + if (usacExtBitPos < 0) { + self->frameOK = 0; + ErrorStatus = AAC_DEC_PARSE_ERROR; } + FDKpushBiDirectional(bs, usacExtBitPos); } } - break; - + } break; case ID_END: + case ID_USAC_END: break; default: @@ -1566,32 +2884,56 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( previous_element = type; element_count++; - } /* while ( (type != ID_END) ... ) */ + } /* while ( (type != ID_END) ... ) */ - if ( !(flags & (AACDEC_CONCEAL|AACDEC_FLUSH)) ) - { + 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 ) { + if (transportDec_GetAuBitsTotal(self->hInput, 0) > 0) { INT unreadBits = transportDec_GetAuBitsRemaining(self->hInput, 0); - if ( unreadBits != 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; + } - 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. */ + /* 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 ) { + /* 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; @@ -1600,219 +2942,479 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( } } - /* 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; + 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; } - self->frameOK = 0; } - aacChannels = 0; + + 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++; } - else if ( aacChannels > self->ascChannels ) { + + /* 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_UNSUPPORTED_FORMAT; + ErrorStatus = AAC_DEC_DECODE_FRAME_ERROR; } self->frameOK = 0; aacChannels = 0; } - if ( TRANSPORTDEC_OK != transportDec_CrcCheck(self->hInput) ) - { - self->frameOK=0; + 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; } - /* store or restore the number of channels and the corresponding info */ - if ( self->frameOK && !(flags &(AACDEC_CONCEAL|AACDEC_FLUSH)) ) { - 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; + 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 { - if (self->aacChannels > 0) { - 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; - } + /* 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; - #ifdef TP_PCE_ENABLE + /* 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 ); + pcmDmx_SetMatrixMixdownFromPce( + self->hPcmUtils, pce->MatrixMixdownIndexPresent, + pce->MatrixMixdownIndex, pce->PseudoSurroundEnable); + ; } - #endif /* If there is no valid data to transfrom into time domain, return. */ - if ( ! IS_OUTPUT_VALID(ErrorStatus) ) { + if (!IS_OUTPUT_VALID(ErrorStatus)) { return ErrorStatus; } - /* Setup the output channel mapping. The table below shows the four possibilities: - * # | chCfg | PCE | cChCfg | chOutMapIdx - * ---+-------+-----+--------+------------------ - * 1 | > 0 | no | - | chCfg - * 2 | 0 | yes | > 0 | cChCfg - * 3 | 0 | yes | 0 | aacChannels || 0 - * 4 | 0 | no | - | aacChannels || 0 + /* 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 #4 should appear only with MPEG-2 (ADTS) streams. This is - * mode is called "implicit channel mapping". + * 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". */ - chOutMapIdx = ((self->chMapIndex==0) && (aacChannels<7)) ? aacChannels : self->chMapIndex; + if ((self->streamInfo.channelConfig == 0) && !pce->isValid) { + self->chMapIndex = (aacChannels < 7) ? aacChannels : 0; + } /* Inverse transform */ { - int stride, offset, c; - - /* 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 ); - /* Extract DRC control data and map it to channels (without bitstream delay) */ - aacDecoder_drcProlog ( - self->hDrcInfo, - bs, - self->pAacDecoderStaticChannelInfo, - self->pce.ElementInstanceTag, - self->chMapping, - aacChannels - ); - - /* "c" iterates in canonical MPEG channel order */ - for (c=0; c < aacChannels; c++) - { - CAacDecoderChannelInfo *pAacDecoderChannelInfo; + 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)); + } - /* Select correct pAacDecoderChannelInfo for current channel */ - if (self->chMapping[c] >= aacChannels) { - pAacDecoderChannelInfo = self->pAacDecoderChannelInfo[c]; - } else { - pAacDecoderChannelInfo = self->pAacDecoderChannelInfo[self->chMapping[c]]; + /* 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; + } - /* Setup offset and stride for time buffer traversal. */ - if (interleaved) { - stride = aacChannels; - offset = self->channelOutputMapping[chOutMapIdx][c]; + 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 { - stride = 1; - offset = self->channelOutputMapping[chOutMapIdx][c] * self->streamInfo.aacSamplesPerFrame; - } - - - 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); - } - - /* - Conceal defective spectral data - */ - CConcealment_Apply(&self->pAacDecoderStaticChannelInfo[c]->concealmentInfo, - pAacDecoderChannelInfo, - self->pAacDecoderStaticChannelInfo[c], - &self->samplingRateInfo, - self->streamInfo.aacSamplesPerFrame, - 0, - (self->frameOK && !(flags&AACDEC_CONCEAL)), - self->flags - ); - - - if (flags & (AACDEC_INTR|AACDEC_CLRHIST)) { - /* Reset DRC control data for this channel */ - aacDecoder_drcInitChannelData ( &self->pAacDecoderStaticChannelInfo[c]->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, - &self->pAacDecoderStaticChannelInfo[c]->drcData, - self->extGain, - c, - self->streamInfo.aacSamplesPerFrame, - self->sbrEnabled - ); + type = channel_elements[el]; + } - switch (pAacDecoderChannelInfo->renderMode) { - case AACDEC_RENDER_IMDCT: - CBlock_FrequencyToTime( - self->pAacDecoderStaticChannelInfo[c], - pAacDecoderChannelInfo, - pTimeData + offset, - self->streamInfo.aacSamplesPerFrame, - stride, - (self->frameOK && !(flags&AACDEC_CONCEAL)), - self->aacCommonData.workBufferCore1->mdctOutTemp - ); - self->extGainDelay = self->streamInfo.aacSamplesPerFrame; - break; - case AACDEC_RENDER_ELDFB: - CBlock_FrequencyToTimeLowDelay( - self->pAacDecoderStaticChannelInfo[c], - pAacDecoderChannelInfo, - pTimeData + offset, - self->streamInfo.aacSamplesPerFrame, - stride - ); - self->extGainDelay = (self->streamInfo.aacSamplesPerFrame*2 - self->streamInfo.aacSamplesPerFrame/2 - 1)/2; - break; - default: - ErrorStatus = AAC_DEC_UNKNOWN; - break; + int nElementChannels; + + nElementChannels = + CAacDecoder_GetELChannels(type, self->usacStereoConfigIndex[el]); + + el_channels += nElementChannels; + + if (nElementChannels == 0) { + continue; + } } - if ( flags&AACDEC_FLUSH ) { - FDKmemclear(pAacDecoderChannelInfo->pSpectralCoefficient, sizeof(FIXP_DBL)*self->streamInfo.aacSamplesPerFrame); - FDKmemclear(self->pAacDecoderStaticChannelInfo[c]->pOverlapBuffer, OverlapBufferSize*sizeof(FIXP_DBL)); + + 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) */ - aacDecoder_drcEpilog ( - self->hDrcInfo, - bs, - self->pAacDecoderStaticChannelInfo, - self->pce.ElementInstanceTag, - self->chMapping, - aacChannels - ); + 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; + 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 - ); + 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)); @@ -1820,9 +3422,11 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( FDKmemcpy(types, self->channelType, sizeof(types)); FDKmemcpy(idx, self->channelIndices, sizeof(idx)); - for (c=0; c<aacChannels; c++) { - self->channelType[self->channelOutputMapping[chOutMapIdx][c]] = types[c]; - self->channelIndices[self->channelOutputMapping[chOutMapIdx][c]] = idx[c]; + 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]; } } @@ -1838,14 +3442,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( \return pointer to the struct */ -LINKSPEC_CPP CStreamInfo* CAacDecoder_GetStreamInfo ( HANDLE_AACDECODER self ) -{ +LINKSPEC_CPP CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self) { if (!self) { return NULL; } return &self->streamInfo; } - - - - diff --git a/libAACdec/src/aacdecoder.h b/libAACdec/src/aacdecoder.h index 25bc35d..20f4c45 100644 --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: -******************************************************************************/ +*******************************************************************************/ #ifndef AACDECODER_H #define AACDECODER_H @@ -104,134 +116,238 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" +#include "FDK_qmf_domain.h" #include "sbrdecoder.h" - #include "aacdec_drc.h" - #include "pcmutils_lib.h" - #include "limiter.h" - - -/* Capabilities flags */ -#define CAPF_AAC_LC 0x00000001 -#define CAPF_AAC_LD 0x00000002 -#define CAPF_AAC_SCAL 0x00000004 -#define CAPF_AAC_ER 0x00000008 -#define CAPF_AAC_480 0x00000010 -#define CAPF_AAC_512 0x00000020 -#define CAPF_AAC_960 0x00000040 -#define CAPF_AAC_1024 0x00000080 -#define CAPF_AAC_HCR 0x00000100 -#define CAPF_AAC_VCB11 0x00000200 -#define CAPF_AAC_RVLC 0x00000400 -#define CAPF_AAC_MPEG4 0x00000800 /* PNS */ -#define CAPF_AAC_DRC 0x00001000 -#define CAPF_AAC_CONCEAL 0x00002000 -#define CAPF_AAC_DRM_BSFORMAT 0x00004000 -#define CAPF_AAC_BSAC 0x00008000 - -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; - - -/* AAC decoder (opaque toward userland) struct declaration */ -struct AAC_DECODER_INSTANCE { - INT aacChannels; /*!< Amount of AAC decoder channels allocated. */ - INT ascChannels; /*!< 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. */ +#include "pcmdmx_lib.h" - SamplingRateInfo samplingRateInfo; /*!< Sampling Rate information table */ +#include "FDK_drcDecLib.h" - UCHAR frameOK; /*!< Will be unset if a consistency check, e.g. CRC etc. fails */ +#include "limiter.h" - UINT flags; /*!< Flags for internal decoder use. DO NOT USE self::streaminfo::flags ! */ +#include "FDK_delay.h" - MP4_ELEMENT_ID elements[(8)]; /*!< Table where the element Id's are listed */ - UCHAR elTags[(8)]; /*!< Table where the elements id Tags are listed */ - UCHAR chMapping[(8)]; /*!< Table of MPEG canonical order to bitstream channel order mapping. */ +#define TIME_DATA_FLUSH_SIZE (128) +#define TIME_DATA_FLUSH_SIZE_SF (7) - 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() */ +#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; - const UCHAR (*channelOutputMapping)[8]; /*!< Table for MPEG canonical order to output channel order 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. */ - - CProgramConfig pce; - CStreamInfo streamInfo; /*!< pointer to StreamInfo data (read from the bitstream) */ - CAacDecoderChannelInfo *pAacDecoderChannelInfo[(8)]; /*!< Temporal channel memory */ - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[(8)]; /*!< Persistent channel memory */ - - CAacDecoderCommonData aacCommonData; /*!< Temporal shared data for all channels hooked into pAacDecoderChannelInfo */ - - CConcealParams concealCommonData; - - 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. */ - - - 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 */ - - QMF_MODE qmfModeCurr; /*!< The current QMF mode */ - QMF_MODE qmfModeUser; /*!< The QMF mode requested by the library user */ +enum { L = 0, R = 1 }; - HANDLE_AAC_DRC hDrcInfo; /*!< handle to DRC data structure */ +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; - CAncData ancData; /*!< structure to handle ancillary data */ +typedef struct { + int bsDelay; +} SBR_PARAMS; - 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. */ +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 +}; - FIXP_DBL extGain[1]; /*!< Gain that must be applied to the output signal. */ - UINT extGainDelay; /*!< Delay that must be accounted for extGain. */ +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 +}; - INT_PCM pcmOutputBuffer[(8)*(2048)]; +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 "\ +#define AAC_DEBUG_EXTHLP \ + "\ --- AAC-Core ---\n\ 0x00010000 Header data\n\ 0x00020000 CRC data\n\ @@ -272,7 +388,8 @@ void CAacDecoder_SignalInterruption(HANDLE_AACDECODER self); \return Error code */ -AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, unsigned char *buffer, int size); +AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, + unsigned char *buffer, int size); /*! \brief Get one ancillary data element @@ -280,20 +397,22 @@ AAC_DECODER_ERROR CAacDecoder_AncDataInit(CAncData *ancData, unsigned char *buff \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 + \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); - +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 stream-info elements */ +/* Initialization of channel elements */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, - const CSAudioSpecificConfig *asc); - + const CSAudioSpecificConfig *asc, + UCHAR configMode, + UCHAR *configChanged); /*! \brief Decodes one aac frame @@ -308,18 +427,39 @@ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_Init(HANDLE_AACDECODER self, \return error status */ LINKSPEC_H AAC_DECODER_ERROR CAacDecoder_DecodeFrame( - HANDLE_AACDECODER self, - const UINT flags, - INT_PCM *pTimeData, - const INT timeDataSize, - const INT interleaved - ); + 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 ); +LINKSPEC_H void CAacDecoder_Close(HANDLE_AACDECODER self); /* get streaminfo handle from decoder */ -LINKSPEC_H CStreamInfo* CAacDecoder_GetStreamInfo ( HANDLE_AACDECODER self ); - +LINKSPEC_H CStreamInfo *CAacDecoder_GetStreamInfo(HANDLE_AACDECODER self); #endif /* #ifndef AACDECODER_H */ diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index 50efb0f..b7ea8df 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Manuel Jander + Description: -******************************************************************************/ +*******************************************************************************/ #include "aacdecoder_lib.h" @@ -95,22 +107,20 @@ amm-info@iis.fraunhofer.de #include "tpdec_lib.h" #include "FDK_core.h" /* FDK_tools version info */ - - #include "sbrdecoder.h" - - - +#include "sbrdecoder.h" #include "conceal.h" - #include "aacdec_drc.h" +#include "aacdec_drc.h" +#include "sac_dec_lib.h" +#include "pcm_utils.h" /* Decoder library info */ -#define AACDECODER_LIB_VL0 2 -#define AACDECODER_LIB_VL1 5 -#define AACDECODER_LIB_VL2 17 +#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 "" @@ -120,19 +130,38 @@ amm-info@iis.fraunhofer.de #define AACDECODER_LIB_BUILD_TIME __TIME__ #endif -static AAC_DECODER_ERROR -setConcealMethod ( const HANDLE_AACDECODER self, - const INT method ); +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); -LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_GetFreeBytes ( const HANDLE_AACDECODER self, UINT *pFreeBytes){ + /* 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; + if (!self) return AAC_DEC_INVALID_HANDLE; /* return nr of free bytes */ HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0); @@ -145,43 +174,46 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_GetFreeBytes ( const HANDLE_AACDECODER /** * Config Decoder using a CSAudioSpecificConfig struct. */ -static -LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Config(HANDLE_AACDECODER self, const CSAudioSpecificConfig *pAscStruct) -{ +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); + 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[] ) -{ +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; + 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); + 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; + 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){ + if (layer >= 1) { self->nrOfLayers = layer; err = AAC_DEC_OK; } @@ -193,39 +225,91 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_ConfigRaw ( 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); + } -static INT aacDecoder_ConfigCallback(void *handle, const CSAudioSpecificConfig *pAscStruct) -{ + 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); - } + { err = aacDecoder_Config(self, pAscStruct, configMode, configChanged); } } if (err == AAC_DEC_OK) { - if ( self->flags & (AC_USAC|AC_RSVD50|AC_LD|AC_ELD) - && CConcealment_GetDelay(&self->concealCommonData) > 0 ) - { + /* + 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/RSVD50 or + Because interpolation is not implemented for USAC or the additional delay is unwanted for low delay codecs. */ setConcealMethod(self, 1); -#ifdef DEBUG - FDKprintf(" Concealment method was reverted to 1 !\n"); -#endif } + aacDecoder_setMetadataExpiry(self, self->metadataExpiry); errTp = TRANSPORTDEC_OK; } else { - if (IS_INIT_ERROR(err)) { + 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 if (err == AAC_DEC_NEED_TO_RESTART) { - errTp = TRANSPORTDEC_NEED_TO_RESTART; - } else { + else { errTp = TRANSPORTDEC_UNKOWN_ERROR; } } @@ -233,37 +317,228 @@ static INT aacDecoder_ConfigCallback(void *handle, const CSAudioSpecificConfig * 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); -LINKSPEC_CPP AAC_DECODER_ERROR -aacDecoder_AncDataInit ( HANDLE_AACDECODER self, - UCHAR *buffer, - int size ) -{ + 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_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, + const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingRate, + const INT stereoConfigIndex, + const INT coreSbrFrameLengthIndex, + const INT configBytes, const UCHAR configMode, + UCHAR *configChanged) { + SACDEC_ERROR err; + TRANSPORTDEC_ERROR errTp; + HANDLE_AACDECODER hAacDecoder = (HANDLE_AACDECODER)handle; + + err = mpegSurroundDecoder_Config( + (CMpegSurroundDecoder *)hAacDecoder->pMpegSurroundDecoder, hBs, coreCodec, + samplingRate, 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) || 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 ) -{ +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; -static AAC_DECODER_ERROR -setConcealMethod ( const HANDLE_AACDECODER self, /*!< Handle of the decoder instance */ - const INT method ) -{ + 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; + CConcealParams *pConcealData = NULL; + int method_revert = 0; HANDLE_SBRDECODER hSbrDec = NULL; HANDLE_AAC_DRC hDrcInfo = NULL; HANDLE_PCM_DOWNMIX hPcmDmx = NULL; @@ -277,25 +552,33 @@ setConcealMethod ( const HANDLE_AACDECODER self, /*!< Handle of the decoder i 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); + backupDelay = CConcealment_GetDelay(pConcealData); /* Be sure to set AAC and SBR concealment method simultaneously! */ - errorStatus = - CConcealment_SetParams( + errorStatus = CConcealment_SetParams( pConcealData, - (int)method, // 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) ) { + (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; } @@ -306,350 +589,342 @@ setConcealMethod ( const HANDLE_AACDECODER self, /*!< Handle of the decoder i SBR_ERROR sbrErr = SBRDEC_OK; /* set SBR bitstream delay */ - sbrErr = sbrDecoder_SetParam ( - hSbrDec, - SBR_SYSTEM_BITSTREAM_DELAY, - bsDelay - ); + 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; + 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) ) { + 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 - ); + PCMDMX_ERROR err = pcmDmx_SetParam(hPcmDmx, DMX_BS_DATA_DELAY, bsDelay); switch (err) { - case PCMDMX_INVALID_HANDLE: - errorStatus = AAC_DEC_INVALID_HANDLE; - case PCMDMX_OK: - break; - default: - errorStatus = AAC_DEC_SET_PARAM_FAIL; - goto bail; + case PCMDMX_INVALID_HANDLE: + errorStatus = AAC_DEC_INVALID_HANDLE; + case PCMDMX_OK: + break; + default: + errorStatus = AAC_DEC_SET_PARAM_FAIL; + goto bail; } } - bail: - if ( (errorStatus != AAC_DEC_OK) - && (errorStatus != AAC_DEC_INVALID_HANDLE) ) - { + 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 - ); + 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 - ); + sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay); /* Revert DRC bitstream delay */ - aacDecoder_drcSetParam ( - hDrcInfo, - DRC_BS_DELAY, - backupDelay - ); + aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay); /* Revert PCM mixdown bitstream delay */ - pcmDmx_SetParam ( - hPcmDmx, - DMX_BS_DATA_DELAY, - backupDelay - ); + 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 */ +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; - CConcealParams *pConcealData = NULL; + 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) { - pConcealData = &self->concealCommonData; + 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_OUTPUT_INTERLEAVED: - if (value < 0 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->outputInterleaved = value; - break; + 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_MIN_OUTPUT_CHANNELS: - if (value < -1 || value > (8)) { - return AAC_DEC_SET_PARAM_FAIL; - } - { - PCMDMX_ERROR err; + 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); - err = pcmDmx_SetParam ( - hPcmDmx, - MIN_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; - switch (err) { - case PCMDMX_OK: - break; - case PCMDMX_INVALID_HANDLE: - return AAC_DEC_INVALID_HANDLE; - default: + 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; } - } - break; - - case AAC_PCM_MAX_OUTPUT_CHANNELS: - if (value < -1 || value > (8)) { - return AAC_DEC_SET_PARAM_FAIL; - } - { - PCMDMX_ERROR err; + self->limiterEnableUser = value; + break; - err = pcmDmx_SetParam ( - hPcmDmx, - MAX_NUMBER_OF_OUTPUT_CHANNELS, - value ); + 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; - switch (err) { - case PCMDMX_OK: - break; - case PCMDMX_INVALID_HANDLE: - return AAC_DEC_INVALID_HANDLE; - default: + case AAC_PCM_LIMITER_RELEAS_TIME: + if (value <= 0) { /* module function converts value to unsigned */ return AAC_DEC_SET_PARAM_FAIL; } - } - break; + 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_PCM_DUAL_CHANNEL_OUTPUT_MODE: - { - PCMDMX_ERROR err; + case AAC_METADATA_PROFILE: { + DMX_PROFILE_TYPE dmxProfile; + INT mdExpiry = -1; /* in ms (-1: don't change) */ - err = pcmDmx_SetParam ( - hPcmDmx, - DMX_DUAL_CHANNEL_MODE, - value ); + 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; - switch (err) { - case PCMDMX_OK: - break; - case PCMDMX_INVALID_HANDLE: - return AAC_DEC_INVALID_HANDLE; - default: + case AAC_METADATA_EXPIRY_TIME: + if (value < 0) { return AAC_DEC_SET_PARAM_FAIL; } - } - break; + 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_PCM_LIMITER_ENABLE: - if (value < -1 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - self->limiterEnableUser = value; - break; + case AAC_QMF_LOWPOWER: + if (value < -1 || value > 1) { + return AAC_DEC_SET_PARAM_FAIL; + } - case AAC_PCM_LIMITER_ATTACK_TIME: - if (value <= 0) { /* module function converts value to unsigned */ - return AAC_DEC_SET_PARAM_FAIL; - } - switch (setLimiterAttack(hPcmTdl, value)) { - case TDLIMIT_OK: + /** + * Set QMF mode (might be overriden) + * 0:HQ (complex) + * 1:LP (partially complex) + */ + self->qmfModeUser = (QMF_MODE)value; 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 (setLimiterRelease(hPcmTdl, value)) { - case TDLIMIT_OK: + 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 TDLIMIT_INVALID_HANDLE: - return AAC_DEC_INVALID_HANDLE; - case TDLIMIT_INVALID_PARAMETER: + + 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; - } - break; + } /* switch(param) */ - case AAC_PCM_OUTPUT_CHANNEL_MAPPING: - switch (value) { - case 0: - if (self != NULL) { - self->channelOutputMapping = channelMappingTablePassthrough; - } +bail: + + if (errorStatus == AAC_DEC_OK) { + /* Check error code returned by DMX module library: */ + switch (dmxErr) { + case PCMDMX_OK: break; - case 1: - if (self != NULL) { - self->channelOutputMapping = channelMappingTableWAV; - } + case PCMDMX_INVALID_HANDLE: + errorStatus = AAC_DEC_INVALID_HANDLE; break; default: errorStatus = AAC_DEC_SET_PARAM_FAIL; - break; } - break; + } + if (errTp != TRANSPORTDEC_OK && errorStatus == AAC_DEC_OK) { + errorStatus = AAC_DEC_SET_PARAM_FAIL; + } - case AAC_QMF_LOWPOWER: - if (value < -1 || value > 1) { - return AAC_DEC_SET_PARAM_FAIL; - } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; + 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; } - - /** - * 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: - /* DRC reference level quantized in 0.25dB steps using values [0..127] it is '-' for analog scaling */ - errorStatus = - aacDecoder_drcSetParam ( - hDrcInfo, - TARGET_REF_LEVEL, - 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_TPDEC_CLEAR_BUFFER: - transportDec_SetParam(self->hInput, 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 ); - break; - - default: - return AAC_DEC_SET_PARAM_FAIL; - } /* switch(param) */ + } return (errorStatus); } - - -LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT nrOfLayers) -{ +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); + 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); @@ -659,29 +934,67 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT } aacDec->hInput = pIn; - aacDec->nrOfLayers = nrOfLayers; + aacDec->nrOfLayers = nrOfLayers_min; - aacDec->channelOutputMapping = channelMappingTableWAV; + /* Setup channel mapping descriptor. */ + FDK_chMapDescr_init(&aacDec->mapDescr, NULL, 0, 0); /* Register Config Update callback. */ - transportDec_RegisterAscCallback(pIn, aacDecoder_ConfigCallback, (void*)aacDec); + 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 )) { + if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) { err = -1; goto bail; } aacDec->qmfModeUser = NOT_DEFINED; - transportDec_RegisterSbrCallback(aacDec->hInput, (cbSbr_t)sbrDecoder_Header, (void*)aacDec->hSbrDecoder); + transportDec_RegisterSbrCallback(aacDec->hInput, (cbSbr_t)sbrDecoder_Header, + (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 ); + pcmDmx_Open(&aacDec->hPcmUtils); if (aacDec->hPcmUtils == NULL) { err = -1; goto bail; } - aacDec->hLimiter = createLimiter(TDL_ATTACK_DEFAULT_MS, TDL_RELEASE_DEFAULT_MS, SAMPLE_MAX, (8), 96000); + 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; @@ -689,10 +1002,9 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt, UINT aacDec->limiterEnableUser = (UCHAR)-1; aacDec->limiterEnableCurr = 0; - - /* Assure that all modules have same delay */ - if ( setConcealMethod(aacDec, CConcealment_GetMethod(&aacDec->concealCommonData)) ) { + if (setConcealMethod(aacDec, + CConcealment_GetMethod(&aacDec->concealCommonData))) { err = -1; goto bail; } @@ -705,25 +1017,24 @@ bail: return aacDec; } -LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill( - HANDLE_AACDECODER self, - UCHAR *pBuffer[], - const UINT bufferSize[], - UINT *pBytesValid - ) -{ +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; + /* 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++){ + for (layer = 0; layer < nrOfLayers; layer++) { { - tpErr = transportDec_FillData( self->hInput, pBuffer[layer], bufferSize[layer], &pBytesValid[layer], 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_UNKNOWN; /* Must be an internal error */ } } } @@ -732,38 +1043,47 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_Fill( return AAC_DEC_OK; } - -static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) -{ +static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) { CAacDecoder_SignalInterruption(self); - if ( self->hSbrDecoder != NULL ) { - sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 0); + 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) -{ +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 - FDKgetValidBits(hBs); + 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. + 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) { - pSi->bitRate = (nBits * pSi->sampleRate)/pSi->frameSize; + /* 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; + nBytes = nBits >> 3; pSi->numTotalBytes += nBytes; if (IS_OUTPUT_VALID(ErrorStatus)) { pSi->numTotalAccessUnits++; @@ -775,54 +1095,81 @@ static void aacDecoder_UpdateBitStreamCounters(CStreamInfo *pSi, HANDLE_FDK_BITS } } -static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) -{ +static INT aacDecoder_EstimateNumberOfLostFrames(HANDLE_AACDECODER self) { INT n; - transportDec_GetMissingAccessUnitCount( &n, self->hInput); + 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 fTpInterruption = 0; /* Transport originated interruption detection. */ - int fTpConceal = 0; /* Transport originated concealment. */ +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; + } - if (self == NULL) { - return AAC_DEC_INVALID_HANDLE; - } - INT interleaved = self->outputInterleaved; - INT_PCM *pTimeData = self->pcmOutputBuffer; - INT timeDataSize = sizeof(self->pcmOutputBuffer)/sizeof(*self->pcmOutputBuffer); + pTimeData = self->pcmOutputBuffer; + timeDataSize = sizeof(self->pcmOutputBuffer) / sizeof(*self->pcmOutputBuffer); - if (flags & AACDEC_INTR) { - self->streamInfo.numLostAccessUnits = 0; + 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); } + } - HANDLE_FDK_BITSTREAM hBs = transportDec_GetBitstream(self->hInput, 0); - - /* Get current bits position for bitrate calculation. */ - INT nBits = FDKgetValidBits(hBs); - if (! (flags & (AACDEC_CONCEAL | AACDEC_FLUSH) ) ) - { - TRANSPORTDEC_ERROR err; + 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(INT layer = 0; layer < self->nrOfLayers; layer++) - { - err = transportDec_ReadAccessUnit(self->hInput, layer); - if (err != TRANSPORTDEC_OK) { - switch (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); + self->streamInfo.numLostAccessUnits = + aacDecoder_EstimateNumberOfLostFrames(self); fTpInterruption = 1; break; case TRANSPORTDEC_NEED_TO_RESTART: @@ -831,258 +1178,774 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecoder_DecodeFrame( 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--; + } + } 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|AACDEC_CLRHIST)) ) - { - sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, (flags&AACDEC_CLRHIST)); + if (fTpInterruption || (flags & AACDEC_INTR)) { aacDecoder_SignalInterruption(self); - if ( ! (flags & AACDEC_INTR) ) { + 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) - { - transportDec_SetParam(self->hInput, TPDEC_PARAM_RESET, 1); - self->streamInfo.numLostAccessUnits = 0; - self->streamInfo.numBadBytes = 0; - self->streamInfo.numTotalBytes = 0; + 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. */ + /* Reset the output delay field. The modules will add their figures one + * after another. */ self->streamInfo.outputDelay = 0; - if (self->limiterEnableUser==(UCHAR)-1) { - /* Enbale limiter for all non-lowdelay AOT's. */ - self->limiterEnableCurr = ( self->flags & (AC_LD|AC_ELD) ) ? 0 : 1; - } - else { + 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)); + 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; + } - ErrorStatus = CAacDecoder_DecodeFrame(self, - flags | (fTpConceal ? AACDEC_CONCEAL : 0), - pTimeData, - timeDataSize, - interleaved); + self->streamInfo.numChannels = self->streamInfo.aacNumChannels; - if (!(flags & (AACDEC_CONCEAL|AACDEC_FLUSH))) { - TRANSPORTDEC_ERROR tpErr; - tpErr = transportDec_EndAccessUnit(self->hInput); - if (tpErr != TRANSPORTDEC_OK) { - self->frameOK = 0; + { + FDK_Delay_Apply(&self->usacResidualDelay, + pTimeDataFixpPcm + + 1 * (self->streamInfo.aacSamplesPerFrame + 0) + 0, + self->streamInfo.frameSize, 0); } - } - /* If the current pTimeData does not contain a valid signal, there nothing else we can do, so bail. */ - if ( ! IS_OUTPUT_VALID(ErrorStatus) ) { - goto bail; - } + /* 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)); + } - { - /* Export data into streaminfo structure */ - self->streamInfo.sampleRate = self->streamInfo.aacSampleRate; - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame; - } - self->streamInfo.numChannels = self->streamInfo.aacNumChannels; + 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); + self->qmfDomain.globalConf.nQmfTimeSlots_requested = + self->streamInfo.aacSamplesPerFrame / + self->qmfDomain.globalConf.nBandsAnalysis_requested; + } + self->qmfDomain.globalConf.TDinput = pTimeData; - CAacDecoder_SyncQmfMode(self); + 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 */ + /* sbr decoder */ - if (ErrorStatus || (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 ((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) - { - SBR_ERROR sbrError = SBRDEC_OK; - int chIdx, numCoreChannel = self->streamInfo.numChannels; - int chOutMapIdx = ((self->chMapIndex==0) && (numCoreChannel<7)) ? numCoreChannel : self->chMapIndex; + 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) */ - /* set params */ - sbrDecoder_SetParam ( self->hSbrDecoder, - SBR_SYSTEM_BITSTREAM_DELAY, + 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_FLUSH_DATA, - (flags & AACDEC_FLUSH) ); - - if ( self->streamInfo.aot == AOT_ER_AAC_ELD ) { - /* Configure QMF */ - sbrDecoder_SetParam ( self->hSbrDecoder, - SBR_LD_QMF_TIME_ALIGN, - (self->flags & AC_LD_MPS) ? 1 : 0 ); + + 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; + } } { - PCMDMX_ERROR dmxErr; - INT maxOutCh = 0; + 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++) { + int mapValue = FDK_chMapDescr_getMapValue( + &self->mapDescr, (UCHAR)ch, self->chMapIndex); + reverseInChannelMap[mapValue] = ch; + } + for (ch = 0; ch < (int)numDrcOutChannels; ch++) { + int mapValue = FDK_chMapDescr_getMapValue( + &self->mapDescr, (UCHAR)ch, numDrcOutChannels); + 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; + } - 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; + /* 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; + } - /* apply SBR processing */ - sbrError = sbrDecoder_Apply ( self->hSbrDecoder, - pTimeData, - &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - self->channelOutputMapping[chOutMapIdx], - interleaved, - self->frameOK, - &self->psPossible); - - - if (sbrError == SBRDEC_OK) { - #define UPS_SCALE 2 /* Maximum upsampling factor is 4 (CELP+SBR) */ - FIXP_DBL upsampleFactor = FL2FXCONST_DBL(1.0f/(1<<UPS_SCALE)); - - /* Update data in streaminfo structure. Assume that the SBR upsampling factor is either 1 or 2 */ - self->flags |= AC_SBR_PRESENT; - if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) { - if (self->streamInfo.frameSize == 768) { - upsampleFactor = FL2FXCONST_DBL(8.0f/(3<<UPS_SCALE)); - } else { - upsampleFactor = FL2FXCONST_DBL(2.0f/(1<<UPS_SCALE)); - } - } - /* Apply upsampling factor to both the core frame length and the core delay */ - self->streamInfo.frameSize = (INT)fMult((FIXP_DBL)self->streamInfo.aacSamplesPerFrame<<UPS_SCALE, upsampleFactor); - self->streamInfo.outputDelay = (UINT)(INT)fMult((FIXP_DBL)self->streamInfo.outputDelay<<UPS_SCALE, upsampleFactor); - self->streamInfo.outputDelay += sbrDecoder_GetDelay( self->hSbrDecoder ); - - if (self->psPossible) { - self->flags |= AC_PS_PRESENT; - } - for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; chIdx+=1) { - self->channelType[chIdx] = ACT_FRONT; - self->channelIndices[chIdx] = chIdx; - } - } - } + 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); + } - { - INT pcmLimiterScale = 0; - PCMDMX_ERROR dmxErr = PCMDMX_OK; - if ( flags & (AACDEC_INTR | AACDEC_CLRHIST) ) { - /* delete data from the past (e.g. mixdown coeficients) */ - pcmDmx_Reset( self->hPcmUtils, PCMDMX_RESET_BS_DATA ); - } - /* do PCM post processing */ - dmxErr = pcmDmx_ApplyFrame ( - self->hPcmUtils, - pTimeData, - self->streamInfo.frameSize, - &self->streamInfo.numChannels, - interleaved, - self->channelType, - self->channelIndices, - self->channelOutputMapping, - (self->limiterEnableCurr) ? &pcmLimiterScale : NULL - ); - 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; - } + pcmLimiter_Apply(self->hLimiter, pInterleaveBuffer, pTimeData, + self->extGain, &pcmLimiterScale, 1, + self->extGainDelay, self->streamInfo.frameSize); - if ( flags & AACDEC_CLRHIST ) { - /* Delete the delayed signal. */ - resetLimiter(self->hLimiter); - } - if (self->limiterEnableCurr) - { - /* Set actual signal parameters */ - setLimiterNChannels(self->hLimiter, self->streamInfo.numChannels); - setLimiterSampleRate(self->hLimiter, self->streamInfo.sampleRate); - - applyLimiter( - self->hLimiter, - pTimeData, - self->extGain, - &pcmLimiterScale, - 1, - self->extGainDelay, - self->streamInfo.frameSize - ); - - /* Announce the additional limiter output delay */ - self->streamInfo.outputDelay += getLimiterDelay(self->hLimiter); - } - } + { + /* 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; + } - /* Signal interruption to take effect in next frame. */ - if ( flags & AACDEC_FLUSH ) { - aacDecoder_SignalInterruption(self); - } + 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; + } + } - /* Update externally visible copy of flags */ - self->streamInfo.flags = self->flags; + /* Signal interruption to take effect in next frame. */ + if ((flags & AACDEC_FLUSH || self->flushStatus) && + !(flags & AACDEC_CONCEAL)) { + aacDecoder_SignalInterruption(self); + } -bail: + /* Update externally visible copy of flags */ + self->streamInfo.flags = self->flags[0]; - /* Update Statistics */ - aacDecoder_UpdateBitStreamCounters(&self->streamInfo, hBs, nBits, ErrorStatus); + } /* USAC DASH IPF flushing possible end */ + if (accessUnit < numPrerollAU) { + FDKpushBack(hBsAu, auStartAnchor - 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--; - /* Check whether external output buffer is large enough. */ - if (timeDataSize_extern < self->streamInfo.numChannels*self->streamInfo.frameSize) { - ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; - } + if (self->buildUpCnt < 0) { + self->buildUpStatus = 0; + } + } - /* Update external output buffer. */ - if ( IS_OUTPUT_VALID(ErrorStatus) ) { - FDKmemcpy(pTimeData_extern, pTimeData, self->streamInfo.numChannels*self->streamInfo.frameSize*sizeof(*pTimeData)); + if (self->flags[0] & AC_USAC) { + if (self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON && + !(flags & AACDEC_CONCEAL)) { + self->streamInfo.frameSize = 0; + } + } } - else { - FDKmemclear(pTimeData_extern, timeDataSize_extern*sizeof(*pTimeData_extern)); + + if (self->flushStatus != AACDEC_USAC_DASH_IPF_FLUSH_ON) { + accessUnit++; } + } while ((accessUnit < numAccessUnits) || + ((self->flushStatus == AACDEC_USAC_DASH_IPF_FLUSH_ON) && + !(flags & AACDEC_CONCEAL))); - return ErrorStatus; -} +bail: -LINKSPEC_CPP void aacDecoder_Close ( HANDLE_AACDECODER self ) -{ - if (self == NULL) - return; + /* 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) { - destroyLimiter(self->hLimiter); + pcmLimiter_Destroy(self->hLimiter); } if (self->hPcmUtils != NULL) { - pcmDmx_Close( &self->hPcmUtils ); + 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); @@ -1095,24 +1958,24 @@ LINKSPEC_CPP void aacDecoder_Close ( HANDLE_AACDECODER self ) CAacDecoder_Close(self); } - -LINKSPEC_CPP CStreamInfo* aacDecoder_GetStreamInfo ( HANDLE_AACDECODER self ) -{ +LINKSPEC_CPP CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self) { return CAacDecoder_GetStreamInfo(self); } -LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info ) -{ +LINKSPEC_CPP INT aacDecoder_GetLibInfo(LIB_INFO *info) { int i; if (info == NULL) { return -1; } - sbrDecoder_GetLibInfo( info ); - transportDec_GetLibInfo( info ); - FDK_toolsGetLibInfo( info ); - pcmDmx_GetLibInfo( info ); + 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++) { @@ -1125,41 +1988,23 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo ( LIB_INFO *info ) info->module_id = FDK_AACDEC; /* build own library info */ - info->version = LIB_VERSION(AACDECODER_LIB_VL0, AACDECODER_LIB_VL1, AACDECODER_LIB_VL2); + 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_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 - - ; + 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/libAACdec/src/arm/block_arm.cpp b/libAACdec/src/arm/block_arm.cpp index fbc1bf3..3c1b4ba 100644 --- a/libAACdec/src/arm/block_arm.cpp +++ b/libAACdec/src/arm/block_arm.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,16 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - +----------------------------------------------------------------------------- */ -/******************************** Fraunhofer IIS *************************** +/**************************** AAC decoder library ****************************** Author(s): Arthur Tritthart - Description: (ARM optimised) Scaling of spectral data -******************************************************************************/ + Description: (ARM optimised) Scaling of spectral data +*******************************************************************************/ #define FUNCTION_CBlock_ScaleSpectralData_func1 @@ -97,26 +107,20 @@ amm-info@iis.fraunhofer.de loop overhead per sample, that goes down to 1-cycle per sample with an optimal 4x-loop construct (do - 4x - while). */ - -FDK_INLINE static void CBlock_ScaleSpectralData_func1( - FIXP_DBL *pSpectrum, - int max_band, - const SHORT * RESTRICT BandOffsets, - int SpecScale_window, - const SHORT * RESTRICT pSfbScale, - int window) -{ +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 < max_band; band++) - { + 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 */ - int scale = SpecScale_window-pSfbScale[window*16+band]; - if (scale) - { - do - { + 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]; @@ -130,11 +134,9 @@ FDK_INLINE static void CBlock_ScaleSpectralData_func1( *pSpectrum++ = tmp1; *pSpectrum++ = tmp2; *pSpectrum++ = tmp3; - } while ((runs = runs-4) != 0); - } - else - { - pSpectrum+= runs; + } while ((runs = runs - 4) != 0); + } else { + pSpectrum += runs; } } } diff --git a/libAACdec/src/block.cpp b/libAACdec/src/block.cpp index a19284e..7d2a4b9 100644 --- a/libAACdec/src/block.cpp +++ b/libAACdec/src/block.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,28 +90,33 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 @@ -111,135 +127,169 @@ amm-info@iis.fraunhofer.de 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 31 bits to prevent endless loops. + If it strikes, 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 */ + const LONG q) /*!< quantized coefficient */ { - LONG i, off, neg ; + if (fAbs(q) != 16) return (q); - if (q < 0) - { - if (q != -16) return q; - neg = 1; - } - else - { - if (q != +16) return q; - neg = 0; + LONG i, off; + for (i = 4; i < 32; i++) { + if (FDKreadBit(bs) == 0) break; } - for (i=4; ; i++) - { - if (FDKreadBits(bs,1) == 0) - break; - } - - if (i > 16) - { - if (i - 16 > CACHE_BITS) { /* cannot read more than "CACHE_BITS" bits at once in the function FDKreadBits() */ - return (MAX_QUANTIZED_VALUE + 1); /* returning invalid value that will be captured later */ - } - - off = FDKreadBits(bs,i-16) << 16; - off |= FDKreadBits(bs,16); - } - else - { - off = FDKreadBits(bs,i); - } + if (i == 32) return (MAX_QUANTIZED_VALUE + 1); + off = FDKreadBits(bs, i); i = off + (1 << i); - if (neg) i = -i; + if (q < 0) i = -i; return i; } AAC_DECODER_ERROR CBlock_ReadScaleFactorData( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs, - UINT flags - ) -{ + 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 */ + 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]; - - int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); - for (group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) - { - for (band=0; band < ScaleFactorBandsTransmitted; band++) - { - switch (pCodeBook[group*16+band]) { - - case ZERO_HCB: /* zero book */ - pScaleFactor[group*16+band] = 0; - break; - - default: /* decode scale factor */ - { - temp = CBlock_DecodeHuffmanWord(bs,hcb); - factor += temp - 60; /* MIDFAC 1.5 dB */ - } - pScaleFactor[group*16+band] = factor - 100; - break; - - case INTENSITY_HCB: /* intensity steering */ - case INTENSITY_HCB2: - temp = CBlock_DecodeHuffmanWord(bs,hcb); - position += temp - 60; - pScaleFactor[group*16+band] = position - 100; - break; - - case NOISE_HCB: /* PNS */ - if (flags & (AC_MPS_RES|AC_USAC|AC_RSVD50)) { - return AAC_DEC_PARSE_ERROR; - } - CPns_Read( &pAacDecoderChannelInfo->data.aac.PnsData, bs, hcb, pAacDecoderChannelInfo->pDynData->aScaleFactor, pAacDecoderChannelInfo->pDynData->RawDataInfo.GlobalGain, band, group); - break; + 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, SamplingRateInfo *pSamplingRateInfo) -{ +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)); - - int max_band = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); - for (window=0, group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) - { - for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++, 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); + FIXP_DBL *pSpectrum = SPEC(pSpectralCoefficient, window, + pAacDecoderChannelInfo->granuleLength); /* find scaling for current window */ - for (band=0; band < max_band; band++) - { - SpecScale_window = fMax(SpecScale_window, (int)pSfbScale[window*16+band]); + for (band = 0; band < maxSfbs; band++) { + SpecScale_window = + fMax(SpecScale_window, (int)pSfbScale[window * 16 + band]); } - if (pAacDecoderChannelInfo->pDynData->TnsData.Active) { - SpecScale_window += TNS_SCALE; + 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 */ @@ -247,79 +297,80 @@ void CBlock_ScaleSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, Sa #ifdef FUNCTION_CBlock_ScaleSpectralData_func1 - CBlock_ScaleSpectralData_func1(pSpectrum, max_band, BandOffsets, SpecScale_window, pSfbScale, window); - -#else /* FUNCTION_CBlock_ScaleSpectralData_func1 */ - for (band=0; band < max_band; band++) - { - int scale = SpecScale_window - pSfbScale[window*16+band]; - if (scale) - { - /* following relation can be used for optimizations: (BandOffsets[i]%4) == 0 for all i */ - int max_index = BandOffsets[band+1]; - for (int index = BandOffsets[band]; index < max_index; index++) - { + 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 */ +#endif /* FUNCTION_CBlock_ScaleSpectralData_func1 */ } } - } -AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const UINT flags) -{ +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); + 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)); + FDKmemclear(pCodeBook, sizeof(UCHAR) * (8 * 16)); - const int nbits = (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3; + const int nbits = + (IsLongBlock(&pAacDecoderChannelInfo->icsInfo) == 1) ? 5 : 3; - int sect_esc_val = (1 << nbits) - 1 ; + 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; ) - { + 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) { + 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)) ) { + 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) - { + while (sect_len_incr == sect_esc_val) { sect_len += sect_esc_val; sect_len_incr = FDKreadBits(bs, nbits); } - } - else { + } else { sect_len_incr = 1; } sect_len += sect_len_incr; - top = band + sect_len; if (flags & AC_ER_HCR) { @@ -327,10 +378,13 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs, 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) - { + if (sect_cb == BOOKSCL) { return AAC_DEC_INVALID_CODE_BOOK; } else { *pHcrCodeBook++ = sect_cb; @@ -339,259 +393,340 @@ AAC_DECODER_ERROR CBlock_ReadSectionData(HANDLE_FDK_BITSTREAM bs, } /* Check spectral line limits */ - if (IsLongBlock( &(pAacDecoderChannelInfo->icsInfo) )) - { + if (IsLongBlock(&(pAacDecoderChannelInfo->icsInfo))) { if (top > 64) { return AAC_DEC_DECODE_FRAME_ERROR; } } else { /* short block */ - if (top + group*16 > (8 * 16)) { + 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) - ) - { + 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; + 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). + * \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 -void InverseQuantizeBand( FIXP_DBL * RESTRICT spectrum, - INT noLines, - INT lsb, - INT scale ) -{ - const FIXP_DBL * RESTRICT InverseQuantTabler=(FIXP_DBL *)InverseQuantTable; - const FIXP_DBL * RESTRICT MantissaTabler=(FIXP_DBL *)MantissaTable[lsb]; - const SCHAR* RESTRICT ExponentTabler=(SCHAR*)ExponentTable[lsb]; +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 *ptr = spectrum; - FIXP_DBL signedValue; + FIXP_DBL *RESTRICT ptr = spectrum; + FIXP_DBL signedValue; - FDK_ASSERT(noLines>2); - for (INT i=noLines; i--; ) - { - if ((signedValue = *ptr++) != FL2FXCONST_DBL(0)) - { - FIXP_DBL value = fAbs(signedValue); - UINT freeBits = CntLeadingZeros(value); - UINT exponent = 32 - freeBits; + 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 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); + 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]); + value = fMultDiv2((FIXP_DBL)temp, MantissaTabler[exponent]); - /* + 1 compensates fMultDiv2() */ - scaleValueInPlace(&value, scale + ExponentTabler[exponent] + 1); + /* + 1 compensates fMultDiv2() */ + scaleValueInPlace(&value, scale + ExponentTabler[exponent]); - signedValue = (signedValue < (FIXP_DBL)0) ? -value : value; - ptr[-1] = signedValue; - } + signedValue = (signedValue < (FIXP_DBL)0) ? -value : value; + ptr[-1] = signedValue; } + } } -AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo) -{ +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); + 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); - - 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++) - { + 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]; - - int noLines = BandOffsets[band+1] - BandOffsets[band]; - int bnds = group*16+band; - int i; - - if ((pCodeBook[bnds] == ZERO_HCB) - || (pCodeBook[bnds] == INTENSITY_HCB) - || (pCodeBook[bnds] == INTENSITY_HCB2) - ) + 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 ; + 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; } - /* Find max spectral line value of the current sfb */ - FIXP_DBL locMax = (FIXP_DBL)0; + locMax = maxabs_D(pSpectralCoefficient, noLines); - for (i = noLines; i-- ; ) { - /* Expensive memory access */ - locMax = fMax(fixp_abs(pSpectralCoefficient[i]), locMax); + 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_DECODE_FRAME_ERROR; + return AAC_DEC_PARSE_ERROR; } - /* - The inverse quantized spectral lines are defined by: - pSpectralCoefficient[i] = Sign(pSpectralCoefficient[i]) * 2^(0.25*pScaleFactor[bnds]) * pSpectralCoefficient[i]^(4/3) - This is equivalent to: - pSpectralCoefficient[i] = Sign(pSpectralCoefficient[i]) * (2^(pScaleFactor[bnds] % 4) * pSpectralCoefficient[i]^(4/3)) - pSpectralCoefficient_e[i] += pScaleFactor[bnds]/4 + /* 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 ; - int lsb = pScaleFactor [bnds] & 0x03 ; - int scale = GetScaleFromValue(locMax, lsb); + int msb = pScaleFactor[bnds] >> 2; - pSfbScale[window*16+band] = msb - scale; - InverseQuantizeBand(pSpectralCoefficient, noLines, lsb, scale); + /* 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++) */ - return AAC_DEC_OK; -} + /* 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++)*/ -AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const UINT flags) -{ - int i,index; - int window,group,groupwin,groupoffset,band; - UCHAR *RESTRICT pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; - const SHORT *RESTRICT BandOffsets = GetScaleFactorBandOffsets(&pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo); + return AAC_DEC_OK; +} - SPECTRAL_PTR pSpectralCoefficient = pAacDecoderChannelInfo->pSpectralCoefficient; - FIXP_DBL locMax; +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); - int ScaleFactorBandsTransmitted = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); + SPECTRAL_PTR pSpectralCoefficient = + pAacDecoderChannelInfo->pSpectralCoefficient; FDK_ASSERT(BandOffsets != NULL); FDKmemclear(pSpectralCoefficient, sizeof(SPECTRUM)); - if ( (flags & AC_ER_HCR) == 0 ) - { + 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 */ - for (group=0; group < GetWindowGroups(&pAacDecoderChannelInfo->icsInfo); group++) - { - for (band=0; band < ScaleFactorBandsTransmitted; band++) - { - int bnds = group*16+band; + 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) */ + /* 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]; + 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; - - for (groupwin=0; groupwin < GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); groupwin++) - { - window = groupoffset + groupwin; - - FIXP_DBL *mdctSpectrum = SPEC(pSpectralCoefficient, window, pAacDecoderChannelInfo->granuleLength); - - locMax = (FIXP_DBL)0 ; - - for (index=BandOffsets[band]; index < BandOffsets[band+1]; index+=step) - { - int idx = CBlock_DecodeHuffmanWord(bs,hcb); - - for (i=0; i<step; i++) { - FIXP_DBL tmp; - - tmp = (FIXP_DBL)((idx & mask)-offset); - idx >>= bits; + 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 (offset == 0) { - if (tmp != FIXP_DBL(0)) - tmp = (FDKreadBits(bs,1))? -tmp : tmp; + if (currentCB == ESCBOOK) { + for (int j = 0; j < 2; j++) + mdctSpectrum[index + j] = (FIXP_DBL)CBlock_GetEscape( + bs, (LONG)mdctSpectrum[index + j]); } - mdctSpectrum[index+i] = tmp; } - - if (currentCB == ESCBOOK) - { - mdctSpectrum[index+0] = (FIXP_DBL)CBlock_GetEscape(bs, (LONG)mdctSpectrum[index+0]); - mdctSpectrum[index+1] = (FIXP_DBL)CBlock_GetEscape(bs, (LONG)mdctSpectrum[index+1]); - + 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 += GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo,group); + groupoffset += max_groupwin; } /* plain huffman decoding (short) finished */ } + /* HCR - Huffman Codeword Reordering short */ - else /* if ( flags & AC_ER_HCR ) */ + 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 ) { - + if (pAacDecoderChannelInfo->pDynData->specificTo.aac + .lenOfReorderedSpectralData != 0) { /* HCR initialization short */ hcrStatus = HcrInit(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs); @@ -600,7 +735,8 @@ AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs, } /* HCR decoding short */ - hcrStatus = HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs); + hcrStatus = + HcrDecoder(hHcr, pAacDecoderChannelInfo, pSamplingRateInfo, bs); if (hcrStatus != 0) { #if HCR_ERROR_CONCEALMENT @@ -610,100 +746,314 @@ AAC_DECODER_ERROR CBlock_ReadSpectralData(HANDLE_FDK_BITSTREAM bs, #endif /* HCR_ERROR_CONCEALMENT */ } - FDKpushFor (bs, pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData); + 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; +} - 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)); +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; - return AAC_DEC_OK; + /* 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; + } -void ApplyTools ( CAacDecoderChannelInfo *pAacDecoderChannelInfo[], - const SamplingRateInfo *pSamplingRateInfo, - const UINT flags, - const int channel ) -{ + return errorAAC; +} - if ( !(flags & (AC_USAC|AC_RSVD50|AC_MPS_RES)) ) { - 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 - ); +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); } - CTns_Apply ( - &pAacDecoderChannelInfo[channel]->pDynData->TnsData, - &pAacDecoderChannelInfo[channel]->icsInfo, - pAacDecoderChannelInfo[channel]->pSpectralCoefficient, - pSamplingRateInfo, - pAacDecoderChannelInfo[channel]->granuleLength - ); + 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) -{ +static int getWindow2Nr(int length, int shape) { int nr = 0; if (shape == 2) { /* Low Overlap, 3/4 zeroed */ - nr = (length * 3)>>2; + nr = (length * 3) >> 2; } return nr; } -void CBlock_FrequencyToTime(CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - INT_PCM outSamples[], - const SHORT frameLen, - const int stride, - const int frameOk, - FIXP_DBL *pWorkBuffer1 ) -{ - int fr, fl, tl, nSamples, nSpec; +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; - /* 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. +#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 ) { + switch (pAacDecoderChannelInfo->icsInfo.WindowSequence) { default: - case OnlyLongSequence: + case BLOCK_LONG: fl = frameLen; - fr = frameLen - getWindow2Nr(frameLen, GetWindowShape(&pAacDecoderChannelInfo->icsInfo)); + 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 LongStopSequence: + case BLOCK_STOP: fl = frameLen >> 3; fr = frameLen; break; - case LongStartSequence: /* or StopStartSequence */ + case BLOCK_START: /* or StopStartSequence */ fl = frameLen; fr = frameLen >> 3; break; - case EightShortSequence: + case BLOCK_SHORT: fl = fr = frameLen >> 3; tl >>= 3; nSpec = 8; @@ -711,48 +1061,198 @@ void CBlock_FrequencyToTime(CAacDecoderStaticChannelInfo *pAacDecoderStaticChann } { - int i; + int last_frame_lost = pAacDecoderStaticChannelInfo->last_lpc_lost; - { - FIXP_DBL *tmp = pAacDecoderChannelInfo->pComData->workBufferCore1->mdctOutTemp; - - nSamples = imdct_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 ); - - for (i=0; i<frameLen; i++) { - outSamples[i*stride] = IMDCT_SCALE(tmp[i]); + 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, - INT_PCM outSamples[], - const short frameLen, - const char stride ) -{ - InvMdctTransformLowDelay_fdk ( - SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient), - pAacDecoderChannelInfo->specScale[0], - outSamples, - pAacDecoderStaticChannelInfo->pOverlapBuffer, - stride, - frameLen - ); +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/libAACdec/src/block.h b/libAACdec/src/block.h index f9394f6..f0f56cd 100644 --- a/libAACdec/src/block.h +++ b/libAACdec/src/block.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: long/short-block decoding -******************************************************************************/ +*******************************************************************************/ #ifndef BLOCK_H #define BLOCK_H @@ -97,25 +109,19 @@ amm-info@iis.fraunhofer.de #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 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) */ /*! @@ -126,28 +132,21 @@ void CPns_Apply (const CPnsData *pPnsData, \return none */ -void CTns_ReadDataPresentFlag(HANDLE_FDK_BITSTREAM bs, - CTnsData *pTnsData); - -void CTns_ReadDataPresentUsac( - HANDLE_FDK_BITSTREAM hBs, - CTnsData *pTnsData0, - CTnsData *pTnsData1, - const CIcsInfo *pIcsInfo, - const UINT flags, - 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); +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 */ @@ -155,17 +154,16 @@ 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. + * 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 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 - ); + CAacDecoderChannelInfo *pAacDecoderChannelInfo, HANDLE_FDK_BITSTREAM bs, + const UINT flags); /** * \brief Read Huffman encoded spectral data. @@ -173,111 +171,124 @@ AAC_DECODER_ERROR CBlock_ReadScaleFactorData( * \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); +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); +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. + * \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, SamplingRateInfo *pSamplingRateInfo); +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 int channel ); +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, - INT_PCM outSamples[], - const SHORT frameLen, - const int stride, - const int frameOk, - FIXP_DBL *pWorkBuffer1); +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, - INT_PCM outSamples[], - const short frameLen, - const char stride); +void CBlock_FrequencyToTimeLowDelay( + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, + CAacDecoderChannelInfo *pAacDecoderChannelInfo, FIXP_PCM outSamples[], + const short frameLen); -AAC_DECODER_ERROR CBlock_InverseQuantizeSpectralData(CAacDecoderChannelInfo *pAacDecoderChannelInfo, SamplingRateInfo *pSamplingRateInfo); +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. + * \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 ) -{ +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); + 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 ; + 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; + 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]) ; + *pValue = fMultDiv2(invQVal, MantissaTable[lsb][exponent]); /* + 1 compensates fMultDiv2(). */ - return ExponentTable [lsb][exponent] + 1; + 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. + * \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. */ +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. */ } - -//#ifdef AACDEC_HUFFMANDECODER_ENABLE - /*! \brief Read huffman codeword @@ -286,27 +297,24 @@ FDK_INLINE int GetScaleFromValue (FIXP_DBL value, unsigned int lsb) \return index value */ -inline int CBlock_DecodeHuffmanWord( HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */ - const CodeBookDescription *hcb ) /*!< pointer to codebook description */ +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; + const USHORT(*CodeBook)[HuffmanEntries] = hcb->CodeBook; - while (1) - { - val = CodeBook[index][FDKreadBits(bs,HuffmanBits)]; /* Expensive memory access */ + while (1) { + val = CodeBook[index] + [FDKreadBits(bs, HuffmanBits)]; /* Expensive memory access */ - if ((val & 1) == 0) - { - index = val>>2; + if ((val & 1) == 0) { + index = val >> 2; continue; - } - else - { - if (val & 2) - { - FDKpushBackCache(bs,1); + } else { + if (val & 2) { + FDKpushBackCache(bs, 1); } val >>= 2; @@ -316,7 +324,22 @@ inline int CBlock_DecodeHuffmanWord( HANDLE_FDK_BITSTREAM bs, return val; } +inline int CBlock_DecodeHuffmanWordCB( + HANDLE_FDK_BITSTREAM bs, /*!< pointer to bitstream */ + const USHORT ( + *CodeBook)[HuffmanEntries]) /*!< pointer to codebook description */ +{ + UINT index = 0; -//#endif /* AACDEC_HUFFMANDECODER_ENABLE */ + 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/libAACdec/src/channel.cpp b/libAACdec/src/channel.cpp index 5475079..dbbf58a 100644 --- a/libAACdec/src/channel.cpp +++ b/libAACdec/src/channel.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,21 +90,21 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 "FDK_tools_rom.h" #include "conceal.h" @@ -101,27 +112,46 @@ amm-info@iis.fraunhofer.de #include "aacdec_hcr.h" +#include "usacdec_lpd.h" +#include "usacdec_fac.h" -static -void MapMidSideMaskToPnsCorrelation (CAacDecoderChannelInfo *pAacDecoderChannelInfo[2]) -{ +static void MapMidSideMaskToPnsCorrelation( + CAacDecoderChannelInfo *pAacDecoderChannelInfo[2]) { int group; - for (group = 0 ; group < pAacDecoderChannelInfo[L]->icsInfo.WindowGroups; 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 */ + 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 @@ -129,79 +159,232 @@ void MapMidSideMaskToPnsCorrelation (CAacDecoderChannelInfo *pAacDecoderChannelI \return none */ -void CChannelElement_Decode( CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], /*!< pointer to aac decoder channel info */ - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2], - SamplingRateInfo *pSamplingRateInfo, - UINT flags, - int el_channels) -{ - int ch, maybe_jstereo = 0; +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; + } + } - maybe_jstereo = (el_channels > 1); + if (maybe_jstereo) { + maxSfBandsL = + GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo); + maxSfBandsR = + GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo); - for (ch = 0; ch < el_channels; ch++) { - if ( pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_IMDCT - || pAacDecoderChannelInfo[ch]->renderMode == AACDEC_RENDER_ELDFB ) - { - CBlock_InverseQuantizeSpectralData(pAacDecoderChannelInfo[ch], pSamplingRateInfo); + /* 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))) { + CJointStereo_ApplyIS( + pAacDecoderChannelInfo, + GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo, + pSamplingRateInfo), + GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo), + GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), + GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo), + pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ? 1 + : 0); } - } + } /* 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) { - int maxSfBandsL = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo); - int maxSfBandsR = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[R]->icsInfo); - if (pAacDecoderChannelInfo[L]->data.aac.PnsData.PnsActive || pAacDecoderChannelInfo[R]->data.aac.PnsData.PnsActive) { - MapMidSideMaskToPnsCorrelation(pAacDecoderChannelInfo); + } /* 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)); } - - CJointStereo_ApplyMS(pAacDecoderChannelInfo, - GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo, pSamplingRateInfo), - GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo), - GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), - maxSfBandsL, - maxSfBandsR); } - /* apply intensity stereo */ /* modifies pAacDecoderChannelInfo[]->aSpecSfb */ - CJointStereo_ApplyIS(pAacDecoderChannelInfo, - GetScaleFactorBandOffsets(&pAacDecoderChannelInfo[L]->icsInfo, pSamplingRateInfo), - GetWindowGroupLengthTable(&pAacDecoderChannelInfo[L]->icsInfo), - GetWindowGroups(&pAacDecoderChannelInfo[L]->icsInfo), - GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo[L]->icsInfo), - pAacDecoderChannelInfo[L]->pDynData->RawDataInfo.CommonWindow ? 1 : 0); + } /* 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); + } - for (ch = 0; ch < el_channels; ch++) - { - { - /* write pAacDecoderChannelInfo[ch]->specScale */ - CBlock_ScaleSpectralData(pAacDecoderChannelInfo[ch], pSamplingRateInfo); + 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++)" */ - ApplyTools (pAacDecoderChannelInfo, pSamplingRateInfo, flags, 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 - ); + CRvlc_ElementCheck(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo, + flags, el_channels); } -void CChannel_CodebookTableInit(CAacDecoderChannelInfo *pAacDecoderChannelInfo) -{ +void CChannel_CodebookTableInit( + CAacDecoderChannelInfo *pAacDecoderChannelInfo) { int b, w, maxBands, maxWindows; int maxSfb = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo); UCHAR *pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; - if ( IsLongBlock(&pAacDecoderChannelInfo->icsInfo) ) { + if (IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) { maxBands = 64; maxWindows = 1; } else { @@ -209,60 +392,69 @@ void CChannel_CodebookTableInit(CAacDecoderChannelInfo *pAacDecoderChannelInfo) maxWindows = 8; } - for (w = 0; w<maxWindows; w++) { + for (w = 0; w < maxWindows; w++) { for (b = 0; b < maxSfb; b++) { pCodeBook[b] = ESCBOOK; } - for (; b<maxBands; b++) { + 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, - const SamplingRateInfo *pSamplingRateInfo, - const UINT flags, - const UINT frame_length, - const UCHAR numberOfChannels, - const SCHAR epConfig, - HANDLE_TRANSPORTDEC pTpDec - ) -{ +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) ); + FDK_ASSERT((numberOfChannels == 1) || (numberOfChannels == 2)); /* Get channel element sequence table */ - list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0); + 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; } - if (flags & (AC_ELD|AC_SCALABLE)) { - pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow = 1; - if (numberOfChannels == 2) { - pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow; + 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; + pAacDecoderChannelInfo[1]->pDynData->RawDataInfo.CommonWindow = + pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow; } } @@ -272,170 +464,413 @@ AAC_DECODER_ERROR CChannelElement_Read(HANDLE_FDK_BITSTREAM hBs, 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: - /* Read individual channel info */ - error = IcsRead( hBs, - &pAacDecoderChannelInfo[ch]->icsInfo, - pSamplingRateInfo, - flags ); - - if (numberOfChannels == 2 && pAacDecoderChannelInfo[0]->pDynData->RawDataInfo.CommonWindow) { - pAacDecoderChannelInfo[1]->icsInfo = pAacDecoderChannelInfo[0]->icsInfo; - } - break; - - - case ltp_data_present: - if (FDKreadBits(hBs, 1) != 0) { - error = AAC_DEC_UNSUPPORTED_PREDICTION; - } - break; - - case ms: - if ( CJointStereo_Read( - hBs, - &pAacDecoderChannelInfo[0]->pComData->jointStereoData, - GetWindowGroups(&pAacDecoderChannelInfo[0]->icsInfo), - GetScaleMaxFactorBandsTransmitted(&pAacDecoderChannelInfo[0]->icsInfo, - &pAacDecoderChannelInfo[1]->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 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(). */ + + 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: - 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); - 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 esc2_rvlc: - if (flags & AC_ER_RVLC) { - CRvlc_Decode( - pAacDecoderChannelInfo[ch], - pAacDecoderStaticChannelInfo[ch], - hBs - ); + error = CLpdChannelStream_Read(/* = lpd_channel_stream() */ + hBs, pAacDecoderChannelInfo[ch], + pAacDecoderStaticChannelInfo[ch], + pSamplingRateInfo, flags); } - break; - case esc1_hcr: - if (flags & AC_ER_HCR) { - CHcr_Read(hBs, pAacDecoderChannelInfo[ch] ); - } - break; - - case spectral_data: - error = CBlock_ReadSpectralData( hBs, - pAacDecoderChannelInfo[ch], - pSamplingRateInfo, - flags ); - if (flags & AC_ELD) { - pAacDecoderChannelInfo[ch]->renderMode = AACDEC_RENDER_ELDFB; - } else { + 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; - - - /* 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); - } - break; - case adtscrc_end_reg2: - if (pTpDec != NULL) { - transportDec_CrcEndReg(pTpDec, crcReg2); - } - 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; + 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) { @@ -446,6 +881,40 @@ AAC_DECODER_ERROR CChannelElement_Read(HANDLE_FDK_BITSTREAM hBs, } 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/libAACdec/src/channel.h b/libAACdec/src/channel.h index 1146998..ed46666 100644 --- a/libAACdec/src/channel.h +++ b/libAACdec/src/channel.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,46 +90,48 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: -******************************************************************************/ +*******************************************************************************/ #ifndef CHANNEL_H #define CHANNEL_H #include "common_fix.h" -#include "FDK_bitstream.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. + * \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 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) - * \param stride factor for accessing output */ -void CChannelElement_Decode ( CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[2], - SamplingRateInfo *pSamplingRateInfo, - UINT flags, - int el_channels ); - +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. @@ -126,23 +139,22 @@ void CChannelElement_Decode ( CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], * \param pAacDecoderChannelInfo pointer array to store channel information. * \param aot Audio Object Type * \param pSamplingRateInfo sampling rate info table. - * \param flags 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 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, - const SamplingRateInfo *pSamplingRateInfo, - const UINT flags, - const UINT frame_length, - const UCHAR numberOfChannels, - const SCHAR epConfig, - HANDLE_TRANSPORTDEC pTpDec - ); +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/libAACdec/src/channelinfo.cpp b/libAACdec/src/channelinfo.cpp index 76d5895..79add5b 100644 --- a/libAACdec/src/channelinfo.cpp +++ b/libAACdec/src/channelinfo.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,27 +90,23 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 IcsReadMaxSfb(HANDLE_FDK_BITSTREAM bs, CIcsInfo *pIcsInfo, + const SamplingRateInfo *pSamplingRateInfo) { AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK; int nbits; @@ -110,36 +117,31 @@ AAC_DECODER_ERROR IcsReadMaxSfb ( nbits = 4; pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short; } - pIcsInfo->MaxSfBands = (UCHAR) FDKreadBits(bs, nbits); + pIcsInfo->MaxSfBands = (UCHAR)FDKreadBits(bs, nbits); - if (pIcsInfo->MaxSfBands > pIcsInfo->TotalSfBands){ + 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 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 = OnlyLongSequence; + if (flags & AC_ELD) { + pIcsInfo->WindowSequence = BLOCK_LONG; pIcsInfo->WindowShape = 0; - } - else { - if ( !(flags & (AC_USAC|AC_RSVD50)) ) { - FDKreadBits(bs,1); + } else { + if (!(flags & (AC_USAC | AC_RSVD50 | AC_RSV603DA))) { + FDKreadBits(bs, 1); } - pIcsInfo->WindowSequence = (UCHAR) FDKreadBits(bs,2); - pIcsInfo->WindowShape = (UCHAR) 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 */ @@ -148,8 +150,8 @@ AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, } /* Sanity check */ - if ( (flags & (AC_ELD|AC_LD)) && pIcsInfo->WindowSequence != OnlyLongSequence) { - pIcsInfo->WindowSequence = OnlyLongSequence; + if ((flags & (AC_ELD | AC_LD)) && pIcsInfo->WindowSequence != BLOCK_LONG) { + pIcsInfo->WindowSequence = BLOCK_LONG; ErrorStatus = AAC_DEC_PARSE_ERROR; goto bail; } @@ -159,11 +161,12 @@ AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, goto bail; } - if (IsLongBlock(pIcsInfo)) - { - if ( !(flags & (AC_ELD|AC_SCALABLE|AC_BSAC|AC_USAC|AC_RSVD50)) ) /* If not ELD nor Scalable nor BSAC nor USAC syntax then ... */ + 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 */ + if ((UCHAR)FDKreadBits(bs, 1) != 0) /* UCHAR PredictorDataPresent */ { ErrorStatus = AAC_DEC_UNSUPPORTED_PREDICTION; goto bail; @@ -172,45 +175,36 @@ AAC_DECODER_ERROR IcsRead(HANDLE_FDK_BITSTREAM bs, pIcsInfo->WindowGroups = 1; pIcsInfo->WindowGroupLength[0] = 1; - } - else - { + } else { INT i; UINT mask; - pIcsInfo->ScaleFactorGrouping = (UCHAR) FDKreadBits(bs,7); + pIcsInfo->ScaleFactorGrouping = (UCHAR)FDKreadBits(bs, 7); - pIcsInfo->WindowGroups = 0 ; + pIcsInfo->WindowGroups = 0; - for (i=0; i < (8-1); i++) - { + for (i = 0; i < (8 - 1); i++) { mask = 1 << (6 - i); pIcsInfo->WindowGroupLength[i] = 1; - if (pIcsInfo->ScaleFactorGrouping & mask) - { + if (pIcsInfo->ScaleFactorGrouping & mask) { pIcsInfo->WindowGroupLength[pIcsInfo->WindowGroups]++; - } - else - { + } else { pIcsInfo->WindowGroups++; } } /* loop runs to i < 7 only */ - pIcsInfo->WindowGroupLength[8-1] = 1; + pIcsInfo->WindowGroupLength[8 - 1] = 1; pIcsInfo->WindowGroups++; } - bail: - if (ErrorStatus == AAC_DEC_OK) - pIcsInfo->Valid = 1; + if (ErrorStatus == AAC_DEC_OK) pIcsInfo->Valid = 1; return ErrorStatus; } - /* interleave codebooks the following way @@ -224,53 +218,80 @@ bail: (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 - ) -{ +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 512: - index = 3; - break; - case 480: - index = 4; - break; - - default: - return AAC_DEC_UNSUPPORTED_FORMAT; + 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->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(t->ScaleFactorBands_Long[t->NumberOfScaleFactorBands_Long] == samplesPerFrame); - FDK_ASSERT(t->ScaleFactorBands_Short == NULL || t->ScaleFactorBands_Short[t->NumberOfScaleFactorBands_Short]*8 == samplesPerFrame); + 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/libAACdec/src/channelinfo.h b/libAACdec/src/channelinfo.h index e092ab3..7c95e12 100644 --- a/libAACdec/src/channelinfo.h +++ b/libAACdec/src/channelinfo.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: individual channel stream info -******************************************************************************/ +*******************************************************************************/ #ifndef CHANNELINFO_H #define CHANNELINFO_H @@ -108,10 +120,21 @@ amm-info@iis.fraunhofer.de #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" +#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 { @@ -122,21 +145,11 @@ typedef enum { AACDEC_RENDER_INTIMDCT } AACDEC_RENDER_MODE; -enum { - MAX_QUANTIZED_VALUE = 8191 -}; - -enum -{ - OnlyLongSequence = 0, - LongStartSequence, - EightShortSequence, - LongStopSequence -}; +enum { MAX_QUANTIZED_VALUE = 8191 }; +typedef enum { FD_LONG, FD_SHORT, LPD } USAC_COREMODE; -typedef struct -{ +typedef struct { const SHORT *ScaleFactorBands_Long; const SHORT *ScaleFactorBands_Short; UCHAR NumberOfScaleFactorBands_Long; @@ -145,200 +158,315 @@ typedef struct UINT samplingRate; } SamplingRateInfo; -typedef struct -{ +typedef struct { UCHAR CommonWindow; UCHAR GlobalGain; } CRawDataInfo; -typedef struct -{ +typedef struct { UCHAR WindowGroupLength[8]; UCHAR WindowGroups; UCHAR Valid; - UCHAR WindowShape; /* 0: sine window, 1: KBD, 2: low overlap */ - UCHAR WindowSequence; /* See enum above, 0: long, 1: start, 2: short, 3: stop */ + 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 -{ +enum { ZERO_HCB = 0, - ESCBOOK = 11, + ESCBOOK = 11, NSPECBOOKS = ESCBOOK + 1, - BOOKSCL = NSPECBOOKS, - NOISE_HCB = 13, + BOOKSCL = NSPECBOOKS, + NOISE_HCB = 13, INTENSITY_HCB2 = 14, - INTENSITY_HCB = 15, + INTENSITY_HCB = 15, LAST_HCB }; -#define TNS_SCALE 3 +/* 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 -{ +typedef struct { FIXP_DBL *pOverlapBuffer; mdct_t IMdct; + CArcoData *hArCo; + INT pnsCurrentSeed; - CDrcChannelData drcData; + /* 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; -} CAacDecoderStaticChannelInfo; + 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. */ - CTnsData TnsData; - CRawDataInfo RawDataInfo; + 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 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; - } specificTo; + 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 { - CAacDecoderDynamicData pAacDecoderDynamicData[2]; + UCHAR DrmBsBuffer[DRM_BS_BUFFER_SIZE]; - /* Common signal data, can be used once the bit stream data from above is not used anymore. */ + /* Common signal data, can be used once the bit stream data from above is not + * used anymore. */ FIXP_DBL mdctOutTemp[1024]; - FIXP_DBL sbrWorkBuffer[1024*2]; -} CWorkBufferCore1; + 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 { - - CWorkBufferCore1 *workBufferCore1; - FIXP_DBL* workBufferCore2; + CAacDecoderDynamicData pAacDecoderDynamicData[2]; CPnsInterChannelData pnsInterChannelData; - INT pnsCurrentSeed; - INT pnsRandomSeed[(8*16)]; + INT pnsRandomSeed[(8 * 16)]; - CJointStereoData jointStereoData; /* One for one element */ + 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 */ + 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; + } + overlay; } CAacDecoderCommonData; +typedef struct { + CWorkBufferCore1 *pWorkBufferCore1; + CCplxPredictionData *cplxPredictionData; +} CAacDecoderCommonStaticData; /* - * This struct must be allocated one for every channels 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. + * 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.. + * - 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 -{ - 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 */ - +typedef struct { shouldBeUnion { struct { + FIXP_DBL fac_data0[LFAC]; + UCHAR 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; - struct { - } usac; - } 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; - CAacDecoderDynamicData *pDynData; /* Data required for one element and discarded after decoding */ - CAacDecoderCommonData *pComData; /* Data required for one channel at a time during decode */ + 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); +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 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 - ); +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. - + \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 + \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], - const short *pScaleFactorBandOffsets, - const UCHAR *pWindowGroupLength, - const int windowGroups, - const int scaleFactorBandsTransmittedL, - const int scaleFactorBandsTransmittedR); +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 @@ -360,91 +488,79 @@ void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], const int scaleFactorBandsTransmitted, const UINT CommonWindow); - /* aacdec_pns.cpp */ -int CPns_IsPnsUsed (const CPnsData *pPnsData, - const int group, - const int band); +int CPns_IsPnsUsed(const CPnsData *pPnsData, const int group, const int band); -void CPns_SetCorrelation(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 IsValid(const CIcsInfo *pIcsInfo) { return pIcsInfo->Valid; } -inline UCHAR IsLongBlock(const CIcsInfo *pIcsInfo) -{ - return (pIcsInfo->WindowSequence != EightShortSequence); +inline UCHAR IsLongBlock(const CIcsInfo *pIcsInfo) { + return (pIcsInfo->WindowSequence != BLOCK_SHORT); } -inline UCHAR GetWindowShape(const CIcsInfo *pIcsInfo) -{ +inline UCHAR GetWindowShape(const CIcsInfo *pIcsInfo) { return pIcsInfo->WindowShape; } -inline UCHAR GetWindowSequence(const CIcsInfo *pIcsInfo) -{ +inline BLOCK_TYPE GetWindowSequence(const CIcsInfo *pIcsInfo) { return pIcsInfo->WindowSequence; } -inline const SHORT *GetScaleFactorBandOffsets(const CIcsInfo *pIcsInfo, const SamplingRateInfo* samplingRateInfo) -{ - if (IsLongBlock(pIcsInfo)) - { +inline const SHORT *GetScaleFactorBandOffsets( + const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) { + if (IsLongBlock(pIcsInfo)) { return samplingRateInfo->ScaleFactorBands_Long; - } - else - { + } else { return samplingRateInfo->ScaleFactorBands_Short; } } -inline int GetWindowsPerFrame(const CIcsInfo *pIcsInfo) -{ - return (pIcsInfo->WindowSequence == EightShortSequence) ? 8 : 1; +inline UCHAR GetNumberOfScaleFactorBands( + const CIcsInfo *pIcsInfo, const SamplingRateInfo *samplingRateInfo) { + if (IsLongBlock(pIcsInfo)) { + return samplingRateInfo->NumberOfScaleFactorBands_Long; + } else { + return samplingRateInfo->NumberOfScaleFactorBands_Short; + } } -inline UCHAR GetWindowGroups(const CIcsInfo *pIcsInfo) -{ +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) -{ +inline UCHAR GetWindowGroupLength(const CIcsInfo *pIcsInfo, const INT index) { return pIcsInfo->WindowGroupLength[index]; } -inline const UCHAR *GetWindowGroupLengthTable(const CIcsInfo *pIcsInfo) -{ +inline const UCHAR *GetWindowGroupLengthTable(const CIcsInfo *pIcsInfo) { return pIcsInfo->WindowGroupLength; } -inline UCHAR GetScaleFactorBandsTransmitted(const CIcsInfo *pIcsInfo) -{ +inline UCHAR GetScaleFactorBandsTransmitted(const CIcsInfo *pIcsInfo) { return pIcsInfo->MaxSfBands; } -inline UCHAR GetScaleMaxFactorBandsTransmitted(const CIcsInfo *pIcsInfo0, const CIcsInfo *pIcsInfo1) -{ +inline UCHAR GetScaleMaxFactorBandsTransmitted(const CIcsInfo *pIcsInfo0, + const CIcsInfo *pIcsInfo1) { return fMax(pIcsInfo0->MaxSfBands, pIcsInfo1->MaxSfBands); } -inline UCHAR GetScaleFactorBandsTotal(const CIcsInfo *pIcsInfo) -{ +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) -{ +inline UCHAR GetMaximumTnsBands(const CIcsInfo *pIcsInfo, + const int samplingRateIndex) { return tns_max_bands_tbl[samplingRateIndex][!IsLongBlock(pIcsInfo)]; } #endif /* #ifndef CHANNELINFO_H */ - diff --git a/libAACdec/src/conceal.cpp b/libAACdec/src/conceal.cpp index 1c313ef..91ba488 100644 --- a/libAACdec/src/conceal.cpp +++ b/libAACdec/src/conceal.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,53 +90,58 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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. + 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. + 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) + 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. + 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. + 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" @@ -133,171 +149,153 @@ amm-info@iis.fraunhofer.de #include "aac_rom.h" #include "genericStds.h" - /* PNS (of block) */ #include "aacdec_pns.h" #include "block.h" -#include "FDK_tools_rom.h" - -#define CONCEAL_DFLT_COMF_NOISE_LEVEL ( 46 ) /* ~= -70 dB */ +#define CONCEAL_DFLT_COMF_NOISE_LEVEL (0x100000) +#define CONCEAL_NOT_DEFINED ((UCHAR)-1) /* default settings */ -#define CONCEAL_DFLT_FADEOUT_FRAMES ( 5 ) -#define CONCEAL_DFLT_FADEIN_FRAMES ( 5 ) -#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES ( 3 ) +#define CONCEAL_DFLT_FADEOUT_FRAMES (0) +#define CONCEAL_DFLT_FADEIN_FRAMES (0) +#define CONCEAL_DFLT_MUTE_RELEASE_FRAMES (0) -#define CONCEAL_DFLT_FADE_FACTOR ( 0.707106781186548f ) /* 1/sqrt(2) */ +#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) +#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) +#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; +} 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) */ + 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 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, +static int CConcealment_ApplyInter( + CConcealmentInfo *pConcealmentInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const int samplesPerFrame, - const int improveTonal, - const int frameOk - ); - - + const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, + const int improveTonal, const int frameOk, const int mute_release_active); -static int - CConcealment_ApplyNoise ( +static int CConcealment_ApplyNoise( CConcealmentInfo *pConcealmentInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const int samplesPerFrame, - const UINT flags - ); + const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, + const UINT flags); -static void - CConcealment_UpdateState ( - CConcealmentInfo *pConcealmentInfo, - int frameOk - ); - -static void - CConcealment_ApplyRandomSign ( - int iRandomPhase, - FIXP_DBL *spec, - int samplesPerFrame - ); +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 int CConcealment_GetWinSeq(int prevWinSeq) -{ - int newWinSeq = OnlyLongSequence; +static BLOCK_TYPE CConcealment_GetWinSeq(int prevWinSeq) { + BLOCK_TYPE newWinSeq = BLOCK_LONG; /* Try to have only long blocks */ - if ( prevWinSeq == LongStartSequence - || prevWinSeq == EightShortSequence ) - { - newWinSeq = LongStopSequence; + if (prevWinSeq == BLOCK_START || prevWinSeq == BLOCK_SHORT) { + newWinSeq = BLOCK_STOP; } return (newWinSeq); } - /*! \brief Init common concealment information data - \pConcealCommonData Pointer to the concealment common data structure. - - \return none + \param pConcealCommonData Pointer to the concealment common data structure. */ -void - CConcealment_InitCommonData (CConcealParams *pConcealCommonData) -{ - if (pConcealCommonData != NULL) - { +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->numFadeOutFrames = CONCEAL_DFLT_FADEOUT_FRAMES; + pConcealCommonData->numFadeInFrames = CONCEAL_DFLT_FADEIN_FRAMES; pConcealCommonData->numMuteReleaseFrames = CONCEAL_DFLT_MUTE_RELEASE_FRAMES; - pConcealCommonData->comfortNoiseLevel = CONCEAL_DFLT_COMF_NOISE_LEVEL; + 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]; + 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]; + 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. - \pConcealCommonData Pointer to common concealment data (for all channels) - - \return Concealment method. + \param pConcealCommonData Pointer to common concealment data (for all + channels) */ -CConcealmentMethod - CConcealment_GetMethod( CConcealParams *pConcealCommonData ) -{ +CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData) { CConcealmentMethod method = ConcealMethodNone; if (pConcealCommonData != NULL) { @@ -307,95 +305,95 @@ CConcealmentMethod return (method); } - /*! \brief Init concealment information for each channel - The function initializes the concealment information. Two methods can be chosen: - 0 = interpolation method (adds delay) - 1 = noise substitution (no delay, low complexity) - - \return none + \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, - int samplesPerFrame ) -{ +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; - FDKmemclear(pConcealChannelInfo->spectralCoefficient, 1024 * sizeof(FIXP_CNCL)); + 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->windowSequence = 0; - pConcealChannelInfo->windowShape = 0; + pConcealChannelInfo->iRandomPhase = 0; pConcealChannelInfo->prevFrameOk[0] = 1; pConcealChannelInfo->prevFrameOk[1] = 1; - pConcealChannelInfo->cntFadeFrames = 0; + pConcealChannelInfo->cntFadeFrames = 0; pConcealChannelInfo->cntValidFrames = 0; - - pConcealChannelInfo->concealState = ConcealState_Ok; - + 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 - \concealParams - \method - \fadeOutSlope - \fadeInSlope - \muteRelease - \comfNoiseLevel - - \return none + \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, - int comfNoiseLevel ) -{ +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; + 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; + 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 ((fadeOutSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeOutSlope >= 0)) { if (concealParams == NULL) { return AAC_DEC_INVALID_HANDLE; } else { @@ -409,9 +407,7 @@ AAC_DECODER_ERROR /* set number of frames for fade-in slope */ if (fadeInSlope != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ( (fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) - && (fadeInSlope >= 1) ) - { + if ((fadeInSlope < CONCEAL_MAX_NUM_FADE_FACTORS) && (fadeInSlope >= 0)) { if (concealParams == NULL) { return AAC_DEC_INVALID_HANDLE; } else { @@ -425,9 +421,8 @@ AAC_DECODER_ERROR /* 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 ((muteRelease < (CONCEAL_MAX_NUM_FADE_FACTORS << 1)) && + (muteRelease >= 0)) { if (concealParams == NULL) { return AAC_DEC_INVALID_HANDLE; } else { @@ -440,50 +435,46 @@ AAC_DECODER_ERROR } /* set confort noise level which will be inserted while in state 'muting' */ - if (comfNoiseLevel != AACDEC_CONCEAL_PARAM_NOT_SPECIFIED) { - if ( (comfNoiseLevel < -1) - || (comfNoiseLevel > 127) ) { + 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 = comfNoiseLevel; + concealParams->comfortNoiseLevel = (FIXP_DBL)comfNoiseLevel; } } return (AAC_DEC_OK); } - /*! \brief Set fade-out/in attenuation factor vectors - \concealParams - \fadeOutAttenuationVector - \fadeInAttenuationVector + \param concealParams + \param fadeOutAttenuationVector + \param fadeInAttenuationVector \return 0 if OK all other values indicate errors */ AAC_DECODER_ERROR - CConcealment_SetAttenuation ( - CConcealParams *concealParams, - SHORT *fadeOutAttenuationVector, - SHORT *fadeInAttenuationVector ) -{ - if ( (fadeOutAttenuationVector == NULL) - && (fadeInAttenuationVector == NULL) ) { +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) - { + 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)) { + if ((fadeOutAttenuationVector[i] < 0) || + (fadeOutAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { return AAC_DEC_SET_PARAM_FAIL; } } @@ -492,26 +483,24 @@ AAC_DECODER_ERROR } /* now dequantize factors */ - for (i = 0; i < CONCEAL_MAX_NUM_FADE_FACTORS; i++) - { + 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 - ) - ); + 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) - { + 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)) { + if ((fadeInAttenuationVector[i] < 0) || + (fadeInAttenuationVector[i] > CONCEAL_MAX_QUANT_FACTOR)) { return AAC_DEC_SET_PARAM_FAIL; } } @@ -520,34 +509,26 @@ AAC_DECODER_ERROR } /* 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 - ) - ); + 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. - \pConcealChannelInfo + \param pConcealChannelInfo \return Concealment state. */ -CConcealmentState - CConcealment_GetState ( - CConcealmentInfo *pConcealChannelInfo - ) -{ +CConcealmentState CConcealment_GetState(CConcealmentInfo *pConcealChannelInfo) { CConcealmentState state = ConcealState_Ok; if (pConcealChannelInfo != NULL) { @@ -557,254 +538,247 @@ CConcealmentState return (state); } - -static void CConcealment_fakePnsData ( - CPnsData *pPnsData, - CIcsInfo *pIcsInfo, - const SamplingRateInfo *pSamplingRateInfo, - SHORT *pSpecScale, - SHORT *pScaleFactor, - const int level ) -{ - CPnsInterChannelData *pInterChannelData = pPnsData->pPnsInterChannelData; - - int pnsBand, band, group, win; - //int delta = 0; - int windowsPerFrame = GetWindowsPerFrame(pIcsInfo); - int refLevel = (windowsPerFrame > 1) ? 82 : 91; - - FDK_ASSERT(level >= 0 && level <= 127); - - for (win = 0; win < windowsPerFrame; win++) { - pSpecScale[win] = 31; - } - - /* fake ICS info if necessary */ - if (!IsValid(pIcsInfo)) { - pIcsInfo->WindowGroups = 1; - if (IsLongBlock(pIcsInfo)) { - pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Long; - pIcsInfo->WindowGroupLength[0] = 1; - } - else { - pIcsInfo->TotalSfBands = pSamplingRateInfo->NumberOfScaleFactorBands_Short; - pIcsInfo->WindowGroupLength[0] = 8; - } - pIcsInfo->MaxSfBands = pIcsInfo->TotalSfBands; - } - - /* global activate PNS */ - pPnsData->PnsActive = 1; - /* set energy level */ - pPnsData->CurrentEnergy = fixMax( 0, refLevel - level ); - - /* - value: | Avg. RMS power | Avg. RMS power | - | specScale = 22 | specScale = 31 | - -------+----------------+----------------+ - 5 | | -99.0 dB - 15 | | -90.0 dB - 25 | | -89.7 dB - 35 | | -85.3 dB - ... | ... | ... - 45 | -69.9 dB | -70.0 dB - 50 | -62.2 dB | - 55 | -55.6 dB | -54.6 dB - 60 | -47.0 dB | - 65 | -39.5 dB | -39.5 dB - 70 | -31.9 dB | - 75 | -24.4 dB | -24.4 dB - 80 | -16.9 dB | - 85 | -9.4 dB (c) | -9.4 dB - 90 | -3.9 dB (c) | - 95 | | -2.1 dB - 100 | | -1.6 dB - 105 | | -1.4 dB - */ - - for (group=0; group < GetWindowGroups(pIcsInfo); group++) - { - for (band=0; band < GetScaleFactorBandsTransmitted(pIcsInfo); band++) - { - pnsBand = group * 16 + band; - - if (pnsBand >= NO_OFBANDS) { - return; - } - //pPnsData->CurrentEnergy += delta ; - pScaleFactor[pnsBand] = pPnsData->CurrentEnergy; - pInterChannelData->correlated[pnsBand] = 0; - pPnsData->pnsUsed[pnsBand] = 1; - } - } -} - - /*! \brief Store data for concealment techniques applied later Interface function to store data for different concealment strategies - - \return none */ -void - CConcealment_Store ( +void CConcealment_Store( CConcealmentInfo *hConcealmentInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo ) -{ - if ( !(pAacDecoderChannelInfo->renderMode == AACDEC_RENDER_LPD - ) ) + 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; + FIXP_DBL *pSpectralCoefficient = + SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); + SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; + CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT tSpecScale[8]; - UCHAR tWindowShape, tWindowSequence; + SHORT tSpecScale[8]; + UCHAR tWindowShape; + BLOCK_TYPE tWindowSequence; /* store old window infos for swapping */ tWindowSequence = hConcealmentInfo->windowSequence; - tWindowShape = hConcealmentInfo->windowShape; + tWindowShape = hConcealmentInfo->windowShape; /* store old scale factors for swapping */ - FDKmemcpy(tSpecScale, hConcealmentInfo->specScale, 8*sizeof(SHORT)); + 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); + hConcealmentInfo->windowShape = GetWindowShape(pIcsInfo); + hConcealmentInfo->lastWinGrpLen = + *(GetWindowGroupLengthTable(pIcsInfo) + GetWindowGroups(pIcsInfo) - 1); /* store new scale factors */ - FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8*sizeof(SHORT)); + FDKmemcpy(hConcealmentInfo->specScale, pSpecScale, 8 * sizeof(SHORT)); - if (CConcealment_GetDelay(hConcealmentInfo->pConcealParams) == 0) - { - /* store new spectral bins */ + if (hConcealmentInfo->pConcealParams->method < ConcealMethodInter) { + /* store new spectral bins */ #if (CNCL_FRACT_BITS == DFRACT_BITS) - FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, 1024 * sizeof(FIXP_CNCL)); + FDKmemcpy(hConcealmentInfo->spectralCoefficient, pSpectralCoefficient, + 1024 * sizeof(FIXP_CNCL)); #else - FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1]; - FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024-1]; + 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 - { - FIXP_CNCL *RESTRICT pCncl = &hConcealmentInfo->spectralCoefficient[1024-1]; - FIXP_DBL *RESTRICT pSpec = &pSpectralCoefficient[1024-1]; - int i; + } 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; - /* swap spectral data */ - for (i = 1024; i != 0; i--) { - FIXP_DBL tSpec = *pSpec; + for (int i = 1024; i != 0; i--) { + tSpec = *pSpec; *pSpec-- = FX_CNCL2FX_DBL(*pCncl); - *pCncl-- = FX_DBL2FX_CNCL( tSpec); + *pCncl-- = FX_DBL2FX_CNCL(tSpec); } +#endif /* complete swapping of window infos */ pIcsInfo->WindowSequence = tWindowSequence; - pIcsInfo->WindowShape = tWindowShape; + pIcsInfo->WindowShape = tWindowShape; /* complete swapping of scale factors */ - FDKmemcpy(pSpecScale, tSpecScale, 8*sizeof(SHORT)); + 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 - - \return none */ -int - CConcealment_Apply ( +int CConcealment_Apply( CConcealmentInfo *hConcealmentInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const int samplesPerFrame, - const UCHAR lastLpdMode, - const int frameOk, - const UINT flags) -{ + const SamplingRateInfo *pSamplingRateInfo, const int samplesPerFrame, + const UCHAR lastLpdMode, const int frameOk, const UINT flags) { int appliedProcessing = 0; - - if ( (frameOk == 0) - && (pAacDecoderChannelInfo->renderMode != (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode) ) { - /* restore the last render mode to stay in the same domain which allows to do a proper concealment */ - pAacDecoderChannelInfo->renderMode = (AACDEC_RENDER_MODE)hConcealmentInfo->lastRenderMode; - } else { - /* otherwise store the current mode */ - hConcealmentInfo->lastRenderMode = (SCHAR)pAacDecoderChannelInfo->renderMode; + 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 ) - { + 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 + 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; + 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 ); + CConcealment_UpdateState(hConcealmentInfo, frameOk, + pAacDecoderStaticChannelInfo, samplesPerFrame, + pAacDecoderChannelInfo); { - /* Create data for signal rendering according to the selected concealment method and decoder operating mode. */ + 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 - ) - ) - { - 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; + 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 - case ConcealMethodNoise: - /* Noise substitution error concealment technique */ - appliedProcessing = - CConcealment_ApplyNoise (hConcealmentInfo, - pAacDecoderChannelInfo, - pAacDecoderStaticChannelInfo, - pSamplingRateInfo, - samplesPerFrame, - flags); - break; + /* restore window infos (gri) do we need that? */ + pIcsInfo->WindowSequence = hConcealmentInfo->windowSequence; + pIcsInfo->WindowShape = hConcealmentInfo->windowShape; - case ConcealMethodInter: - /* Energy interpolation concealment based on 3GPP */ - appliedProcessing = - CConcealment_ApplyInter (hConcealmentInfo, - pAacDecoderChannelInfo, - pSamplingRateInfo, - samplesPerFrame, - 0, /* don't use tonal improvement */ - frameOk); - break; + 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)); } } } @@ -812,7 +786,7 @@ int hConcealmentInfo->prevFrameOk[0] = hConcealmentInfo->prevFrameOk[1]; hConcealmentInfo->prevFrameOk[1] = frameOk; - return appliedProcessing; + return mute_release_active ? -1 : appliedProcessing; } /*! @@ -820,308 +794,191 @@ int In case of frame lost this function produces a noisy frame with respect to the energies values of past frame. - -\return none */ -static int - CConcealment_ApplyNoise (CConcealmentInfo *pConcealmentInfo, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const int samplesPerFrame, - const UINT flags) -{ - CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; - - FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; +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((samplesPerFrame>=480) && (samplesPerFrame<=1024)); - FDK_ASSERT((samplesPerFrame&0x1F) == 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: - { - /* restore frequency coefficients from buffer with a specific muting */ - FIXP_SGL fac; - int win, numWindows = 1; - int windowLen = samplesPerFrame; - int tFadeFrames, lastWindow = 0; - int win_idx_stride = 1; - - FDK_ASSERT(pConcealmentInfo != NULL); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames <= pConcealCommonData->numFadeOutFrames); - - /* get attenuation factor */ - tFadeFrames = pConcealmentInfo->cntFadeFrames; - fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; - - /* set old window parameters */ - { - pIcsInfo->WindowShape = pConcealmentInfo->windowShape; - pIcsInfo->WindowSequence = pConcealmentInfo->windowSequence; - - if (pConcealmentInfo->windowSequence == 2) { - /* short block handling */ - numWindows = 8; - windowLen = samplesPerFrame >> 3; - lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; - } - } - - for (win = 0; win < numWindows; win++) { - FIXP_CNCL *pCncl = pConcealmentInfo->spectralCoefficient + (lastWindow * windowLen); - FIXP_DBL *pOut = pSpectralCoefficient + (win * windowLen); - int i; - - FDK_ASSERT((lastWindow * windowLen + windowLen) <= samplesPerFrame); - - /* restore frequency coefficients from buffer with a specific attenuation */ - for (i = 0; i < windowLen; i++) { - pOut[i] = fMult(pCncl[i], fac); - } - - /* 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[win*win_idx_stride] = pConcealmentInfo->specScale[win_idx_stride*lastWindow++]; - - if ( (lastWindow >= numWindows) - && (numWindows > 1) ) - { - /* end of sequence -> rewind */ - lastWindow = numWindows - pConcealmentInfo->lastWinGrpLen; - /* update the attenuation factor to get a faster fade-out */ - tFadeFrames += 1; - if (tFadeFrames < pConcealCommonData->numFadeOutFrames) { - fac = pConcealCommonData->fadeOutFactor[tFadeFrames]; - } else { - fac = (FIXP_SGL)0; - } - } - } + switch (pConcealmentInfo->concealState) { + case ConcealState_Ok: + /* Nothing to do here! */ + break; - /* store temp vars */ - pConcealmentInfo->cntFadeFrames = tFadeFrames; - appliedProcessing = 1; - } - break; + case ConcealState_Single: + case ConcealState_FadeOut: + appliedProcessing = CConcealment_ApplyFadeOut( + /*mode =*/1, pConcealmentInfo, pAacDecoderStaticChannelInfo, + samplesPerFrame, pAacDecoderChannelInfo); + break; - case ConcealState_Mute: - { + 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) */ + 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)); - if ( !(flags & (AC_USAC|AC_RSVD50)) - && pConcealCommonData->comfortNoiseLevel >= 0 - && pConcealCommonData->comfortNoiseLevel <= 61 /* -90dB */) - { - /* insert comfort noise using PNS */ - CConcealment_fakePnsData ( - &pAacDecoderChannelInfo->data.aac.PnsData, - pIcsInfo, - pSamplingRateInfo, - pAacDecoderChannelInfo->pDynData->aSfbScale, - pAacDecoderChannelInfo->pDynData->aScaleFactor, - pConcealCommonData->comfortNoiseLevel - ); - - CPns_Apply ( - &pAacDecoderChannelInfo->data.aac.PnsData, - pIcsInfo, - pAacDecoderChannelInfo->pSpectralCoefficient, - pAacDecoderChannelInfo->specScale, - pAacDecoderChannelInfo->pDynData->aScaleFactor, - pSamplingRateInfo, - pAacDecoderChannelInfo->granuleLength, - 0 /* always apply to first channel */ - ); - } appliedProcessing = 1; - } - break; + } break; - case ConcealState_FadeIn: - { - FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); + case ConcealState_FadeIn: { + /* TimeDomainFading: */ + /* Attenuation of signal is done in CConcealment_TDFading() */ - /* attenuate signal to get a smooth fade-in */ - FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; - FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; - int i; - - for (i = samplesPerFrame; i != 0; i--) { - *pOut = fMult(*pOut, fac); - pOut--; - } appliedProcessing = 1; - } - break; + } break; - default: - /* we shouldn't come here anyway */ - FDK_ASSERT(0); - 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. - - \return none */ -static int - CConcealment_ApplyInter ( - CConcealmentInfo *pConcealmentInfo, +static int CConcealment_ApplyInter( + CConcealmentInfo *pConcealmentInfo, CAacDecoderChannelInfo *pAacDecoderChannelInfo, - const SamplingRateInfo *pSamplingRateInfo, - const int samplesPerFrame, - const int improveTonal, - const int frameOk ) -{ - CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; - - FIXP_DBL *pSpectralCoefficient = SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient); - CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo; - SHORT *pSpecScale = pAacDecoderChannelInfo->specScale; + 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 sfbEnergyAct[64]; int i, appliedProcessing = 0; /* clear/init */ FDKmemclear(sfbEnergyPrev, 64 * sizeof(int)); - FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); - + FDKmemclear(sfbEnergyAct, 64 * sizeof(int)); - if (!frameOk) - { + if (!frameOk || mute_release_active) { /* Restore last frame from concealment buffer */ - pIcsInfo->WindowShape = pConcealmentInfo->windowShape; + 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]); + pSpectralCoefficient[i] = + FX_CNCL2FX_DBL(pConcealmentInfo->spectralCoefficient[i]); } /* Restore scale factors */ - FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8*sizeof(SHORT)); + FDKmemcpy(pSpecScale, pConcealmentInfo->specScale, 8 * sizeof(SHORT)); } /* if previous frame was not ok */ - if (!pConcealmentInfo->prevFrameOk[1]) { - + 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]) - { + 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 == EightShortSequence) { - /* f_(n-2) == EightShortSequence */ + /* 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 == EightShortSequence) { /* f_n == EightShortSequence */ + 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 = 1; - pIcsInfo->WindowSequence = EightShortSequence; + 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++) - { + for (wnd = 0; wnd < 8; wnd++) { CConcealment_CalcBandEnergy( - &pSpectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_(n-2) */ - pSamplingRateInfo, - EightShortSequence, - CConcealment_NoExpand, - sfbEnergyPrev); + &pSpectralCoefficient[wnd * + (samplesPerFrame / 8)], /* spec_(n-2) */ + pSamplingRateInfo, BLOCK_SHORT, CConcealment_NoExpand, + sfbEnergyPrev); CConcealment_CalcBandEnergy( - &pConcealmentInfo->spectralCoefficient[wnd * (samplesPerFrame / 8)], /* spec_n */ - pSamplingRateInfo, - EightShortSequence, - CConcealment_NoExpand, - sfbEnergyAct); + &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); - + &pSpectralCoefficient[wnd * + (samplesPerFrame / 8)], /* spec_(n-1) */ + &pSpecScale[wnd], &pConcealmentInfo->specScale[wnd], + &pSpecScale[wnd], sfbEnergyPrev, sfbEnergyAct, + scaleFactorBandsTotal, pSfbOffset); } - } else { /* f_n != EightShortSequence */ + } else { /* f_n != BLOCK_SHORT */ /* short---long---long interpolation */ - int scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; - const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; + int scaleFactorBandsTotal = + pSamplingRateInfo->NumberOfScaleFactorBands_Long; + const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; SHORT specScaleOut; - CConcealment_CalcBandEnergy(&pSpectralCoefficient[samplesPerFrame - (samplesPerFrame / 8)], /* [wnd] spec_(n-2) */ - pSamplingRateInfo, - EightShortSequence, - CConcealment_Expand, - sfbEnergyAct); + CConcealment_CalcBandEnergy( + &pSpectralCoefficient[samplesPerFrame - + (samplesPerFrame / + 8)], /* [wnd] spec_(n-2) */ + pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, + sfbEnergyAct); - CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, - OnlyLongSequence, - CConcealment_NoExpand, - sfbEnergyPrev); + CConcealment_CalcBandEnergy( + pConcealmentInfo->spectralCoefficient, /* spec_n */ + pSamplingRateInfo, BLOCK_LONG, CConcealment_NoExpand, + sfbEnergyPrev); pIcsInfo->WindowShape = 0; - pIcsInfo->WindowSequence = LongStopSequence; + pIcsInfo->WindowSequence = BLOCK_STOP; - for (i = 0; i < samplesPerFrame ; i++) { - pSpectralCoefficient[i] = pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ + for (i = 0; i < samplesPerFrame; i++) { + pSpectralCoefficient[i] = + pConcealmentInfo->spectralCoefficient[i]; /* spec_n */ } for (i = 0; i < 8; i++) { /* search for max(specScale) */ @@ -1131,14 +988,9 @@ static int } CConcealment_InterpolateBuffer( - pSpectralCoefficient, /* spec_(n-1) */ - &pConcealmentInfo->specScale[0], - &pSpecScale[0], - &specScaleOut, - sfbEnergyPrev, - sfbEnergyAct, - scaleFactorBandsTotal, - pSfbOffset); + pSpectralCoefficient, /* spec_(n-1) */ + &pConcealmentInfo->specScale[0], &pSpecScale[0], &specScaleOut, + sfbEnergyPrev, sfbEnergyAct, scaleFactorBandsTotal, pSfbOffset); pSpecScale[0] = specScaleOut; } @@ -1146,21 +998,21 @@ static int /* 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]; + int scaleFactorBandsTotal = + pSamplingRateInfo->NumberOfScaleFactorBands_Long; + const SHORT *pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; + SHORT specScaleAct = pConcealmentInfo->specScale[0]; - CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ - pSamplingRateInfo, - OnlyLongSequence, - CConcealment_NoExpand, - sfbEnergyPrev); + CConcealment_CalcBandEnergy(pSpectralCoefficient, /* spec_(n-2) */ + pSamplingRateInfo, BLOCK_LONG, + CConcealment_NoExpand, sfbEnergyPrev); - if (pConcealmentInfo->windowSequence == EightShortSequence) { /* f_n == EightShortSequence */ + if (pConcealmentInfo->windowSequence == + BLOCK_SHORT) { /* f_n == BLOCK_SHORT */ /* long---long---short interpolation */ - pIcsInfo->WindowShape = 1; - pIcsInfo->WindowSequence = LongStartSequence; + 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) { @@ -1169,310 +1021,277 @@ static int } /* Expand first short spectrum */ - CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, - EightShortSequence, - CConcealment_Expand, /* !!! */ - sfbEnergyAct); + CConcealment_CalcBandEnergy( + pConcealmentInfo->spectralCoefficient, /* spec_n */ + pSamplingRateInfo, BLOCK_SHORT, CConcealment_Expand, /* !!! */ + sfbEnergyAct); } else { /* long---long---long interpolation */ pIcsInfo->WindowShape = 0; - pIcsInfo->WindowSequence = OnlyLongSequence; + pIcsInfo->WindowSequence = BLOCK_LONG; - CConcealment_CalcBandEnergy(pConcealmentInfo->spectralCoefficient, /* spec_n */ - pSamplingRateInfo, - OnlyLongSequence, - CConcealment_NoExpand, - sfbEnergyAct); + 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); - + 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); + /* 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; + switch (pConcealmentInfo->concealState) { + case ConcealState_Single: + appliedProcessing = 1; + break; - case ConcealState_FadeOut: - { + case ConcealState_FadeOut: { FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeOutFrames); + FDK_ASSERT(pConcealmentInfo->cntFadeFrames < + CONCEAL_MAX_NUM_FADE_FACTORS); + FDK_ASSERT(pConcealmentInfo->cntFadeFrames < + pConcealCommonData->numFadeOutFrames); - /* restore frequency coefficients from buffer with a specific muting */ - FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; - FIXP_SGL fac = pConcealCommonData->fadeOutFactor[pConcealmentInfo->cntFadeFrames]; + /* TimeDomainFading: */ + /* Attenuation of signal is done in CConcealment_TDFading() */ - for (i = samplesPerFrame; i != 0; i--) { - *pOut = fMult(*pOut, fac); - pOut--; - } appliedProcessing = 1; - } - break; + } break; - case ConcealState_FadeIn: - { + case ConcealState_FadeIn: { FDK_ASSERT(pConcealmentInfo->cntFadeFrames >= 0); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < CONCEAL_MAX_NUM_FADE_FACTORS); - FDK_ASSERT(pConcealmentInfo->cntFadeFrames < pConcealCommonData->numFadeInFrames); + FDK_ASSERT(pConcealmentInfo->cntFadeFrames < + CONCEAL_MAX_NUM_FADE_FACTORS); + FDK_ASSERT(pConcealmentInfo->cntFadeFrames < + pConcealCommonData->numFadeInFrames); - /* attenuate signal to get a smooth fade-in */ - FIXP_DBL *RESTRICT pOut = &pSpectralCoefficient[samplesPerFrame-1]; - FIXP_SGL fac = pConcealCommonData->fadeInFactor[pConcealmentInfo->cntFadeFrames]; + /* TimeDomainFading: */ + /* Attenuation of signal is done in CConcealment_TDFading() */ - for (i = samplesPerFrame; i != 0; i--) { - *pOut = fMult(*pOut, fac); - pOut--; - } appliedProcessing = 1; - } - break; - - case ConcealState_Mute: - { - int fac = pConcealCommonData->comfortNoiseLevel; + } 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) */ + 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)); - if (fac >= 0 && fac <= 61) { - /* insert comfort noise using PNS */ - CConcealment_fakePnsData ( - &pAacDecoderChannelInfo->data.aac.PnsData, - pIcsInfo, - pSamplingRateInfo, - pAacDecoderChannelInfo->specScale, - pAacDecoderChannelInfo->pDynData->aScaleFactor, - fac - ); - - CPns_Apply ( - &pAacDecoderChannelInfo->data.aac.PnsData, - pIcsInfo, - pAacDecoderChannelInfo->pSpectralCoefficient, - pAacDecoderChannelInfo->specScale, - pAacDecoderChannelInfo->pDynData->aScaleFactor, - pSamplingRateInfo, - pAacDecoderChannelInfo->granuleLength, - 0 /* always apply to first channel */ - ); - } appliedProcessing = 1; - } - break; + } break; - default: - /* nothing to do here */ - 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. - - \return none */ -static void - CConcealment_CalcBandEnergy ( - FIXP_DBL *spectrum, - const SamplingRateInfo *pSamplingRateInfo, - const int blockType, - CConcealmentExpandType expandType, - int *sfbEnergy ) -{ +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) { + /* In the following calculations, enAccu is initialized with LSB-value in + * order to avoid zero energy-level */ - case OnlyLongSequence: - case LongStartSequence: - case LongStopSequence: - - if (expandType == CConcealment_NoExpand) { - /* standard long calculation */ - scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Long; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Long; + line = 0; - 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; + 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; } - *(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; + } 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; } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; } - } - break; - - case EightShortSequence: - - if (expandType == CConcealment_NoExpand) { - /* standard short calculation */ - scaleFactorBandsTotal = pSamplingRateInfo->NumberOfScaleFactorBands_Short; - pSfbOffset = pSamplingRateInfo->ScaleFactorBands_Short; + break; - 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; + 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; } - *(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; + } 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; } - *(sfbEnergy + sfb) = CntLeadingZeros(enAccu) - 1; } - } - break; + 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. - - \return none */ -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; +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 = + 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]); + 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; + *(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 ) -{ +static INT findEquiFadeFrame(CConcealParams *pConcealCommonData, + INT actFadeIndex, int direction) { FIXP_SGL *pFactor; - FIXP_SGL referenceVal; - FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; + FIXP_SGL referenceVal; + FIXP_SGL minDiff = (FIXP_SGL)MAXVAL_SGL; - INT numFrames = 0; - INT nextFadeIndex = 0; + INT nextFadeIndex = 0; - int i; + int i; /* init depending on direction */ - if (direction == 0) { /* FADE-OUT => FADE-IN */ - numFrames = pConcealCommonData->numFadeInFrames; - referenceVal = pConcealCommonData->fadeOutFactor[actFadeIndex] >> 1; + 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 */ - numFrames = pConcealCommonData->numFadeOutFrames; - referenceVal = pConcealCommonData->fadeInFactor[actFadeIndex] >> 1; + } 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 < numFrames; i++) { - FIXP_SGL diff = fixp_abs((pFactor[i]>>1) - referenceVal); + 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; @@ -1480,13 +1299,17 @@ static INT findEquiFadeFrame ( } /* check and adjust depending on direction */ - if (direction == 0) { /* FADE-OUT => FADE-IN */ - if (((pFactor[nextFadeIndex]>>1) <= referenceVal) && (nextFadeIndex > 0)) { + 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 < numFrames-1)) { + } else { /* FADE-IN => FADE-OUT */ + if (((pFactor[nextFadeIndex] >> 1) >= referenceVal) && + (nextFadeIndex < CONCEAL_MAX_NUM_FADE_FACTORS - 1)) { nextFadeIndex += 1; } } @@ -1494,268 +1317,304 @@ static INT findEquiFadeFrame ( 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. - - \return none */ -static void - CConcealment_UpdateState ( - CConcealmentInfo *pConcealmentInfo, - int frameOk ) -{ +static void CConcealment_UpdateState( + CConcealmentInfo *pConcealmentInfo, int frameOk, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo, + const int samplesPerFrame, CAacDecoderChannelInfo *pAacDecoderChannelInfo) { CConcealParams *pConcealCommonData = pConcealmentInfo->pConcealParams; - switch (pConcealCommonData->method) - { - case ConcealMethodNoise: - { + 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; + pConcealmentInfo->cntValidFrames = 0; } } /* -- STATE MACHINE for Noise Substitution -- */ - switch (pConcealmentInfo->concealState) - { - case ConcealState_Ok: - if (!frameOk) { - if (pConcealCommonData->numFadeOutFrames > 0) { - /* change to state SINGLE-FRAME-LOSS */ - pConcealmentInfo->concealState = ConcealState_Single; - } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; + 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; + } } - pConcealmentInfo->cntFadeFrames = 0; - pConcealmentInfo->cntValidFrames = 0; - } - break; + break; - case ConcealState_Single: /* Just a pre-stage before fade-out begins. Stay here only one frame! */ - pConcealmentInfo->cntFadeFrames += 1; - if (frameOk) { - if (pConcealmentInfo->cntValidFrames > pConcealCommonData->numMuteReleaseFrames) { - /* change to state FADE-IN */ - pConcealmentInfo->concealState = ConcealState_FadeIn; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, - pConcealmentInfo->cntFadeFrames-1, - 0 /* FadeOut -> FadeIn */); - } else { + 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; + 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: - pConcealmentInfo->cntFadeFrames += 1; /* used to address the fade-out factors */ - 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 */); + 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 { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; + 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; + 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 { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } - break; - - case ConcealState_FadeIn: - pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ - if (frameOk) { - if (pConcealmentInfo->cntFadeFrames < 0) { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; + 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; + } } - } else { - if (pConcealCommonData->numFadeOutFrames > 0) { - /* change to state FADE-OUT */ - pConcealmentInfo->concealState = ConcealState_FadeOut; - pConcealmentInfo->cntFadeFrames = findEquiFadeFrame( pConcealCommonData, - pConcealmentInfo->cntFadeFrames+1, - 1 /* FadeIn -> FadeOut */); + break; + + case ConcealState_FadeIn: + pConcealmentInfo->cntFadeFrames -= 1; + if (frameOk) { + if (pConcealmentInfo->cntFadeFrames < 0) { + /* change to state OK */ + pConcealmentInfo->concealState = ConcealState_Ok; + } } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; + 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; + break; - default: - FDK_ASSERT(0); - break; + default: + FDK_ASSERT(0); + break; } - } - break; + } break; - case ConcealMethodInter: - case ConcealMethodTonal: - { + 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 */ + 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; + 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; + 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; } - 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 */); + 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 { - /* change to state OK */ - pConcealmentInfo->concealState = ConcealState_Ok; - } - } else { - if (pConcealmentInfo->cntFadeFrames >= pConcealCommonData->numFadeOutFrames) { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; + 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_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; + break; - case ConcealState_FadeIn: - pConcealmentInfo->cntFadeFrames -= 1; /* used to address the fade-in factors */ + 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 */); + if (frameOk || pConcealmentInfo->prevFrameOk[1]) { + if (pConcealmentInfo->cntFadeFrames < 0) { + /* change to state OK */ + pConcealmentInfo->concealState = ConcealState_Ok; + } } else { - /* change to state MUTE */ - pConcealmentInfo->concealState = ConcealState_Mute; + 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; + break; } /* End switch(pConcealmentInfo->concealState) */ - } - break; + } break; - default: - /* Don't need a state machine for other concealment methods. */ - 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. - -\return none */ -static -void CConcealment_ApplyRandomSign (int randomPhase, - FIXP_DBL *spec, - int samplesPerFrame - ) -{ +static void CConcealment_ApplyRandomSign(int randomPhase, FIXP_DBL *spec, + int samplesPerFrame) { int i; - USHORT packedSign=0; + USHORT packedSign = 0; - /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit */ + /* random table 512x16bit has been reduced to 512 packed sign bits = 32x16 bit + */ /* read current packed sign word */ - packedSign = randomSign[randomPhase>>4]; - packedSign >>= (randomPhase&0xf); + packedSign = AacDec_randomSign[randomPhase >> 4]; + packedSign >>= (randomPhase & 0xf); - for (i = 0; i < samplesPerFrame ; i++) { + for (i = 0; i < samplesPerFrame; i++) { if ((randomPhase & 0xf) == 0) { - packedSign = randomSign[randomPhase>>4]; + packedSign = AacDec_randomSign[randomPhase >> 4]; } if (packedSign & 0x1) { @@ -1767,53 +1626,6 @@ void CConcealment_ApplyRandomSign (int randomPhase, } } - -/*! - \brief Get fadeing factor for current concealment state. - - The function returns the factor used for fading that belongs to the current internal state. - - \return Fade factor - */ -FIXP_DBL - CConcealment_GetFadeFactor ( - CConcealmentInfo *hConcealmentInfo, - const int fPreviousFactor - ) -{ - FIXP_DBL fac = (FIXP_DBL)0; - - CConcealParams *pConcealCommonData = hConcealmentInfo->pConcealParams; - - if (hConcealmentInfo->pConcealParams->method > ConcealMethodMute) { - switch (hConcealmentInfo->concealState) { - default: - case ConcealState_Mute: - /* Nothing to do here */ - break; - case ConcealState_Ok: - fac = (FIXP_DBL)MAXVAL_DBL; - break; - case ConcealState_Single: - case ConcealState_FadeOut: - { - int idx = hConcealmentInfo->cntFadeFrames - ((fPreviousFactor != 0) ? 1 : 0); - fac = (idx < 0) ? (FIXP_DBL)MAXVAL_DBL : FX_SGL2FX_DBL(pConcealCommonData->fadeOutFactor[idx]); - } - break; - case ConcealState_FadeIn: - { - int idx = hConcealmentInfo->cntFadeFrames + ((fPreviousFactor != 0) ? 1 : 0); - fac = (idx >= hConcealmentInfo->pConcealParams->numFadeInFrames) ? (FIXP_DBL)0 : FX_SGL2FX_DBL(pConcealCommonData->fadeInFactor[idx]); - } - break; - } - } - - return (fac); -} - - /*! \brief Get fadeing factor for current concealment state. @@ -1823,12 +1635,8 @@ FIXP_DBL \return Frame OK flag of previous frame. */ -int - CConcealment_GetLastFrameOk ( - CConcealmentInfo *hConcealmentInfo, - const int fBeforeApply - ) -{ +int CConcealment_GetLastFrameOk(CConcealmentInfo *hConcealmentInfo, + const int fBeforeApply) { int prevFrameOk = 1; if (hConcealmentInfo != NULL) { @@ -1839,28 +1647,448 @@ int } /*! - \brief Get the number of delay frames introduced by concealment technique. + \brief Get the number of delay frames introduced by concealment technique. \return Number of delay frames. */ -UINT - CConcealment_GetDelay ( - CConcealParams *pConcealCommonData - ) -{ +UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData) { UINT frameDelay = 0; if (pConcealCommonData != NULL) { switch (pConcealCommonData->method) { - case ConcealMethodTonal: - case ConcealMethodInter: - frameDelay = 1; + 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; + 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); - return frameDelay; + /* 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 (pcmdata[ii] > (FIXP_PCM)MAXVAL_FIXP_PCM - noiseVal && + noiseVal > (FIXP_PCM)0) { + noiseVal = noiseVal * (FIXP_PCM)-1; + } else if (pcmdata[ii] < (FIXP_PCM)MINVAL_FIXP_PCM - noiseVal && + noiseVal < (FIXP_PCM)0) { + noiseVal = noiseVal * (FIXP_PCM)-1; + } + + pcmdata[ii] += noiseVal; + } + } +} diff --git a/libAACdec/src/conceal.h b/libAACdec/src/conceal.h index 20e674f..e01a796 100644 --- a/libAACdec/src/conceal.h +++ b/libAACdec/src/conceal.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,70 +90,63 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl - Description: independent channel concealment -******************************************************************************/ + Description: independent channel concealment -#ifndef _CONCEAL_H_ -#define _CONCEAL_H_ +*******************************************************************************/ -#include "aacdecoder_lib.h" +#ifndef CONCEAL_H +#define CONCEAL_H #include "channelinfo.h" -#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED ( 0xFFFE ) +#define AACDEC_CONCEAL_PARAM_NOT_SPECIFIED (0xFFFE) -void CConcealment_InitCommonData (CConcealParams *pConcealCommonData); +void CConcealment_InitCommonData(CConcealParams *pConcealCommonData); -void CConcealment_InitChannelData (CConcealmentInfo *hConcealmentInfo, - CConcealParams *pConcealCommonData, - int samplesPerFrame); +void CConcealment_InitChannelData(CConcealmentInfo *hConcealmentInfo, + CConcealParams *pConcealCommonData, + AACDEC_RENDER_MODE initRenderMode, + int samplesPerFrame); -CConcealmentMethod - CConcealment_GetMethod (CConcealParams *pConcealCommonData); +CConcealmentMethod CConcealment_GetMethod(CConcealParams *pConcealCommonData); -UINT - CConcealment_GetDelay (CConcealParams *pConcealCommonData); +UINT CConcealment_GetDelay(CConcealParams *pConcealCommonData); AAC_DECODER_ERROR - CConcealment_SetParams (CConcealParams *concealParams, - int method, - int fadeOutSlope, - int fadeInSlope, - int muteRelease, - int comfNoiseLevel); +CConcealment_SetParams(CConcealParams *concealParams, int method, + int fadeOutSlope, int fadeInSlope, int muteRelease, + FIXP_DBL comfNoiseLevel); -CConcealmentState - CConcealment_GetState (CConcealmentInfo *hConcealmentInfo); +CConcealmentState CConcealment_GetState(CConcealmentInfo *hConcealmentInfo); AAC_DECODER_ERROR - CConcealment_SetAttenuation (CConcealParams *concealParams, - SHORT *fadeOutAttenuationVector, - 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); - -FIXP_DBL - CConcealment_GetFadeFactor (CConcealmentInfo *hConcealmentInfo, - const int fPreviousFactor); - -int CConcealment_GetLastFrameOk (CConcealmentInfo *hConcealmentInfo, - const int fBeforeApply); - -#endif /* #ifndef _CONCEAL_H_ */ +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/libAACdec/src/conceal_types.h b/libAACdec/src/conceal_types.h index 31bc645..d90374e 100644 --- a/libAACdec/src/conceal_types.h +++ b/libAACdec/src/conceal_types.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,48 +90,45 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 ( 16 ) +#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 +#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 +typedef enum { + ConcealMethodNone = -1, + ConcealMethodMute = 0, + ConcealMethodNoise = 1, + ConcealMethodInter = 2, + ConcealMethodTonal = 3 } CConcealmentMethod; - -typedef enum -{ +typedef enum { ConcealState_Ok, ConcealState_Single, ConcealState_FadeIn, @@ -129,50 +137,67 @@ typedef enum } CConcealmentState; +typedef struct { + FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS]; + FIXP_SGL fadeInFactor[CONCEAL_MAX_NUM_FADE_FACTORS]; -typedef struct -{ - FIXP_SGL fadeOutFactor[CONCEAL_MAX_NUM_FADE_FACTORS]; - FIXP_SGL fadeInFactor [CONCEAL_MAX_NUM_FADE_FACTORS]; - - CConcealmentMethod method; + CConcealmentMethod method; - int numFadeOutFrames; - int numFadeInFrames; - int numMuteReleaseFrames; - int comfortNoiseLevel; + int numFadeOutFrames; + int numFadeInFrames; + int numMuteReleaseFrames; + FIXP_DBL comfortNoiseLevel; } CConcealParams; +typedef enum { + FADE_TIMEDOMAIN_TOSPECTRALMUTE = 1, + FADE_TIMEDOMAIN_FROMSPECTRALMUTE, + FADE_TIMEDOMAIN +} TDfadingType; - -typedef struct -{ +typedef struct { CConcealParams *pConcealParams; FIXP_CNCL spectralCoefficient[1024]; - SHORT specScale[8]; + 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; - INT iRandomPhase; - INT prevFrameOk[2]; - INT cntFadeFrames; - INT cntValidFrames; + 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 */ + SHORT aRvlcPreviousScaleFactor[RVLC_MAX_SFB]; /* needed once per channel */ + UCHAR aRvlcPreviousCodebook[RVLC_MAX_SFB]; /* needed once per channel */ SCHAR rvlcPreviousScaleFactorOK; SCHAR rvlcPreviousBlockType; - - SCHAR lastRenderMode; - - UCHAR windowShape; - UCHAR windowSequence; - UCHAR lastWinGrpLen; - - CConcealmentState concealState; + 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/libAACdec/src/debug.h b/libAACdec/src/debug.h deleted file mode 100644 index e903291..0000000 --- a/libAACdec/src/debug.h +++ /dev/null @@ -1,97 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. - - 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. - -2. COPYRIGHT LICENSE - -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: - -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. - -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your -modifications thereto to recipients of copies in binary form. - -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. - -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. - -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." - -3. NO PATENT LICENSE - -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. - -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. - -4. DISCLAIMER - -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/***************************** MPEG-4 AAC Decoder ************************** - - Author(s): Josef Hoepfl - Description: debug output - -******************************************************************************/ - -#ifndef DEBUG_H -#define DEBUG_H - -#include "machine_type.h" - - -#endif diff --git a/libAACdec/src/ldfiltbank.cpp b/libAACdec/src/ldfiltbank.cpp index c08cc41..66a5914 100644 --- a/libAACdec/src/ldfiltbank.cpp +++ b/libAACdec/src/ldfiltbank.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,17 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************************************************************\ -* - * filename: ldfiltbank.c - * project : MPEG-4 Audio Decoder - * contents/description: low delay filterbank - * -\***************************************************************************/ +/**************************** AAC decoder library ****************************** -#include "ldfiltbank.h" + Author(s): + + Description: low delay filterbank +*******************************************************************************/ + +#include "ldfiltbank.h" #include "aac_rom.h" #include "dct.h" @@ -99,110 +109,166 @@ amm-info@iis.fraunhofer.de #define LDFB_HEADROOM 2 -static void multE2_DinvF_fdk(INT_PCM *output, FIXP_DBL* x, const FIXP_WTB* fb, FIXP_DBL* z, const int N, const int stride) -{ - int i, scale; +#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. */ - scale = (DFRACT_BITS - SAMPLE_BITS) - LDFB_HEADROOM; + 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++) - { + 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) ); + 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) ); + 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]) ) ; + tmp = (fMultDiv2(z[N / 2 + i], fb[N + N / 2 - 1 - i]) + + fMultDiv2(z[i], fb[N + N / 2 + i])); -#if (SAMPLE_BITS <= 16) - FDK_ASSERT( (-WTS1-1 + scale) >= 0); - output[(N*3/4-1-i)*stride] = (INT_PCM)SATURATE_RIGHT_SHIFT(tmp, -WTS1-1 + scale, SAMPLE_BITS); +#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)*stride] = (INT_PCM)SATURATE_LEFT_SHIFT(tmp, WTS1+1 - scale, SAMPLE_BITS); + 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++) - { + 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 (SAMPLE_BITS <= 16) - FDK_ASSERT( (-WTS0-1 + scale) >= 0); - output[(i-N/4)*stride] = (INT_PCM)SATURATE_RIGHT_SHIFT(tmp0, -WTS0-1 + scale, SAMPLE_BITS); - output[(N*3/4-1-i)*stride] = (INT_PCM)SATURATE_RIGHT_SHIFT(tmp1, -WTS1-1 + scale, SAMPLE_BITS); + 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)*stride] = (INT_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0+1 - scale, SAMPLE_BITS); - output[(N*3/4-1-i)*stride] = (INT_PCM)SATURATE_LEFT_SHIFT(tmp1, WTS1+1 - scale, SAMPLE_BITS); + 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 (SAMPLE_BITS <= 16) - FDK_ASSERT( (-WTS0-1 + scale) >= 0); - output[(N*3/4 + i)*stride] = (INT_PCM)SATURATE_RIGHT_SHIFT(tmp0, -WTS0-1 + scale, SAMPLE_BITS); + 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)*stride] = (INT_PCM)SATURATE_LEFT_SHIFT(tmp0, WTS0+1 - scale, SAMPLE_BITS); + 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, INT_PCM *output, FIXP_DBL *fs_buffer, const int stride, const int N) { - +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 scale = mdctData_e + MDCT_OUT_HEADROOM - + LDFB_HEADROOM; /* The LDFB_HEADROOM is compensated inside + multE2_DinvF_fdk() below */ /* Select LD window slope */ - if (N == 512) - coef = (FIXP_WTB*)LowDelaySynthesis512; - else - coef = (FIXP_WTB*)LowDelaySynthesis480; + 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". + 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) { scaleValuesWithFactor(mdctData, gain, N, scale); } else { scaleValues(mdctData, N, scale); } - /* Since all exponent and factors have been applied, current exponent is zero. */ - multE2_DinvF_fdk(output, mdctData, coef, fs_buffer, N, stride); + /* 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/libAACdec/src/ldfiltbank.h b/libAACdec/src/ldfiltbank.h index d1f9402..b63da6b 100644 --- a/libAACdec/src/ldfiltbank.h +++ b/libAACdec/src/ldfiltbank.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,31 +90,23 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************************************************************\ - * +/**************************** AAC decoder library ****************************** - * filename: ldfiltbank.h - * project : MPEG-4 Audio Decoder - * contents/description: low delay filterbank interface - * -\***************************************************************************/ + Author(s): -#ifndef _LDFILTBANK_H -#define _LDFILTBANK_H + Description: low delay filterbank interface -#include "common_fix.h" +*******************************************************************************/ +#ifndef LDFILTBANK_H +#define LDFILTBANK_H -int InvMdctTransformLowDelay_fdk ( - FIXP_DBL *mdctdata_m, - const int mdctdata_e, - INT_PCM *mdctOut, - FIXP_DBL *fs_buffer, - const int stride, - const int frameLength - ); +#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/libAACdec/src/overlapadd.h b/libAACdec/src/overlapadd.h index 1469be7..49eecd8 100644 --- a/libAACdec/src/overlapadd.h +++ b/libAACdec/src/overlapadd.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,27 +90,31 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** AAC decoder library ****************************** Author(s): Josef Hoepfl + Description: -******************************************************************************/ +*******************************************************************************/ #ifndef OVERLAPADD_H #define OVERLAPADD_H #include "common_fix.h" -#define OverlapBufferSize (1024*2) +/* ELD uses different overlap which is twice the frame size: */ +#define OverlapBufferSize (768) typedef FIXP_DBL SPECTRUM[1024]; -typedef FIXP_DBL * SPECTRAL_PTR; +typedef FIXP_DBL* SPECTRAL_PTR; -#define SPEC_LONG(ptr) (ptr) -#define SPEC(ptr,w,gl) ((ptr)+((w)*(gl))) +#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/libAACdec/src/pulsedata.cpp b/libAACdec/src/pulsedata.cpp index 0f2f0ec..eb6d5bc 100644 --- a/libAACdec/src/pulsedata.cpp +++ b/libAACdec/src/pulsedata.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,42 +90,37 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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((CIcsInfo*)pIcsInfo); +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((CIcsInfo*)pIcsInfo)) { + 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); + PulseData->NumberPulse = (UCHAR)FDKreadBits(bs, 2); + PulseData->PulseStartBand = (UCHAR)FDKreadBits(bs, 6); if (PulseData->PulseStartBand >= MaxSfBands) { return AAC_DEC_DECODE_FRAME_ERROR; @@ -122,37 +128,37 @@ INT CPulseData_Read( 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); + 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 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 */ +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; + int i, k; - if (PulseData->PulseDataPresent) - { + if (PulseData->PulseDataPresent) { k = pScaleFactorBandOffsets[PulseData->PulseStartBand]; - for (i=0; i<=PulseData->NumberPulse; i++) - { + 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]; + 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/libAACdec/src/pulsedata.h b/libAACdec/src/pulsedata.h index fa97d99..15ae11c 100644 --- a/libAACdec/src/pulsedata.h +++ b/libAACdec/src/pulsedata.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,27 +90,25 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 -{ +typedef struct { UCHAR PulseDataPresent; UCHAR NumberPulse; UCHAR PulseStartBand; @@ -114,17 +123,14 @@ typedef struct * the bitstream. * * \param bs bit stream handle data source. - * \param PulseData pointer to a CPulseData were the decoded data is stored into. + * \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 - ); +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 @@ -134,12 +140,11 @@ INT CPulseData_Read( * * \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. + * \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); - + const short *pScaleFactorBandOffsets, FIXP_DBL *coef); #endif /* #ifndef PULSEDATA_H */ diff --git a/libAACdec/src/rvlc.cpp b/libAACdec/src/rvlc.cpp index 16f0bf5..92f9f02 100644 --- a/libAACdec/src/rvlc.cpp +++ b/libAACdec/src/rvlc.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -89,7 +108,6 @@ amm-info@iis.fraunhofer.de #include "rvlc.h" - #include "block.h" #include "aac_rom.h" @@ -100,26 +118,25 @@ amm-info@iis.fraunhofer.de /*--------------------------------------------------------------------------------------------- function: rvlcInit - description: init RVLC by data from channelinfo, which was decoded previously and - set up pointers + 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) -{ +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; + 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; @@ -129,7 +146,7 @@ void rvlcInit (CErRvlcInfo *pRvlc, pRvlc->numDecodedEscapeWordsBwd = 0; pRvlc->intensity_used = 0; - pRvlc->errorLogRvlc = 0; + pRvlc->errorLogRvlc = 0; pRvlc->conceal_max = CONCEAL_MAX_INIT; pRvlc->conceal_min = CONCEAL_MIN_INIT; @@ -137,8 +154,8 @@ void rvlcInit (CErRvlcInfo *pRvlc, pRvlc->conceal_max_esc = CONCEAL_MAX_INIT; pRvlc->conceal_min_esc = CONCEAL_MIN_INIT; - pRvlc->pHuffTreeRvlcEscape = aHuffTreeRvlcEscape; - pRvlc->pHuffTreeRvlCodewds = aHuffTreeRvlCodewds; + 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++) { @@ -148,33 +165,36 @@ void rvlcInit (CErRvlcInfo *pRvlc, pScaleFactor[bnds] = 0; } - /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2)) */ - FDKsyncCache (bs); - - pRvlc->bitstreamIndexRvlFwd = FDKgetBitCnt(bs); /* first bit within RVL coded block as start address for forward decoding */ - pRvlc->bitstreamIndexRvlBwd = FDKgetBitCnt(bs) + pRvlc->length_of_rvlc_sf - 1; /* last bit within RVL coded block as start address for backward decoding */ + /* set base bitstream ptr to the RVL-coded part (start of RVLC data (ESC 2)) + */ + FDKsyncCache(bs); - /* skip RVLC-bitstream-part -- pointing now to escapes (if present) or to TNS data (if present) */ - FDKpushFor (bs, pRvlc->length_of_rvlc_sf); + pRvlc->bitstreamIndexRvlFwd = FDKgetBitCnt( + bs); /* first bit within RVL coded block as start address for forward + decoding */ + pRvlc->bitstreamIndexRvlBwd = FDKgetBitCnt(bs) + pRvlc->length_of_rvlc_sf - + 1; /* last bit within RVL coded block as start + address for backward decoding */ - if ( pRvlc->sf_escapes_present != 0 ) { + /* 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); + FDKsyncCache(bs); pRvlc->bitstreamIndexEsc = FDKgetBitCnt(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); + /* 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); } - -#if VERBOSE_RVLC_INIT - DebugOutputInit(pRvlc,pAacDecoderChannelInfo); -#endif } - /*--------------------------------------------------------------------------------------------- function: rvlcCheckIntensityCb @@ -187,20 +207,22 @@ void rvlcInit (CErRvlcInfo *pRvlc, 1 intensity codebook is used ----------------------------------------------------------------------------------------------- return: - --------------------------------------------------------------------------------------------- */ +-------------------------------------------------------------------------------------------- +*/ -static -void rvlcCheckIntensityCb (CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo) -{ +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) ) { + 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; } @@ -208,49 +230,46 @@ void rvlcCheckIntensityCb (CErRvlcInfo *pRvlc, } } - /*--------------------------------------------------------------------------------------------- function: rvlcDecodeEscapeWord - description: Decode a huffman coded RVLC Escape-word. This value is part of a DPCM coded - scalefactor. + 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; - - USHORT* pBitstreamIndexEsc; - const UINT* pEscTree; + 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 */ + treeNode = *pEscTree; /* init at starting node */ - for (i=MAX_LEN_RVLC_ESCAPE_WORD-1; i >= 0; i--) { - carryBit = rvlcReadBitFromBitstream(bs, /* get next bit */ - pBitstreamIndexEsc, - FWD); + for (i = MAX_LEN_RVLC_ESCAPE_WORD - 1; i >= 0; i--) { + carryBit = rvlcReadBitFromBitstream(bs, /* get next bit */ + pBitstreamIndexEsc, FWD); - CarryBitToBranchValue(carryBit, /* huffman decoding, do a single step in huffman decoding tree */ - treeNode, - &branchValue, - &branchNode); + 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; + 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) { @@ -259,32 +278,33 @@ SCHAR rvlcDecodeEscapeWord (CErRvlcInfo *pRvlc, } return value; - } - else { - treeNode = *(pEscTree + branchValue); /* update treeNode for further step in decoding tree */ + } 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 */ + 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: + 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. + 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. + 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. ----------------------------------------------------------------------------------------------- @@ -294,29 +314,25 @@ SCHAR rvlcDecodeEscapeWord (CErRvlcInfo *pRvlc, 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; +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 ) { + while (*pEscBitCntSum > 0) { escWord = rvlcDecodeEscapeWord(pRvlc, bs); if (escWord >= 0) { - pEsc[escCnt] = escWord; escCnt++; - } - else { + } else { pRvlc->errorLogRvlc |= RVLC_ERROR_ALL_ESCAPE_WORDS_INVALID; pRvlc->numDecodedEscapeWordsEsc = escCnt; @@ -327,7 +343,6 @@ void rvlcDecodeEscapes (CErRvlcInfo *pRvlc, pRvlc->numDecodedEscapeWordsEsc = escCnt; } - /*--------------------------------------------------------------------------------------------- function: decodeRVLCodeword @@ -336,68 +351,71 @@ void rvlcDecodeEscapes (CErRvlcInfo *pRvlc, 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; + 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; - USHORT *pBitstrIndxRvl = pRvlc->pBitstrIndxRvl_RVL; - UINT treeNode = *pRvlCodeTree; - - for (i=MAX_LEN_RVLC_CODE_WORD-1; i >= 0; i--) { - carryBit = rvlcReadBitFromBitstream(bs, /* get next bit */ - 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); - + 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 */ + 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 */ + 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; + 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*/ - } + 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 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; -} + return -1; +} /*--------------------------------------------------------------------------------------------- function: rvlcDecodeForward @@ -409,94 +427,122 @@ SCHAR decodeRVLCodeword (HANDLE_FDK_BITSTREAM bs, CErRvlcInfo *pRvlc) - handle to FDK bitstream ----------------------------------------------------------------------------------------------- return: - --------------------------------------------------------------------------------------------- */ - -static -void rvlcDecodeForward (CErRvlcInfo *pRvlc, - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) -{ - int band = 0; +-------------------------------------------------------------------------------------------- +*/ + +static void rvlcDecodeForward(CErRvlcInfo *pRvlc, + CAacDecoderChannelInfo *pAacDecoderChannelInfo, + HANDLE_FDK_BITSTREAM bs) { + int band = 0; int group = 0; - int bnds = 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 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); - 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; + *pEscFwdCnt = 0; + pRvlc->direction = FWD; pRvlc->noise_used = 0; - pRvlc->sf_used = 0; - pRvlc->lastScf = 0; - pRvlc->lastNrg = 0; - pRvlc->lastIs = 0; + pRvlc->sf_used = 0; + pRvlc->lastScf = 0; + pRvlc->lastNrg = 0; + pRvlc->lastIs = 0; - rvlcCheckIntensityCb(pRvlc,pAacDecoderChannelInfo); + 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; + 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 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) { + case INTENSITY_HCB2: + case INTENSITY_HCB: + /* store dpcm_is_position */ + dpcm = decodeRVLCodeword(bs, pRvlc); + if (dpcm < 0) { pRvlc->conceal_max = bnds; return; } - else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; + 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; + } } - else { - dpcm += *pScfEsc++; + } + 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; } - (*pEscFwdCnt)++; - if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { - pRvlc->conceal_max_esc = bnds; + 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; } - } - position += dpcm; - pScfFwd[bnds] = position; - pRvlc->lastIs = position; - break; + pAacDecoderChannelInfo->data.aac.PnsData.pnsUsed[bnds] = 1; + 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 { + default: + pRvlc->sf_used = 1; dpcm = decodeRVLCodeword(bs, pRvlc); - if ( dpcm < 0 ) { + if (dpcm < 0) { pRvlc->conceal_max = bnds; return; } @@ -505,13 +551,11 @@ void rvlcDecodeForward (CErRvlcInfo *pRvlc, if (pRvlc->length_of_rvlc_escapes) { pRvlc->conceal_max = bnds; return; - } - else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } - else { - dpcm += *pScfEsc++; + } else { + if (dpcm == MIN_RVL) { + dpcm -= *pScfEsc++; + } else { + dpcm += *pScfEsc++; } (*pEscFwdCnt)++; if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { @@ -519,50 +563,18 @@ void rvlcDecodeForward (CErRvlcInfo *pRvlc, } } } - 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; + 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 ) { + dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */ + if (dpcm < 0) { pRvlc->conceal_max = bnds; return; } @@ -571,15 +583,13 @@ void rvlcDecodeForward (CErRvlcInfo *pRvlc, if (pRvlc->length_of_rvlc_escapes) { pRvlc->conceal_max = bnds; return; - } - else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc++; - } - else { - dpcm += *pScfEsc++; + } else { + if (dpcm == MIN_RVL) { + dpcm -= *pScfEsc++; + } else { + dpcm += *pScfEsc++; } - (*pEscFwdCnt)++; + (*pEscFwdCnt)++; if (pRvlc->conceal_max_esc == CONCEAL_MAX_INIT) { pRvlc->conceal_max_esc = bnds; } @@ -589,7 +599,6 @@ void rvlcDecodeForward (CErRvlcInfo *pRvlc, } } - /*--------------------------------------------------------------------------------------------- function: rvlcDecodeBackward @@ -600,22 +609,22 @@ void rvlcDecodeForward (CErRvlcInfo *pRvlc, - 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; +-------------------------------------------------------------------------------------------- +*/ + +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); @@ -624,15 +633,15 @@ void rvlcDecodeBackward (CErRvlcInfo *pRvlc, *pEscBwdCnt = 0; pRvlc->direction = BWD; - pScfEsc += *pEscEscCnt - 1; /* set pScfEsc to last entry */ + 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 ) { + dpcm = decodeRVLCodeword(bs, pRvlc); /* dpcm_is_last_position */ + if (dpcm < 0) { pRvlc->dpcm_is_last_position = 0; pRvlc->conceal_min = bnds; return; @@ -642,15 +651,13 @@ void rvlcDecodeBackward (CErRvlcInfo *pRvlc, if (pRvlc->length_of_rvlc_escapes) { pRvlc->conceal_min = bnds; return; - } - else { + } else { if (dpcm == MIN_RVL) { dpcm -= *pScfEsc--; - } - else { + } else { dpcm += *pScfEsc--; } - (*pEscBwdCnt)++; + (*pEscBwdCnt)++; if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { pRvlc->conceal_min_esc = bnds; } @@ -660,171 +667,162 @@ void rvlcDecodeBackward (CErRvlcInfo *pRvlc, } /* main loop long BWD */ - for (group=pRvlc->numWindowGroups-1; group >= 0; group--) { - for (band=pRvlc->maxSfbTransmitted-1; band >= 0; band--) { - bnds = 16*group+band; + 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 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 = FDKmax(0,bnds-offset); - return; - } - dpcm -= TABLE_OFFSET; - if ((dpcm == MIN_RVL) || (dpcm == MAX_RVL)) { - if (pRvlc->length_of_rvlc_escapes) { + case INTENSITY_HCB2: + case INTENSITY_HCB: + /* store dpcm_is_position */ + dpcm = decodeRVLCodeword(bs, pRvlc); + if (dpcm < 0) { pScfBwd[bnds] = position; - pRvlc->conceal_min = FDKmax(0,bnds-offset); + pRvlc->conceal_min = fMax(0, bnds - offset); return; } - else { - if (dpcm == MIN_RVL) { - dpcm -= *pScfEsc--; + 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); + } } - else { - dpcm += *pScfEsc--; + } + 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; } - (*pEscBwdCnt)++; - if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = FDKmax(0,bnds-offset); + 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; } - } - pScfBwd[bnds] = position; - position -= dpcm; - pRvlc->firstIs = position; - break; + 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 { + default: dpcm = decodeRVLCodeword(bs, pRvlc); - if ( dpcm < 0 ) { - pScfBwd[bnds] = noisenrg; - pRvlc->conceal_min = FDKmax(0,bnds-offset); + 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] = noisenrg; - pRvlc->conceal_min = FDKmax(0,bnds-offset); + pScfBwd[bnds] = factor; + pRvlc->conceal_min = fMax(0, bnds - offset); return; - } - else { + } else { if (dpcm == MIN_RVL) { dpcm -= *pScfEsc--; - } - else { + } else { dpcm += *pScfEsc--; } (*pEscBwdCnt)++; if (pRvlc->conceal_min_esc == CONCEAL_MIN_INIT) { - pRvlc->conceal_min_esc = FDKmax(0,bnds-offset); + 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 = FDKmax(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 = FDKmax(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 = FDKmax(0,bnds-offset); - } - } - } - pScfBwd[bnds] = factor; - factor -= dpcm; - pRvlc->firstScf = factor; - break; + factor -= dpcm; + pRvlc->firstScf = factor; + break; } } } } - /*--------------------------------------------------------------------------------------------- - function: rvlcFinalErrorDetection + function: rvlcFinalErrorDetection - description: Call RVLC concealment if error was detected in decoding process + 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; +-------------------------------------------------------------------------------------------- +*/ + +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*/ - -#if VERBOSE_RVLC_OUTPUT - CHAR Strategy[60]="No"; - SHORT conceal_max; - SHORT conceal_min; -#endif + 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 */ + /* invalid escape words, bit counter unequal zero, forbidden codeword detected + */ if (pRvlc->errorLogRvlc & RVLC_ERROR_FORBIDDEN_CW_DETECTED_FWD) ErrorStatusForbiddenCwFwd = 1; @@ -832,100 +830,102 @@ void rvlcFinalErrorDetection (CAacDecoderChannelInfo *pAacDecoderChannelInfo, ErrorStatusForbiddenCwBwd = 1; /* bit counter forward unequal zero */ - if (pRvlc->length_of_rvlc_sf_fwd) - ErrorStatusLengthFwd = 1; + if (pRvlc->length_of_rvlc_sf_fwd) ErrorStatusLengthFwd = 1; /* bit counter backward unequal zero */ - if (pRvlc->length_of_rvlc_sf_bwd) - ErrorStatusLengthBwd = 1; + 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->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) ) + 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) ) + /* 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) ) + /* 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) ) + /* 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; + 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) ) + 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)) { + 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)) { + if ((pRvlc->numDecodedEscapeWordsBwd != pRvlc->numDecodedEscapeWordsEsc) && + (pRvlc->conceal_min == CONCEAL_MIN_INIT)) { ErrorStatusNumEscapesBwd = 1; } -#if VERBOSE_RVLC_OUTPUT - conceal_max = pRvlc->conceal_max; - conceal_min = pRvlc->conceal_min; -#endif - - 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 = FDKmax(0, (pRvlc->numWindowGroups-1)*16+pRvlc->maxSfbTransmitted-1); - } - else { - pRvlc->conceal_max = FDKmin(pRvlc->conceal_max,pRvlc->conceal_max_esc); - pRvlc->conceal_min = FDKmax(pRvlc->conceal_min,pRvlc->conceal_min_esc); + 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; + ErrorStatusComplete = ErrorStatusLastScf || ErrorStatusFirstScf || + ErrorStatusLastNrg || ErrorStatusFirstNrg || + ErrorStatusLastIs || ErrorStatusFirstIs || + ErrorStatusForbiddenCwFwd || + ErrorStatusForbiddenCwBwd || ErrorStatusLengthFwd || + ErrorStatusLengthBwd || ErrorStatusLengthEscapes || + ErrorStatusNumEscapesFwd || ErrorStatusNumEscapesBwd; - currentBlockType = (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == EightShortSequence) ? 0 : 1; + currentBlockType = + (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) ? 0 + : 1; - if (!ErrorStatusComplete) { int band; int group; @@ -934,111 +934,115 @@ void rvlcFinalErrorDetection (CAacDecoderChannelInfo *pAacDecoderChannelInfo, 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; + 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 (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; + for (; band < lastSfbIndex; band++) { + bnds = 16 * group + band; FDK_ASSERT(bnds >= 0 && bnds < RVLC_MAX_SFB); - pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds] = ZERO_HCB; + pAacDecoderStaticChannelInfo->concealmentInfo + .aRvlcPreviousCodebook[bnds] = ZERO_HCB; } } - } - else { + } 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; -#if VERBOSE_RVLC_OUTPUT - FDKstrcpy(Strategy,"Yes (BidirectionalEstimation_UseScfOfPrevFrameAsReference)"); -#endif + /* 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; -#if VERBOSE_RVLC_OUTPUT - FDKstrcpy(Strategy,"Yes (BidirectionalEstimation_UseLowerScfOfCurrentFrame)"); -#endif + /* 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; -#if VERBOSE_RVLC_OUTPUT - FDKstrcpy(Strategy,"Yes (StatisticalEstimation)"); -#endif + /* 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; -#if VERBOSE_RVLC_OUTPUT - FDKstrcpy(Strategy,"Yes (PredictiveInterpolation)"); -#endif + /* 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 */ + /* 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; + 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; -#if VERBOSE_RVLC_OUTPUT - FDKstrcpy(Strategy,"Yes (FrameConcealment)"); -#endif + pAacDecoderChannelInfo->pDynData->specificTo.aac + .rvlcCurrentScaleFactorOK = 0; } } - -#if VERBOSE_RVLC_OUTPUT - DebugOutputDistortedBitstreams(pRvlc,pAacDecoderChannelInfo,ErrorStatusLengthFwd,ErrorStatusLengthBwd, - ErrorStatusLengthEscapes,ErrorStatusFirstScf,ErrorStatusLastScf, - ErrorStatusFirstNrg,ErrorStatusLastNrg,ErrorStatusFirstIs,ErrorStatusLastIs, - ErrorStatusForbiddenCwFwd,ErrorStatusForbiddenCwBwd,ErrorStatusNumEscapesFwd, - ErrorStatusNumEscapesBwd,conceal_max,conceal_min,Strategy); -#endif } - /*--------------------------------------------------------------------------------------------- - function: CRvlc_Read + function: CRvlc_Read description: Read RVLC ESC1 data (side info) from bitstream. ----------------------------------------------------------------------------------------------- @@ -1047,56 +1051,58 @@ void rvlcFinalErrorDetection (CAacDecoderChannelInfo *pAacDecoderChannelInfo, - pointer bitstream structure ----------------------------------------------------------------------------------------------- return: - --------------------------------------------------------------------------------------------- */ +-------------------------------------------------------------------------------------------- +*/ -void CRvlc_Read ( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - HANDLE_FDK_BITSTREAM bs) -{ - CErRvlcInfo *pRvlc = &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; +void CRvlc_Read(CAacDecoderChannelInfo *pAacDecoderChannelInfo, + HANDLE_FDK_BITSTREAM bs) { + CErRvlcInfo *pRvlc = + &pAacDecoderChannelInfo->pComData->overlay.aac.erRvlcInfo; - int group,band; + 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 */ + 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) == EightShortSequence) { - pRvlc->length_of_rvlc_sf = FDKreadBits(bs,11); /* #3 */ - } - else { - pRvlc->length_of_rvlc_sf = FDKreadBits(bs,9); /* #3 */ + 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) { + for (band = 0; band < pRvlc->maxSfbTransmitted; band++) { + if (pAacDecoderChannelInfo->pDynData->aCodeBook[16 * group + band] == + NOISE_HCB) { pRvlc->noise_used = 1; - break; + break; } } } - if (pRvlc->noise_used) - pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */ + if (pRvlc->noise_used) + pRvlc->dpcm_noise_nrg = FDKreadBits(bs, 9); /* #4 PNS */ - pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */ + pRvlc->sf_escapes_present = FDKreadBits(bs, 1); /* #5 */ - if ( pRvlc->sf_escapes_present) { - pRvlc->length_of_rvlc_escapes = FDKreadBits(bs, 8); /* #6 */ + 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 */ + if (pRvlc->noise_used) { + pRvlc->dpcm_noise_last_position = FDKreadBits(bs, 9); /* #7 PNS */ pRvlc->length_of_rvlc_sf -= 9; } @@ -1104,16 +1110,15 @@ void CRvlc_Read ( pRvlc->length_of_rvlc_sf_bwd = pRvlc->length_of_rvlc_sf; } - /*--------------------------------------------------------------------------------------------- - function: CRvlc_Decode + 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. + 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 @@ -1121,62 +1126,45 @@ void CRvlc_Read ( - 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; - UINT saveBitCnt; +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); + rvlcInit(pRvlc, pAacDecoderChannelInfo, bs); /* save bitstream position */ saveBitCnt = FDKgetBitCnt(bs); -#if RVLC_ADVANCED_BITSTREAM_ERROR_GENERATOR_SF - GenerateSingleBitError(pRvlc, - &(pRvlc->bitstreamIndexRvlFwd), - pRvlc->length_of_rvlc_sf, - 0); -#endif - -#if RVLC_ADVANCED_BITSTREAM_ERROR_GENERATOR_ESC if (pRvlc->sf_escapes_present) - GenerateSingleBitError(pRvlc, - &(pRvlc->bitstreamIndexEsc), - pRvlc->length_of_rvlc_escapes, - 1); -#endif + rvlcDecodeEscapes( + pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs); - if ( pRvlc->sf_escapes_present) - rvlcDecodeEscapes(pRvlc, pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfEsc, bs); - - rvlcDecodeForward(pRvlc,pAacDecoderChannelInfo, bs); - rvlcDecodeBackward(pRvlc,pAacDecoderChannelInfo, bs); + rvlcDecodeForward(pRvlc, pAacDecoderChannelInfo, bs); + rvlcDecodeBackward(pRvlc, pAacDecoderChannelInfo, bs); rvlcFinalErrorDetection(pAacDecoderChannelInfo, pAacDecoderStaticChannelInfo); - pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = pRvlc->intensity_used; + pAacDecoderChannelInfo->pDynData->specificTo.aac.rvlcIntensityUsed = + pRvlc->intensity_used; pAacDecoderChannelInfo->data.aac.PnsData.PnsActive = pRvlc->noise_used; /* restore bitstream position */ bitCntOffst = saveBitCnt - FDKgetBitCnt(bs); - if( bitCntOffst ) { + if (bitCntOffst) { FDKpushBiDirectional(bs, bitCntOffst); } } -void CRvlc_ElementCheck ( - CAacDecoderChannelInfo *pAacDecoderChannelInfo[], - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], - const UINT flags, - const INT elChannels - ) -{ +void CRvlc_ElementCheck( + CAacDecoderChannelInfo *pAacDecoderChannelInfo[], + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], + const UINT flags, const INT elChannels) { int ch; /* Required for MPS residuals. */ @@ -1185,31 +1173,42 @@ void CRvlc_ElementCheck ( } /* 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 ((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; + 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) == EightShortSequence) ? 0 : 1; + 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; + pAacDecoderStaticChannelInfo[ch] + ->concealmentInfo.rvlcPreviousScaleFactorOK = + pAacDecoderChannelInfo[ch] + ->pDynData->specificTo.aac.rvlcCurrentScaleFactorOK; + } else { + pAacDecoderStaticChannelInfo[ch] + ->concealmentInfo.rvlcPreviousScaleFactorOK = 0; } } } - - diff --git a/libAACdec/src/rvlc.h b/libAACdec/src/rvlc.h index 18d5fa3..9c60d51 100644 --- a/libAACdec/src/rvlc.h +++ b/libAACdec/src/rvlc.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -90,8 +109,6 @@ amm-info@iis.fraunhofer.de #ifndef RVLC_H #define RVLC_H - - #include "aacdecoder.h" #include "channel.h" #include "rvlc_info.h" @@ -100,35 +117,37 @@ amm-info@iis.fraunhofer.de /* 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); +#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. + * \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 - ); - - - +void CRvlc_ElementCheck( + CAacDecoderChannelInfo *pAacDecoderChannelInfo[], + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[], + const UINT flags, const INT elChannels); #endif /* RVLC_H */ diff --git a/libAACdec/src/rvlc_info.h b/libAACdec/src/rvlc_info.h index 63934af..fc9c19d 100644 --- a/libAACdec/src/rvlc_info.h +++ b/libAACdec/src/rvlc_info.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -89,88 +108,96 @@ amm-info@iis.fraunhofer.de #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 FWD 0 /* bitstream decoding direction forward (RVL coded part) */ -#define BWD 1 /* bitstream decoding direction backward (RVL coded part) */ +#define DPCM_NOISE_NRG_BITS 9 +#define SF_OFFSET 100 /* offset for correcting scf value */ -#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 CONCEAL_MAX_INIT 1311 /* arbitrary value */ +#define CONCEAL_MIN_INIT -1311 /* arbitrary value */ -#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)) +#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 */ +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; - USHORT *pBitstrIndxRvl_RVL; + SHORT *pRvlBitCnt_RVL; + INT *pBitstrIndxRvl_RVL; - UCHAR numWindowGroups; - UCHAR maxSfbTransmitted; - UCHAR first_noise_group; - UCHAR first_noise_band; - UCHAR direction; + UCHAR numWindowGroups; + UCHAR maxSfbTransmitted; + UCHAR first_noise_group; + UCHAR first_noise_band; + UCHAR direction; /* bitstream indices */ - USHORT bitstreamIndexRvlFwd; /* base address of RVL-coded-scalefactor data (ESC 2) for forward decoding */ - USHORT bitstreamIndexRvlBwd; /* base address of RVL-coded-scalefactor data (ESC 2) for backward decoding */ - USHORT bitstreamIndexEsc; /* base address where RVLC-escapes start (ESC 2) */ + 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 */ + 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; + SCHAR noise_used; + SCHAR intensity_used; + SCHAR sf_used; - SHORT firstScf; - SHORT lastScf; - SHORT firstNrg; - SHORT lastNrg; - SHORT firstIs; - SHORT lastIs; + 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 */ + 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/libAACdec/src/rvlcbit.cpp b/libAACdec/src/rvlcbit.cpp index 6efbb93..c06cf96 100644 --- a/libAACdec/src/rvlcbit.cpp +++ b/libAACdec/src/rvlcbit.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -89,28 +108,27 @@ amm-info@iis.fraunhofer.de #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). + 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, - USHORT *pPosition, - UCHAR readDirection) -{ - UINT bit; - INT readBitOffset = *pPosition-FDKgetBitCnt(bs); +UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, INT *pPosition, + UCHAR readDirection) { + UINT bit; + INT readBitOffset = *pPosition - FDKgetBitCnt(bs); - if( readBitOffset ) { + if (readBitOffset) { FDKpushBiDirectional(bs, readBitOffset); } @@ -128,4 +146,3 @@ UCHAR rvlcReadBitFromBitstream (HANDLE_FDK_BITSTREAM bs, return (bit); } - diff --git a/libAACdec/src/rvlcbit.h b/libAACdec/src/rvlcbit.h index 02fba88..5c6a3f1 100644 --- a/libAACdec/src/rvlcbit.h +++ b/libAACdec/src/rvlcbit.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,11 +90,12 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder *************************** +/**************************** AAC decoder library ****************************** Author(s): Robert Weidner (DSP Solutions) + Description: RVLC Decoder: Bitstream reading *******************************************************************************/ @@ -91,13 +103,9 @@ amm-info@iis.fraunhofer.de #ifndef RVLCBIT_H #define RVLCBIT_H - - #include "rvlc.h" -UCHAR rvlcReadBitFromBitstream (HANDLE_FDK_BITSTREAM bs, - USHORT *pPosition, - UCHAR readDirection); - +UCHAR rvlcReadBitFromBitstream(HANDLE_FDK_BITSTREAM bs, INT *pPosition, + UCHAR readDirection); #endif /* RVLCBIT_H */ diff --git a/libAACdec/src/rvlcconceal.cpp b/libAACdec/src/rvlcconceal.cpp index cf33dd5..77fda68 100644 --- a/libAACdec/src/rvlcconceal.cpp +++ b/libAACdec/src/rvlcconceal.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -89,37 +108,33 @@ amm-info@iis.fraunhofer.de #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. + 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; +-------------------------------------------------------------------------------------------- +*/ +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) == EightShortSequence) + if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) MaximumScaleFactorBands = 16; else MaximumScaleFactorBands = 64; @@ -131,69 +146,71 @@ void calcRefValFwd (CErRvlcInfo *pRvlc, 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; + *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 */ + *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 */ + *refNrgFwd = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; + idNrg = 0; /* reference value has been set */ } - break ; + break; default: if (idScf) { - *refScfFwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; - idScf=0; /* reference value has been set */ + *refScfFwd = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; + idScf = 0; /* reference value has been set */ } break; } } - startBand = pRvlc->maxSfbTransmitted-1; + 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. + 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; +-------------------------------------------------------------------------------------------- +*/ + +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) == EightShortSequence) + if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) MaximumScaleFactorBands = 16; else MaximumScaleFactorBands = 64; @@ -206,86 +223,91 @@ void calcRefValBwd (CErRvlcInfo *pRvlc, /* 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; + *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; + 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; + 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 */ + *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 */ + *refNrgBwd = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; + idNrg = 0; /* reference value has been set */ } - break ; + break; default: if (idScf) { - *refScfBwd = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - idScf=0; /* reference value has been set */ + *refScfBwd = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; + idScf = 0; /* reference value has been set */ } break; } } - startBand=0; + 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. + 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 + 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; +-------------------------------------------------------------------------------------------- +*/ + +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) == EightShortSequence) { + if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) { MaximumScaleFactorBands = 16; - } - else { + } 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 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; + pRvlc->conceal_max = + (pRvlc->numWindowGroups - 1) * 16 + pRvlc->maxSfbTransmitted - 1; conceal_min = pRvlc->conceal_min % MaximumScaleFactorBands; conceal_group_min = pRvlc->conceal_min / MaximumScaleFactorBands; @@ -293,20 +315,21 @@ void BidirectionalEstimation_UseLowerScfOfCurrentFrame (CAacDecoderChannelInfo * conceal_group_max = pRvlc->conceal_max / MaximumScaleFactorBands; if (pRvlc->conceal_min == pRvlc->conceal_max) { - - int refIsFwd,refNrgFwd,refScfFwd; - int refIsBwd,refNrgBwd,refScfBwd; + int refIsFwd, refNrgFwd, refScfFwd; + int refIsBwd, refNrgBwd, refScfBwd; bnds = pRvlc->conceal_min; - calcRefValFwd(pRvlc,pAacDecoderChannelInfo,&refIsFwd,&refNrgFwd,&refScfFwd); - calcRefValBwd(pRvlc,pAacDecoderChannelInfo,&refIsBwd,&refNrgBwd,&refScfBwd); + 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) + if (refIsFwd < refIsBwd) pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsFwd; else pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refIsBwd; @@ -320,55 +343,64 @@ void BidirectionalEstimation_UseLowerScfOfCurrentFrame (CAacDecoderChannelInfo * default: if (refScfFwd < refScfBwd) pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = refScfFwd; - else + 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->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; - } + 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 (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; + 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 = 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; } @@ -377,71 +409,79 @@ void BidirectionalEstimation_UseLowerScfOfCurrentFrame (CAacDecoderChannelInfo * /*--------------------------------------------------------------------------------------------- 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. + 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 + 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; +-------------------------------------------------------------------------------------------- +*/ + +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; - int commonMin; + SHORT commonMin; - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == EightShortSequence) { + if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == BLOCK_SHORT) { MaximumScaleFactorBands = 16; - } - else { + } 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 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; + 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; + 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; + 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; @@ -449,62 +489,92 @@ void BidirectionalEstimation_UseScfOfPrevFrameAsReference ( case INTENSITY_HCB: case INTENSITY_HCB2: - if ( (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==INTENSITY_HCB) || (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==INTENSITY_HCB2) ) { - commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); - } - else { - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); + 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 = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); + 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] = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); + 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 = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds], pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); + 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] = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); + 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; + 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 (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; + 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 = 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; } @@ -513,81 +583,82 @@ void BidirectionalEstimation_UseScfOfPrevFrameAsReference ( /*--------------------------------------------------------------------------------------------- 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. + 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 */ - int MaximumScaleFactorBands; +-------------------------------------------------------------------------------------------- +*/ - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == EightShortSequence) - MaximumScaleFactorBands = 16; - else - MaximumScaleFactorBands = 64; +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; + /* 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]; + 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 ; + 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]; + 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 (sumIsFwd < sumIsBwd) useIsFwd = 1; - if ( sumNrgFwd < sumNrgBwd ) - useNrgFwd = 1; + if (sumNrgFwd < sumNrgBwd) useNrgFwd = 1; - if ( sumScfFwd < sumScfBwd ) - useScfFwd = 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; + 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; @@ -595,63 +666,63 @@ void StatisticalEstimation (CAacDecoderChannelInfo *pAacDecoderChannelInfo) case INTENSITY_HCB: case INTENSITY_HCB2: if (useIsFwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; + pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; + 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]; + pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; - break ; + pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; + break; default: if (useScfFwd) - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; + pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = + pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds]; else - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]; + 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. + 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; - int MaximumScaleFactorBands; - int commonMin; - - if (GetWindowSequence(&pAacDecoderChannelInfo->icsInfo) == EightShortSequence) - MaximumScaleFactorBands = 16; - else - MaximumScaleFactorBands = 64; +-------------------------------------------------------------------------------------------- +*/ - for (group=0; group<pRvlc->numWindowGroups; group++) { - for (band=0; band < pRvlc->maxSfbTransmitted; band++) { - bnds = 16*group+band; +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; @@ -659,34 +730,54 @@ void PredictiveInterpolation ( case INTENSITY_HCB: case INTENSITY_HCB2: - if ( (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==INTENSITY_HCB) || (pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousCodebook[bnds]==INTENSITY_HCB2) ) { - commonMin = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); - } - else { + 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 = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); - } - else { + 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 = FDKmin(pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfFwd[bnds],pAacDecoderChannelInfo->pComData->overlay.aac.aRvlcScfBwd[bnds]); - pAacDecoderChannelInfo->pDynData->aScaleFactor[bnds] = FDKmin(commonMin, pAacDecoderStaticChannelInfo->concealmentInfo.aRvlcPreviousScaleFactor[bnds]); - } - else { + 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; @@ -694,4 +785,3 @@ void PredictiveInterpolation ( } } } - diff --git a/libAACdec/src/rvlcconceal.h b/libAACdec/src/rvlcconceal.h index 750cbcd..8e2062e 100644 --- a/libAACdec/src/rvlcconceal.h +++ b/libAACdec/src/rvlcconceal.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,7 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file @@ -90,23 +109,19 @@ amm-info@iis.fraunhofer.de #ifndef RVLCCONCEAL_H #define RVLCCONCEAL_H - - #include "rvlc.h" -void BidirectionalEstimation_UseLowerScfOfCurrentFrame(CAacDecoderChannelInfo *pAacDecoderChannelInfo); +void BidirectionalEstimation_UseLowerScfOfCurrentFrame( + CAacDecoderChannelInfo *pAacDecoderChannelInfo); void BidirectionalEstimation_UseScfOfPrevFrameAsReference( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo - ); - -void StatisticalEstimation (CAacDecoderChannelInfo *pAacDecoderChannelInfo); + CAacDecoderChannelInfo *pAacDecoderChannelInfo, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo); -void PredictiveInterpolation ( - CAacDecoderChannelInfo *pAacDecoderChannelInfo, - CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo - ); +void StatisticalEstimation(CAacDecoderChannelInfo *pAacDecoderChannelInfo); +void PredictiveInterpolation( + CAacDecoderChannelInfo *pAacDecoderChannelInfo, + CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo); #endif /* RVLCCONCEAL_H */ diff --git a/libAACdec/src/stereo.cpp b/libAACdec/src/stereo.cpp index 4f28244..bb4f050 100644 --- a/libAACdec/src/stereo.cpp +++ b/libAACdec/src/stereo.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,216 +90,1159 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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; + } -enum -{ - L = 0, - R = 1 -}; + 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; -int CJointStereo_Read( - HANDLE_FDK_BITSTREAM bs, - CJointStereoData *pJointStereoData, - const int windowGroups, - const int scaleFactorBandsTransmitted, - const UINT flags - ) -{ - int group,band; + case 2: /* full spectrum M/S */ + for (band = 0; band < scaleFactorBandsTransmitted; band++) { + pJointStereoData->MsUsed[band] = 255; /* set all flags to 1 */ + } + break; - pJointStereoData->MsMaskPresent = (UCHAR) FDKreadBits(bs,2); + 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)' */ - FDKmemclear(pJointStereoData->MsUsed, scaleFactorBandsTransmitted*sizeof(UCHAR)); + pJointStereoData->cplx_pred_flag = 1; - switch (pJointStereoData->MsMaskPresent) - { - case 0 : /* no M/S */ - /* all flags are already cleared */ - break ; + /* 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); - case 1 : /* read ms_used */ + 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; + } - for (group=0; group<windowGroups; group++) - { - for (band=0; band<scaleFactorBandsTransmitted; band++) + 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)); + } { - pJointStereoData->MsUsed[band] |= (FDKreadBits(bs,1) << group); + FDKmemclear(cplxPredictionData->alpha_q_re, + JointStereoMaximumGroups * JointStereoMaximumBands * + sizeof(SHORT)); + FDKmemclear(cplxPredictionData->alpha_q_im, + JointStereoMaximumGroups * JointStereoMaximumBands * + sizeof(SHORT)); } - } - break ; - case 2 : /* full spectrum M/S */ + /* 0 = mid->side prediction, 1 = side->mid prediction */ + cplxPredictionData->pred_dir = FDKreadBits(bs, 1); + cplxPredictionData->complex_coef = FDKreadBits(bs, 1); - for (band=0; band<scaleFactorBandsTransmitted; band++) - { - pJointStereoData->MsUsed[band] = 255 ; /* set all flags to 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; + } } - break ; + } + + 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], - const SHORT *pScaleFactorBandOffsets, - const UCHAR *pWindowGroupLength, - const int windowGroups, - const int scaleFactorBandsTransmittedL, - const int scaleFactorBandsTransmittedR - ) -{ - CJointStereoData *pJointStereoData = &pAacDecoderChannelInfo[L]->pComData->jointStereoData; - int window, group, scaleFactorBandsTransmitted; - - FDK_ASSERT(scaleFactorBandsTransmittedL == scaleFactorBandsTransmittedR); - scaleFactorBandsTransmitted = scaleFactorBandsTransmittedL; - for (window = 0, group = 0; group < windowGroups; group++) - { - UCHAR groupMask = 1 << group; + 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; + } - for (int groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++, window++) + /* 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) + ) */ { - int band; - FIXP_DBL *leftSpectrum, *rightSpectrum; - SHORT *leftScale = &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window*16]; - SHORT *rightScale = &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window*16]; + coeffPointerOffset = 3; + } - leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient, window, pAacDecoderChannelInfo[L]->granuleLength); - rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient, window, pAacDecoderChannelInfo[R]->granuleLength); + /* 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; - for (band=0; band<scaleFactorBandsTransmitted; band++) - { - if (pJointStereoData->MsUsed[band] & groupMask) - { - int lScale=leftScale[band]; - int rScale=rightScale[band]; - int commonScale=lScale > rScale ? lScale:rScale; + case BLOCK_STOP: + pCoeff = mdst_filt_coef_curr[8 + coeffPointerOffset]; + break; + + default: + pCoeff = mdst_filt_coef_curr[coeffPointerOffset]; + } - /* 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)); + /* 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; + } + } + } - commonScale++; - leftScale[band]=commonScale; - rightScale[band]=commonScale; + /* find maximum common SF of all windows */ + frameMaxScale = + (frameMaxScale < windowMaxScale) ? windowMaxScale : frameMaxScale; + } + } - lScale = fMin(DFRACT_BITS-1, commonScale - lScale); - rScale = fMin(DFRACT_BITS-1, commonScale - rScale); + /* 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; + } + } + } - FDK_ASSERT(lScale >= 0 && rScale >= 0); + } /* 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; + } - for (int index=pScaleFactorBandOffsets[band]; index<pScaleFactorBandOffsets[band+1]; index++) + /* 3. calculate MDST-portion corresponding to the current frame. */ + if (cplxPredictionData->complex_coef == 1) { { - FIXP_DBL leftCoefficient = leftSpectrum [index] ; - FIXP_DBL rightCoefficient = rightSpectrum [index] ; + /* 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]; + } - leftCoefficient >>= lScale ; - rightCoefficient >>= rScale ; + /* 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]; - leftSpectrum [index] = leftCoefficient + rightCoefficient ; - rightSpectrum [index] = leftCoefficient - rightCoefficient ; + 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)); + /* 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, - const UINT CommonWindow - ) -{ - CJointStereoData *pJointStereoData = &pAacDecoderChannelInfo[L]->pComData->jointStereoData; - - for (int window=0,group=0; group<windowGroups; group++) - { +void CJointStereo_ApplyIS(CAacDecoderChannelInfo *pAacDecoderChannelInfo[2], + const SHORT *pScaleFactorBandOffsets, + const UCHAR *pWindowGroupLength, + const int windowGroups, + const int scaleFactorBandsTransmitted, + const UINT CommonWindow) { + 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]; + CodeBook = &pAacDecoderChannelInfo[R]->pDynData->aCodeBook[group * 16]; + ScaleFactor = + &pAacDecoderChannelInfo[R]->pDynData->aScaleFactor[group * 16]; - for (int groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++, window++) - { + 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]; + 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); + 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) ; + 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 ; + 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 (CommonWindow && (pJointStereoData->MsUsed[band] & groupMask)) - { - + 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 (CommonWindow && (pJointStereoData->MsUsed[band] & groupMask)) { if (CodeBook[band] == INTENSITY_HCB) /* _NOT_ in-phase */ { - scale = -scale ; + scale = -scale; } - } - else - { + } else { if (CodeBook[band] == INTENSITY_HCB2) /* out-of-phase */ { - scale = -scale ; + scale = -scale; } } - for (int index=pScaleFactorBandOffsets[band]; index<pScaleFactorBandOffsets[band+1]; index++) - { - rightSpectrum[index] = fMult(leftSpectrum[index],scale); + for (int index = pScaleFactorBandOffsets[band]; + index < pScaleFactorBandOffsets[band + 1]; index++) { + rightSpectrum[index] = fMult(leftSpectrum[index], scale); } } } diff --git a/libAACdec/src/stereo.h b/libAACdec/src/stereo.h index 899b485..af7a74f 100644 --- a/libAACdec/src/stereo.h +++ b/libAACdec/src/stereo.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,35 +90,100 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Decoder ************************** +/**************************** 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 }; -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 -typedef struct -{ + 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 */ + 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 @@ -115,20 +191,21 @@ typedef struct 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 + \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, - int windowGroups, - int scaleFactorBandsTransmitted, - UINT flags - ); - +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/libAACdec/src/usacdec_ace_d4t64.cpp b/libAACdec/src/usacdec_ace_d4t64.cpp new file mode 100644 index 0000000..43e06cd --- /dev/null +++ b/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/libAACdec/src/usacdec_ace_d4t64.h b/libAACdec/src/usacdec_ace_d4t64.h new file mode 100644 index 0000000..76bc3d9 --- /dev/null +++ b/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/libAACdec/src/usacdec_ace_ltp.cpp b/libAACdec/src/usacdec_ace_ltp.cpp new file mode 100644 index 0000000..5964b49 --- /dev/null +++ b/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/libAACdec/src/usacdec_ace_ltp.h b/libAACdec/src/usacdec_ace_ltp.h new file mode 100644 index 0000000..5128acd --- /dev/null +++ b/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/libAACdec/src/usacdec_acelp.cpp b/libAACdec/src/usacdec_acelp.cpp new file mode 100644 index 0000000..ec4437f --- /dev/null +++ b/libAACdec/src/usacdec_acelp.cpp @@ -0,0 +1,1289 @@ +/* ----------------------------------------------------------------------------- +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 = t_qua_gain7b[i]; /* adaptive codebook gain */ + /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */ + Ltmp = fMult(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)]); + } + + L_tmp = scaleValue(L_tmp, a_exp + 1); + y[i] = 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]); + } + + s = scaleValue(s, a_exp + 1); + 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, 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)); + + /* 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/libAACdec/src/usacdec_acelp.h b/libAACdec/src/usacdec_acelp.h new file mode 100644 index 0000000..593a073 --- /dev/null +++ b/libAACdec/src/usacdec_acelp.h @@ -0,0 +1,280 @@ +/* ----------------------------------------------------------------------------- +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, 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/libAACdec/src/usacdec_const.h b/libAACdec/src/usacdec_const.h new file mode 100644 index 0000000..c7dbae7 --- /dev/null +++ b/libAACdec/src/usacdec_const.h @@ -0,0 +1,202 @@ +/* ----------------------------------------------------------------------------- +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 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/libAACdec/src/usacdec_fac.cpp b/libAACdec/src/usacdec_fac.cpp new file mode 100644 index 0000000..71ce4a9 --- /dev/null +++ b/libAACdec/src/usacdec_fac.cpp @@ -0,0 +1,743 @@ +/* ----------------------------------------------------------------------------- +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, UCHAR *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)]); + } + + L_tmp = scaleValue(L_tmp, a_exp + 1); + + x[i] = scaleValueSaturate((x[i] >> 1) + (L_tmp >> 1), + 1); /* Avoid overflow issues and saturate. */ + } +} + +/* 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) { + scaleValuesWithFactor(pSpec, total_gain, tl, spec_scale[0] + scale); + } else { + scaleValues(pSpec, tl, spec_scale[0] + 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) { + scaleValuesWithFactor(pSpec, total_gain, tl, spec_scale[w] + scale); + } else { + scaleValues(pSpec, tl, spec_scale[w] + 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/libAACdec/src/usacdec_fac.h b/libAACdec/src/usacdec_fac.h new file mode 100644 index 0000000..bf13552 --- /dev/null +++ b/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, UCHAR *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/libAACdec/src/usacdec_lpc.cpp b/libAACdec/src/usacdec_lpc.cpp new file mode 100644 index 0000000..271463f --- /dev/null +++ b/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/libAACdec/src/usacdec_lpc.h b/libAACdec/src/usacdec_lpc.h new file mode 100644 index 0000000..a6713c1 --- /dev/null +++ b/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/libAACdec/src/usacdec_lpd.cpp b/libAACdec/src/usacdec_lpd.cpp new file mode 100644 index 0000000..4ce6699 --- /dev/null +++ b/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; + + 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 (pSamplingRateInfo->samplingRate > + FAC_FSCALE_MAX /* maximum allowed core sampling frequency */) { + 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, + 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/libAACdec/src/usacdec_lpd.h b/libAACdec/src/usacdec_lpd.h new file mode 100644 index 0000000..3e7938d --- /dev/null +++ b/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/libAACdec/src/usacdec_rom.cpp b/libAACdec/src/usacdec_rom.cpp new file mode 100644 index 0000000..519e992 --- /dev/null +++ b/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 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/libAACdec/src/usacdec_rom.h b/libAACdec/src/usacdec_rom.h new file mode 100644 index 0000000..0ad4cb0 --- /dev/null +++ b/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 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 */ |