diff options
Diffstat (limited to 'libAACenc/src')
72 files changed, 23845 insertions, 20313 deletions
diff --git a/libAACenc/src/aacEnc_ram.cpp b/libAACenc/src/aacEnc_ram.cpp index be3eea2..77b1131 100644 --- a/libAACenc/src/aacEnc_ram.cpp +++ b/libAACenc/src/aacEnc_ram.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,16 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M. Lohwasser, M. Gayer -/****************************************************************************** + Description: - Initial authors: M. Lohwasser, M. Gayer - Contents/description: +*******************************************************************************/ -******************************************************************************/ /*! \file \brief Memory layout @@ -95,100 +108,101 @@ amm-info@iis.fraunhofer.de #include "aacEnc_ram.h" - C_AALLOC_MEM (AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE/sizeof(FIXP_DBL)) +C_AALLOC_MEM(AACdynamic_RAM, FIXP_DBL, AAC_ENC_DYN_RAM_SIZE / sizeof(FIXP_DBL)) /* - Static memory areas, must not be overwritten in other sections of the decoder ! + Static memory areas, must not be overwritten in other sections of the decoder + ! */ /* The structure AacEncoder contains all Encoder structures. */ -C_ALLOC_MEM (Ram_aacEnc_AacEncoder, AAC_ENC, 1) - +C_ALLOC_MEM(Ram_aacEnc_AacEncoder, struct AAC_ENC, 1) /* The structure PSY_INTERNAl contains all psych configuration and data pointer. * PsyStatic holds last and current Psych data. - * PsyInputBuffer contains time input. Signal is needed at the beginning of Psych. - Memory can be reused after signal is in time domain. - * PsyData contains spectral, nrg and threshold information. Necessary data are - copied into PsyOut, so memory is available after leaving psych. - * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory from - PsyInputBuffer. + * PsyInputBuffer contains time input. Signal is needed at the beginning of + Psych. Memory can be reused after signal is in time domain. + * PsyData contains spectral, nrg and threshold information. Necessary data + are copied into PsyOut, so memory is available after leaving psych. + * TnsData, ChaosMeasure, PnsData are temporarily necessary, e.g. use memory + from PsyInputBuffer. */ -C_ALLOC_MEM2 (Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, (8)) - -C_ALLOC_MEM (Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1) -C_ALLOC_MEM2 (Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8)) +C_ALLOC_MEM2(Ram_aacEnc_PsyElement, PSY_ELEMENT, 1, ((8))) -C_ALLOC_MEM2 (Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8)) +C_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL, 1) +C_ALLOC_MEM2(Ram_aacEnc_PsyStatic, PSY_STATIC, 1, (8)) - PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic (int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((PSY_DYNAMIC*) (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC))); - } +C_ALLOC_MEM2(Ram_aacEnc_PsyInputBuffer, INT_PCM, MAX_INPUT_BUFFER_SIZE, (8)) - C_ALLOC_MEM (Ram_bsOutbuffer, UCHAR, OUTPUTBUFFER_SIZE) +PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1 + n*sizeof(PSY_DYNAMIC)) is sufficiently aligned, so + * the cast is safe */ + return reinterpret_cast<PSY_DYNAMIC *>(reinterpret_cast<void *>( + dynamic_RAM + P_BUF_1 + n * sizeof(PSY_DYNAMIC))); +} /* The structure PSY_OUT holds all psychoaccoustic data needed in quantization module */ -C_ALLOC_MEM2 (Ram_aacEnc_PsyOut, PSY_OUT, 1, (1)) - -C_ALLOC_MEM2 (Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1)*(8)) -C_ALLOC_MEM2 (Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1)*(8)) +C_ALLOC_MEM2(Ram_aacEnc_PsyOut, PSY_OUT, 1, (1)) +C_ALLOC_MEM2(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT, 1, (1) * ((8))) +C_ALLOC_MEM2(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL, 1, (1) * (8)) /* - The structure QC_STATE contains preinitialized settings and quantizer structures. + The structure QC_STATE contains preinitialized settings and quantizer + structures. * AdjustThreshold structure contains element-wise settings. * ElementBits contains elemnt-wise bit consumption settings. * When CRC is active, lookup table is necessary for fast crc calculation. - * Bitcounter contains buffer to find optimal codebooks and minimal bit consumption. - Values are temporarily, so dynamic memory can be used. + * Bitcounter contains buffer to find optimal codebooks and minimal bit + consumption. Values are temporarily, so dynamic memory can be used. */ -C_ALLOC_MEM (Ram_aacEnc_QCstate, QC_STATE, 1) -C_ALLOC_MEM (Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1) - -C_ALLOC_MEM2 (Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, (8)) -C_ALLOC_MEM2 (Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, (8)) -C_ALLOC_MEM (Ram_aacEnc_BitCntrState, BITCNTR_STATE, 1) - - INT *GetRam_aacEnc_BitLookUp(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((INT*) (dynamic_RAM + P_BUF_1)); - } - INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((INT*) (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)))); - } - +C_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE, 1) +C_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE, 1) + +C_ALLOC_MEM2(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT, 1, ((8))) +C_ALLOC_MEM2(Ram_aacEnc_ElementBits, ELEMENT_BITS, 1, ((8))) +C_ALLOC_MEM(Ram_aacEnc_BitCntrState, struct BITCNTR_STATE, 1) + +INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1) is sufficiently aligned, so the cast is safe */ + return reinterpret_cast<INT *>( + reinterpret_cast<void *>(dynamic_RAM + P_BUF_1)); +} +INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_1 + sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1))) + * is sufficiently aligned, so the cast is safe */ + return reinterpret_cast<INT *>(reinterpret_cast<void *>( + dynamic_RAM + P_BUF_1 + + sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1)))); +} /* - The structure QC_OUT contains settings and structures holding all necessary information - needed in bitstreamwriter. + The structure QC_OUT contains settings and structures holding all necessary + information needed in bitstreamwriter. */ -C_ALLOC_MEM2 (Ram_aacEnc_QCout, QC_OUT, 1, (1)) -C_ALLOC_MEM2 (Ram_aacEnc_QCelement, QC_OUT_ELEMENT, (1), (8)) - QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel (int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM!=0); - return ((QC_OUT_CHANNEL*) (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL))); - } - - - - - - - - - - - - +C_ALLOC_MEM2(Ram_aacEnc_QCout, QC_OUT, 1, (1)) +C_ALLOC_MEM2(Ram_aacEnc_QCelement, QC_OUT_ELEMENT, 1, (1) * ((8))) +QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM) { + FDK_ASSERT(dynamic_RAM != 0); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * (dynamic_RAM + P_BUF_0 + n*sizeof(QC_OUT_CHANNEL)) is sufficiently aligned, + * so the cast is safe */ + return reinterpret_cast<QC_OUT_CHANNEL *>(reinterpret_cast<void *>( + dynamic_RAM + P_BUF_0 + n * sizeof(QC_OUT_CHANNEL))); +} diff --git a/libAACenc/src/aacEnc_ram.h b/libAACenc/src/aacEnc_ram.h index cf7da7c..0775aae 100644 --- a/libAACenc/src/aacEnc_ram.h +++ b/libAACenc/src/aacEnc_ram.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,23 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: -******************************************************************************/ +*******************************************************************************/ /*! \file - \brief Memory layout + \brief Memory layout \author Markus Lohwasser */ -#ifndef AAC_ENC_RAM_H -#define AAC_ENC_RAM_H +#ifndef AACENC_RAM_H +#define AACENC_RAM_H #include "common_fix.h" @@ -107,32 +119,35 @@ amm-info@iis.fraunhofer.de #include "bit_cnt.h" #include "psy_const.h" - #define OUTPUTBUFFER_SIZE (8192) /*!< Output buffer size has to be at least 6144 bits per channel (768 bytes). FDK bitbuffer implementation expects buffer of size 2^n. */ - +#define OUTPUTBUFFER_SIZE \ + (8192) /*!< Output buffer size has to be at least 6144 bits per channel \ + (768 bytes). FDK bitbuffer implementation expects buffer of \ + size 2^n. */ /* - Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size and respective - static memory in aacEnc_ram.cpp. - aac_enc.h is the outward visible header file and putting the struct into would cause necessity - of additional visible header files outside library. + Moved AAC_ENC struct definition from aac_enc.cpp into aacEnc_ram.h to get size + and respective static memory in aacEnc_ram.cpp. aac_enc.h is the outward + visible header file and putting the struct into would cause necessity of + additional visible header files outside library. */ /* define hBitstream size: max AAC framelength is 6144 bits/channel */ -/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) / bbWordSize))*/ +/*#define BUFFER_BITSTR_SIZE ((6400*(8)/bbWordSize) +((bbWordSize - 1) / + * bbWordSize))*/ struct AAC_ENC { + AACENC_CONFIG *config; - AACENC_CONFIG *config; + INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from + ancillary rate */ - INT ancillaryBitsPerFrame; /* ancillary bits per frame calculated from ancillary rate */ + CHANNEL_MAPPING channelMapping; - CHANNEL_MAPPING channelMapping; + QC_STATE *qcKernel; + QC_OUT *qcOut[(1)]; - QC_STATE *qcKernel; - QC_OUT *qcOut[(1)]; - - PSY_OUT *psyOut[(1)]; - PSY_INTERNAL *psyKernel; + PSY_OUT *psyOut[(1)]; + PSY_INTERNAL *psyKernel; /* lifetime vars */ @@ -140,50 +155,61 @@ struct AAC_ENC { INT bandwidth90dB; AACENC_BITRATE_MODE bitrateMode; - INT dontWriteAdif; /* use: write ADIF header only before 1st frame */ - - FIXP_DBL *dynamic_RAM; + INT dontWriteAdif; /* use: write ADIF header only before 1st frame */ + FIXP_DBL *dynamic_RAM; - INT maxChannels; /* used while allocation */ + INT maxChannels; /* used while allocation */ INT maxElements; INT maxFrames; - AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */ + AUDIO_OBJECT_TYPE aot; /* AOT to be used while encoding. */ +}; -} ; - -#define maxSize(a,b) ( ((a)>(b)) ? (a) : (b) ) - -#define BIT_LOOK_UP_SIZE ( sizeof(INT)*(MAX_SFB_LONG*(CODE_BOOK_ESC_NDX+1)) ) -#define MERGE_GAIN_LOOK_UP_SIZE ( sizeof(INT)*MAX_SFB_LONG ) +#define maxSize(a, b) (((a) > (b)) ? (a) : (b)) +#define BIT_LOOK_UP_SIZE \ + (sizeof(INT) * (MAX_SFB_LONG * (CODE_BOOK_ESC_NDX + 1))) +#define MERGE_GAIN_LOOK_UP_SIZE (sizeof(INT) * MAX_SFB_LONG) +/* Size of AhFlag buffer in function FDKaacEnc_adaptThresholdsToPe() */ +#define ADJ_THR_AH_FLAG_SIZE (sizeof(UCHAR) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Size of ThrExp buffer in function FDKaacEnc_adaptThresholdsToPe() */ +#define ADJ_THR_THR_EXP_SIZE (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Size of sfbNActiveLinesLdData buffer in function FDKaacEnc_correctThresh() */ +#define ADJ_THR_ACT_LIN_LD_DATA_SIZE \ + (sizeof(FIXP_DBL) * ((8)) * (2) * MAX_GROUPED_SFB) +/* Total amount of dynamic buffer needed in adjust thresholds functionality */ +#define ADJ_THR_SIZE \ + (ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE + ADJ_THR_ACT_LIN_LD_DATA_SIZE) /* Dynamic RAM - Allocation */ /* - ++++++++++++++++++++++++++++++++++++++++++++ - | P_BUF_0 | P_BUF_1 | - ++++++++++++++++++++++++++++++++++++++++++++ - | QC_OUT_CH | PSY_DYN | - ++++++++++++++++++++++++++++++++++++++++++++ - | | BitLookUp+MergeGainLookUp | - ++++++++++++++++++++++++++++++++++++++++++++ - | | Bitstream output buffer | - ++++++++++++++++++++++++++++++++++++++++++++ + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | P_BUF_0 | P_BUF_1 | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | QC_OUT_CH | PSY_DYN | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | BitLookUp+MergeGainLookUp | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | AH_FLAG | THR_EXP | ACT_LIN_LD_DATA | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | Bitstream output buffer | + +++++++++++++++++++++++++++++++++++++++++++++++++++++ */ -#define BUF_SIZE_0 ( ALIGN_SIZE(sizeof(QC_OUT_CHANNEL)*(8)) ) -#define BUF_SIZE_1 ( ALIGN_SIZE(maxSize(sizeof(PSY_DYNAMIC), \ - (BIT_LOOK_UP_SIZE+MERGE_GAIN_LOOK_UP_SIZE))) ) - -#define P_BUF_0 ( 0 ) -#define P_BUF_1 ( P_BUF_0 + BUF_SIZE_0 ) +#define BUF_SIZE_0 (ALIGN_SIZE(sizeof(QC_OUT_CHANNEL) * (8))) +#define BUF_SIZE_1 \ + (ALIGN_SIZE(maxSize(maxSize(sizeof(PSY_DYNAMIC), \ + (BIT_LOOK_UP_SIZE + MERGE_GAIN_LOOK_UP_SIZE)), \ + ADJ_THR_SIZE))) -#define AAC_ENC_DYN_RAM_SIZE ( BUF_SIZE_0 + BUF_SIZE_1 ) +#define P_BUF_0 (0) +#define P_BUF_1 (P_BUF_0 + BUF_SIZE_0) +#define AAC_ENC_DYN_RAM_SIZE (BUF_SIZE_0 + BUF_SIZE_1) - H_ALLOC_MEM (AACdynamic_RAM, FIXP_DBL) +H_ALLOC_MEM(AACdynamic_RAM, FIXP_DBL) /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ END - Dynamic RAM - Allocation */ @@ -191,36 +217,33 @@ END - Dynamic RAM - Allocation */ /* See further Memory Allocation details in aacEnc_ram.cpp */ - H_ALLOC_MEM (Ram_aacEnc_AacEncoder, AAC_ENC) - - H_ALLOC_MEM (Ram_aacEnc_PsyElement, PSY_ELEMENT) - - H_ALLOC_MEM (Ram_aacEnc_PsyInternal, PSY_INTERNAL) - H_ALLOC_MEM (Ram_aacEnc_PsyStatic, PSY_STATIC) - H_ALLOC_MEM (Ram_aacEnc_PsyInputBuffer, INT_PCM) +H_ALLOC_MEM(Ram_aacEnc_AacEncoder, AAC_ENC) - PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic (int n, UCHAR* dynamic_RAM); - H_ALLOC_MEM (Ram_bsOutbuffer, UCHAR) +H_ALLOC_MEM(Ram_aacEnc_PsyElement, PSY_ELEMENT) - H_ALLOC_MEM (Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL) +H_ALLOC_MEM(Ram_aacEnc_PsyInternal, PSY_INTERNAL) +H_ALLOC_MEM(Ram_aacEnc_PsyStatic, PSY_STATIC) +H_ALLOC_MEM(Ram_aacEnc_PsyInputBuffer, INT_PCM) - H_ALLOC_MEM (Ram_aacEnc_PsyOut, PSY_OUT) - H_ALLOC_MEM (Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT) +PSY_DYNAMIC *GetRam_aacEnc_PsyDynamic(int n, UCHAR *dynamic_RAM); - H_ALLOC_MEM (Ram_aacEnc_QCstate, QC_STATE) - H_ALLOC_MEM (Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE) +H_ALLOC_MEM(Ram_aacEnc_PsyOutChannel, PSY_OUT_CHANNEL) - H_ALLOC_MEM (Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT) - H_ALLOC_MEM (Ram_aacEnc_ElementBits, ELEMENT_BITS) - H_ALLOC_MEM (Ram_aacEnc_BitCntrState, BITCNTR_STATE) +H_ALLOC_MEM(Ram_aacEnc_PsyOut, PSY_OUT) +H_ALLOC_MEM(Ram_aacEnc_PsyOutElements, PSY_OUT_ELEMENT) - INT *GetRam_aacEnc_BitLookUp(int n, UCHAR* dynamic_RAM); - INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR* dynamic_RAM); - QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel (int n, UCHAR* dynamic_RAM); +H_ALLOC_MEM(Ram_aacEnc_QCstate, QC_STATE) +H_ALLOC_MEM(Ram_aacEnc_AdjustThreshold, ADJ_THR_STATE) - H_ALLOC_MEM (Ram_aacEnc_QCout, QC_OUT) - H_ALLOC_MEM (Ram_aacEnc_QCelement, QC_OUT_ELEMENT) +H_ALLOC_MEM(Ram_aacEnc_AdjThrStateElement, ATS_ELEMENT) +H_ALLOC_MEM(Ram_aacEnc_ElementBits, ELEMENT_BITS) +H_ALLOC_MEM(Ram_aacEnc_BitCntrState, BITCNTR_STATE) +INT *GetRam_aacEnc_BitLookUp(int n, UCHAR *dynamic_RAM); +INT *GetRam_aacEnc_MergeGainLookUp(int n, UCHAR *dynamic_RAM); +QC_OUT_CHANNEL *GetRam_aacEnc_QCchannel(int n, UCHAR *dynamic_RAM); -#endif /* #ifndef AAC_ENC_RAM_H */ +H_ALLOC_MEM(Ram_aacEnc_QCout, QC_OUT) +H_ALLOC_MEM(Ram_aacEnc_QCelement, QC_OUT_ELEMENT) +#endif /* #ifndef AACENC_RAM_H */ diff --git a/libAACenc/src/aacEnc_rom.cpp b/libAACenc/src/aacEnc_rom.cpp index c6477e3..ac0fa9d 100644 --- a/libAACenc/src/aacEnc_rom.cpp +++ b/libAACenc/src/aacEnc_rom.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,574 +90,723 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: -******************************************************************************/ +*******************************************************************************/ #include "aacEnc_rom.h" /* Huffman Tables */ -const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]= -{ - { - { {0x000b0009,0x00090007,0x000b0009}, {0x000a0008,0x00070006,0x000a0008}, {0x000b0009,0x00090008,0x000b0009} }, - { {0x000a0008,0x00070006,0x000a0007}, {0x00070006,0x00050005,0x00070006}, {0x00090007,0x00070006,0x000a0008} }, - { {0x000b0009,0x00090007,0x000b0008}, {0x00090008,0x00070006,0x00090008}, {0x000b0009,0x00090007,0x000b0009} } - }, - { - { {0x00090008,0x00070006,0x00090007}, {0x00070006,0x00050005,0x00070006}, {0x00090007,0x00070006,0x00090008} }, - { {0x00070006,0x00050005,0x00070006}, {0x00050005,0x00010003,0x00050005}, {0x00070006,0x00050005,0x00070006} }, - { {0x00090008,0x00070006,0x00090007}, {0x00070006,0x00050005,0x00070006}, {0x00090008,0x00070006,0x00090008} } - }, - { - { {0x000b0009,0x00090007,0x000b0009}, {0x00090008,0x00070006,0x00090008}, {0x000b0008,0x00090007,0x000b0009} }, - { {0x000a0008,0x00070006,0x00090007}, {0x00070006,0x00050004,0x00070006}, {0x00090008,0x00070006,0x000a0007} }, - { {0x000b0009,0x00090007,0x000b0009}, {0x000a0007,0x00070006,0x00090008}, {0x000b0009,0x00090007,0x000b0009} } - } -}; - - -const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]= -{ - { - { {0x00010004,0x00040005,0x00080008}, {0x00040005,0x00050004,0x00080008}, {0x00090009,0x00090008,0x000a000b} }, - { {0x00040005,0x00060005,0x00090008}, {0x00060005,0x00060004,0x00090008}, {0x00090008,0x00090007,0x000a000a} }, - { {0x00090009,0x000a0008,0x000d000b}, {0x00090008,0x00090008,0x000b000a}, {0x000b000b,0x000a000a,0x000c000b} } - }, - { - { {0x00040004,0x00060005,0x000a0008}, {0x00060004,0x00070004,0x000a0008}, {0x000a0008,0x000a0008,0x000c000a} }, - { {0x00050004,0x00070004,0x000b0008}, {0x00060004,0x00070004,0x000a0007}, {0x00090008,0x00090007,0x000b0009} }, - { {0x00090008,0x000a0008,0x000d000a}, {0x00080007,0x00090007,0x000c0009}, {0x000a000a,0x000b0009,0x000c000a} } - }, - { - { {0x00080008,0x000a0008,0x000f000b}, {0x00090008,0x000b0007,0x000f000a}, {0x000d000b,0x000e000a,0x0010000c} }, - { {0x00080008,0x000a0007,0x000e000a}, {0x00090007,0x000a0007,0x000e0009}, {0x000c000a,0x000c0009,0x000f000b} }, - { {0x000b000b,0x000c000a,0x0010000c}, {0x000a000a,0x000b0009,0x000f000b}, {0x000c000b,0x000c000a,0x000f000b} } - } -}; - -const ULONG FDKaacEnc_huff_ltab5_6[9][9]= -{ - {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c000a, 0x000d000b}, - {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0008, 0x000b0009, 0x000c000a}, - {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, 0x00090006, 0x000a0008, 0x000b0009}, - {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, 0x00080006, 0x00090007, 0x000b0009}, - {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004, 0x00070006, 0x00080007, 0x000b0009}, - {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, 0x00080006, 0x00090007, 0x000b0009}, - {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, 0x00090006, 0x000a0008, 0x000b0009}, - {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, 0x000a0007, 0x000b0008, 0x000c000a}, - {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, 0x000b0009, 0x000c000a, 0x000d000b} -}; - -const ULONG FDKaacEnc_huff_ltab7_8[8][8]= -{ - {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, 0x000a0009, 0x000b000a}, - {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x00090008}, - {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007, 0x00090007, 0x000a0008}, - {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007, 0x000a0008, 0x000a0008}, - {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007, 0x000a0008, 0x000b0009}, - {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008, 0x000b0008, 0x000b000a}, - {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008, 0x000c0009, 0x000c0009}, - {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c000a} -}; - -const ULONG FDKaacEnc_huff_ltab9_10[13][13]= -{ - {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, 0x000d000c}, - {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, 0x000c000b}, - {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a, 0x000c000a}, - {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007, 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a, 0x000d000a}, - {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007, 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a}, - {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000b}, - {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000d000b}, - {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008, 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b, 0x000d000b}, - {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b, 0x000e000b}, - {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000c}, - {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b, 0x000f000c}, - {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b, 0x000f000c}, - {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c, 0x000f000c} -}; - -const UCHAR FDKaacEnc_huff_ltab11[17][17]= -{ - {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0b, 0x0c, 0x0c, 0x0a}, - {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, - {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, - {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, - {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x08}, - {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x0b, 0x0b, 0x08}, - {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x08}, - {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, - {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x09}, - {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x05} -}; - -const UCHAR FDKaacEnc_huff_ltabscf[121]= -{ - 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x12, 0x13, 0x12, 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, - 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0c, 0x0b, 0x0a, 0x0a, - 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, - 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, - 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f, 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 -}; - - -const USHORT FDKaacEnc_huff_ctab1[3][3][3][3]= -{ - { - { {0x07f8,0x01f1,0x07fd}, {0x03f5,0x0068,0x03f0}, {0x07f7,0x01ec,0x07f5} }, - { {0x03f1,0x0072,0x03f4}, {0x0074,0x0011,0x0076}, {0x01eb,0x006c,0x03f6} }, - { {0x07fc,0x01e1,0x07f1}, {0x01f0,0x0061,0x01f6}, {0x07f2,0x01ea,0x07fb} } - }, - { - { {0x01f2,0x0069,0x01ed}, {0x0077,0x0017,0x006f}, {0x01e6,0x0064,0x01e5} }, - { {0x0067,0x0015,0x0062}, {0x0012,0x0000,0x0014}, {0x0065,0x0016,0x006d} }, - { {0x01e9,0x0063,0x01e4}, {0x006b,0x0013,0x0071}, {0x01e3,0x0070,0x01f3} } - }, - { - { {0x07fe,0x01e7,0x07f3}, {0x01ef,0x0060,0x01ee}, {0x07f0,0x01e2,0x07fa} }, - { {0x03f3,0x006a,0x01e8}, {0x0075,0x0010,0x0073}, {0x01f4,0x006e,0x03f7} }, - { {0x07f6,0x01e0,0x07f9}, {0x03f2,0x0066,0x01f5}, {0x07ff,0x01f7,0x07f4} } - } -}; - -const USHORT FDKaacEnc_huff_ctab2[3][3][3][3]= -{ - { - { {0x01f3,0x006f,0x01fd}, {0x00eb,0x0023,0x00ea}, {0x01f7,0x00e8,0x01fa} }, - { {0x00f2,0x002d,0x0070}, {0x0020,0x0006,0x002b}, {0x006e,0x0028,0x00e9} }, - { {0x01f9,0x0066,0x00f8}, {0x00e7,0x001b,0x00f1}, {0x01f4,0x006b,0x01f5} } - }, - { - { {0x00ec,0x002a,0x006c}, {0x002c,0x000a,0x0027}, {0x0067,0x001a,0x00f5} }, - { {0x0024,0x0008,0x001f}, {0x0009,0x0000,0x0007}, {0x001d,0x000b,0x0030} }, - { {0x00ef,0x001c,0x0064}, {0x001e,0x000c,0x0029}, {0x00f3,0x002f,0x00f0} } - }, - { - { {0x01fc,0x0071,0x01f2}, {0x00f4,0x0021,0x00e6}, {0x00f7,0x0068,0x01f8} }, - { {0x00ee,0x0022,0x0065}, {0x0031,0x0002,0x0026}, {0x00ed,0x0025,0x006a} }, - { {0x01fb,0x0072,0x01fe}, {0x0069,0x002e,0x00f6}, {0x01ff,0x006d,0x01f6} } - } -}; - -const USHORT FDKaacEnc_huff_ctab3[3][3][3][3]= -{ - { - { {0x0000,0x0009,0x00ef}, {0x000b,0x0019,0x00f0}, {0x01eb,0x01e6,0x03f2} }, - { {0x000a,0x0035,0x01ef}, {0x0034,0x0037,0x01e9}, {0x01ed,0x01e7,0x03f3} }, - { {0x01ee,0x03ed,0x1ffa}, {0x01ec,0x01f2,0x07f9}, {0x07f8,0x03f8,0x0ff8} } - }, - { - { {0x0008,0x0038,0x03f6}, {0x0036,0x0075,0x03f1}, {0x03eb,0x03ec,0x0ff4} }, - { {0x0018,0x0076,0x07f4}, {0x0039,0x0074,0x03ef}, {0x01f3,0x01f4,0x07f6} }, - { {0x01e8,0x03ea,0x1ffc}, {0x00f2,0x01f1,0x0ffb}, {0x03f5,0x07f3,0x0ffc} } - }, - { - { {0x00ee,0x03f7,0x7ffe}, {0x01f0,0x07f5,0x7ffd}, {0x1ffb,0x3ffa,0xffff} }, - { {0x00f1,0x03f0,0x3ffc}, {0x01ea,0x03ee,0x3ffb}, {0x0ff6,0x0ffa,0x7ffc} }, - { {0x07f2,0x0ff5,0xfffe}, {0x03f4,0x07f7,0x7ffb}, {0x0ff7,0x0ff9,0x7ffa} } - } -}; - -const USHORT FDKaacEnc_huff_ctab4[3][3][3][3]= -{ - { - { {0x0007,0x0016,0x00f6}, {0x0018,0x0008,0x00ef}, {0x01ef,0x00f3,0x07f8} }, - { {0x0019,0x0017,0x00ed}, {0x0015,0x0001,0x00e2}, {0x00f0,0x0070,0x03f0} }, - { {0x01ee,0x00f1,0x07fa}, {0x00ee,0x00e4,0x03f2}, {0x07f6,0x03ef,0x07fd} } - }, - { - { {0x0005,0x0014,0x00f2}, {0x0009,0x0004,0x00e5}, {0x00f4,0x00e8,0x03f4} }, - { {0x0006,0x0002,0x00e7}, {0x0003,0x0000,0x006b}, {0x00e3,0x0069,0x01f3} }, - { {0x00eb,0x00e6,0x03f6}, {0x006e,0x006a,0x01f4}, {0x03ec,0x01f0,0x03f9} } - }, - { - { {0x00f5,0x00ec,0x07fb}, {0x00ea,0x006f,0x03f7}, {0x07f9,0x03f3,0x0fff} }, - { {0x00e9,0x006d,0x03f8}, {0x006c,0x0068,0x01f5}, {0x03ee,0x01f2,0x07f4} }, - { {0x07f7,0x03f1,0x0ffe}, {0x03ed,0x01f1,0x07f5}, {0x07fe,0x03f5,0x07fc} } - } -}; -const USHORT FDKaacEnc_huff_ctab5[9][9]= -{ - {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd}, - {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa}, - {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3}, - {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed}, - {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9}, - {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec}, - {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7}, - {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9}, - {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe} -}; - -const USHORT FDKaacEnc_huff_ctab6[9][9]= -{ - {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd}, - {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7}, - {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7}, - {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee}, - {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa}, - {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec}, - {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2}, - {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa}, - {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc} -}; - -const USHORT FDKaacEnc_huff_ctab7[8][8]= -{ - {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7}, - {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5}, - {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5}, - {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa}, - {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb}, - {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc}, - {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe}, - {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff} -}; - -const USHORT FDKaacEnc_huff_ctab8[8][8]= -{ - {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe}, - {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8}, - {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5}, - {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa}, - {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9}, - {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc}, - {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd}, - {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff} -}; - -const USHORT FDKaacEnc_huff_ctab9[13][13]= -{ - {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd, 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec}, - {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, 0x03e0, 0x07d8, 0x0fcf, 0x0fd5}, - {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db, 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4}, - {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, 0x07de, 0x0fd8, 0x0fea, 0x1fdb}, - {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1}, - {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0, 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9}, - {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7}, - {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6}, - {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8, 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2}, - {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5}, - {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0, 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc}, - {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe}, - {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff} -}; - -const USHORT FDKaacEnc_huff_ctab10[13][13]= -{ - {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7, 0x03ed, 0x07f0, 0x07f6, 0x0ffd}, - {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc, 0x01d4, 0x03cd, 0x03de, 0x07e7}, - {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9, 0x01ce, 0x01dc, 0x03d9, 0x03f1}, - {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd, 0x01cc, 0x01de, 0x03d3, 0x03e7}, - {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df, 0x01d2, 0x01e2, 0x03dd, 0x03ee}, - {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2, 0x01da, 0x03d4, 0x03e3, 0x07eb}, - {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca, 0x01e0, 0x03db, 0x03e8, 0x07ec}, - {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8, 0x03ca, 0x03da, 0x07ea, 0x07f1}, - {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1, 0x03d5, 0x03f2, 0x07ee, 0x07fb}, - {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0, 0x03ef, 0x07e6, 0x07f8, 0x0ffa}, - {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea, 0x07ed, 0x07f3, 0x07f9, 0x0ff9}, - {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8, 0x07f4, 0x07f5, 0x07f7, 0x0ffb}, - {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef, 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff} -}; - -const USHORT FDKaacEnc_huff_ctab11[21][17]= -{ - {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2, 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e}, - {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191, 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae}, - {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8, 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d}, - {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be, 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094}, - {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3, 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093}, - {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194, 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f}, - {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f, 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8}, - {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4, 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad}, - {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1, 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4}, - {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b, 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7}, - {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a, 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba}, - {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0, 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1}, - {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8, 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190}, - {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1, 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195}, - {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3, 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193}, - {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3, 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d}, - {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2, 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004}, - {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9, 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015}, - {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a, 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032}, - {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029, 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041}, - {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021} -}; - -const ULONG FDKaacEnc_huff_ctabscf[121]= -{ - 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, 0x0007ffed, 0x0007fff6, - 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, - 0x0007fff8, 0x0007fffb, 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0, - 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1, 0x00007ff6, 0x00007ff7, - 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3, 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, - 0x00000ff9, 0x00000ff7, 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7, - 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6, 0x00000079, 0x0000003a, - 0x00000038, 0x0000001a, 0x0000000b, 0x00000004, 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, - 0x00000039, 0x0000003b, 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9, - 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6, 0x000007f7, 0x00000ff5, - 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8, 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, - 0x0000fff6, 0x00007ff5, 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd, - 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5, 0x0007ffd6, 0x0007fff2, - 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9, 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, - 0x0007ffe1, 0x0007ffe2, 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4, - 0x0007fff3 -}; +const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3] = { + {{{0x000b0009, 0x00090007, 0x000b0009}, + {0x000a0008, 0x00070006, 0x000a0008}, + {0x000b0009, 0x00090008, 0x000b0009}}, + {{0x000a0008, 0x00070006, 0x000a0007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090007, 0x00070006, 0x000a0008}}, + {{0x000b0009, 0x00090007, 0x000b0008}, + {0x00090008, 0x00070006, 0x00090008}, + {0x000b0009, 0x00090007, 0x000b0009}}}, + {{{0x00090008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090007, 0x00070006, 0x00090008}}, + {{0x00070006, 0x00050005, 0x00070006}, + {0x00050005, 0x00010003, 0x00050005}, + {0x00070006, 0x00050005, 0x00070006}}, + {{0x00090008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050005, 0x00070006}, + {0x00090008, 0x00070006, 0x00090008}}}, + {{{0x000b0009, 0x00090007, 0x000b0009}, + {0x00090008, 0x00070006, 0x00090008}, + {0x000b0008, 0x00090007, 0x000b0009}}, + {{0x000a0008, 0x00070006, 0x00090007}, + {0x00070006, 0x00050004, 0x00070006}, + {0x00090008, 0x00070006, 0x000a0007}}, + {{0x000b0009, 0x00090007, 0x000b0009}, + {0x000a0007, 0x00070006, 0x00090008}, + {0x000b0009, 0x00090007, 0x000b0009}}}}; + +const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3] = { + {{{0x00010004, 0x00040005, 0x00080008}, + {0x00040005, 0x00050004, 0x00080008}, + {0x00090009, 0x00090008, 0x000a000b}}, + {{0x00040005, 0x00060005, 0x00090008}, + {0x00060005, 0x00060004, 0x00090008}, + {0x00090008, 0x00090007, 0x000a000a}}, + {{0x00090009, 0x000a0008, 0x000d000b}, + {0x00090008, 0x00090008, 0x000b000a}, + {0x000b000b, 0x000a000a, 0x000c000b}}}, + {{{0x00040004, 0x00060005, 0x000a0008}, + {0x00060004, 0x00070004, 0x000a0008}, + {0x000a0008, 0x000a0008, 0x000c000a}}, + {{0x00050004, 0x00070004, 0x000b0008}, + {0x00060004, 0x00070004, 0x000a0007}, + {0x00090008, 0x00090007, 0x000b0009}}, + {{0x00090008, 0x000a0008, 0x000d000a}, + {0x00080007, 0x00090007, 0x000c0009}, + {0x000a000a, 0x000b0009, 0x000c000a}}}, + {{{0x00080008, 0x000a0008, 0x000f000b}, + {0x00090008, 0x000b0007, 0x000f000a}, + {0x000d000b, 0x000e000a, 0x0010000c}}, + {{0x00080008, 0x000a0007, 0x000e000a}, + {0x00090007, 0x000a0007, 0x000e0009}, + {0x000c000a, 0x000c0009, 0x000f000b}}, + {{0x000b000b, 0x000c000a, 0x0010000c}, + {0x000a000a, 0x000b0009, 0x000f000b}, + {0x000c000b, 0x000c000a, 0x000f000b}}}}; + +const ULONG FDKaacEnc_huff_ltab5_6[9][9] = { + {0x000d000b, 0x000c000a, 0x000b0009, 0x000b0009, 0x000a0009, 0x000b0009, + 0x000b0009, 0x000c000a, 0x000d000b}, + {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, + 0x000a0008, 0x000b0009, 0x000c000a}, + {0x000c0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, + 0x00090006, 0x000a0008, 0x000b0009}, + {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, + 0x00080006, 0x00090007, 0x000b0009}, + {0x000a0009, 0x00080007, 0x00070006, 0x00040004, 0x00010004, 0x00040004, + 0x00070006, 0x00080007, 0x000b0009}, + {0x000b0009, 0x00090007, 0x00080006, 0x00050004, 0x00040004, 0x00050004, + 0x00080006, 0x00090007, 0x000b0009}, + {0x000b0009, 0x000a0008, 0x00090006, 0x00080006, 0x00070006, 0x00080006, + 0x00090006, 0x000a0008, 0x000b0009}, + {0x000c000a, 0x000b0009, 0x000a0008, 0x00090007, 0x00080007, 0x00090007, + 0x000a0007, 0x000b0008, 0x000c000a}, + {0x000d000b, 0x000c000a, 0x000c0009, 0x000b0009, 0x000a0009, 0x000a0009, + 0x000b0009, 0x000c000a, 0x000d000b}}; + +const ULONG FDKaacEnc_huff_ltab7_8[8][8] = { + {0x00010005, 0x00030004, 0x00060005, 0x00070006, 0x00080007, 0x00090008, + 0x000a0009, 0x000b000a}, + {0x00030004, 0x00040003, 0x00060004, 0x00070005, 0x00080006, 0x00080007, + 0x00090007, 0x00090008}, + {0x00060005, 0x00060004, 0x00070004, 0x00080005, 0x00080006, 0x00090007, + 0x00090007, 0x000a0008}, + {0x00070006, 0x00070005, 0x00080005, 0x00080006, 0x00090006, 0x00090007, + 0x000a0008, 0x000a0008}, + {0x00080007, 0x00080006, 0x00090006, 0x00090006, 0x000a0007, 0x000a0007, + 0x000a0008, 0x000b0009}, + {0x00090008, 0x00080007, 0x00090006, 0x00090007, 0x000a0007, 0x000a0008, + 0x000b0008, 0x000b000a}, + {0x000a0009, 0x00090007, 0x00090007, 0x000a0008, 0x000a0008, 0x000b0008, + 0x000c0009, 0x000c0009}, + {0x000b000a, 0x000a0008, 0x000a0008, 0x000a0008, 0x000b0009, 0x000b0009, + 0x000c0009, 0x000c000a}}; + +const ULONG FDKaacEnc_huff_ltab9_10[13][13] = { + {0x00010006, 0x00030005, 0x00060006, 0x00080006, 0x00090007, 0x000a0008, + 0x000a0009, 0x000b000a, 0x000b000a, 0x000c000a, 0x000c000b, 0x000d000b, + 0x000d000c}, + {0x00030005, 0x00040004, 0x00060004, 0x00070005, 0x00080006, 0x00080007, + 0x00090007, 0x000a0008, 0x000a0008, 0x000a0009, 0x000b000a, 0x000c000a, + 0x000c000b}, + {0x00060006, 0x00060004, 0x00070005, 0x00080005, 0x00080006, 0x00090006, + 0x000a0007, 0x000a0008, 0x000a0008, 0x000b0009, 0x000c0009, 0x000c000a, + 0x000c000a}, + {0x00080006, 0x00070005, 0x00080005, 0x00090005, 0x00090006, 0x000a0007, + 0x000a0007, 0x000b0008, 0x000b0008, 0x000b0009, 0x000c0009, 0x000c000a, + 0x000d000a}, + {0x00090007, 0x00080006, 0x00090006, 0x00090006, 0x000a0006, 0x000a0007, + 0x000b0007, 0x000b0008, 0x000b0008, 0x000c0009, 0x000c0009, 0x000c000a, + 0x000d000a}, + {0x000a0008, 0x00090007, 0x00090006, 0x000a0007, 0x000b0007, 0x000b0007, + 0x000b0008, 0x000c0008, 0x000b0008, 0x000c0009, 0x000c000a, 0x000d000a, + 0x000d000b}, + {0x000b0009, 0x00090007, 0x000a0007, 0x000b0007, 0x000b0007, 0x000b0008, + 0x000c0008, 0x000c0009, 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, + 0x000d000b}, + {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000c0008, + 0x000c0009, 0x000d0009, 0x000d0009, 0x000d000a, 0x000d000a, 0x000d000b, + 0x000d000b}, + {0x000b0009, 0x000a0008, 0x000a0008, 0x000b0008, 0x000b0008, 0x000b0008, + 0x000c0009, 0x000c0009, 0x000d000a, 0x000d000a, 0x000e000a, 0x000d000b, + 0x000e000b}, + {0x000b000a, 0x000a0009, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, + 0x000c0009, 0x000c000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, + 0x000e000c}, + {0x000c000a, 0x000b0009, 0x000b0009, 0x000c0009, 0x000c0009, 0x000c000a, + 0x000d000a, 0x000d000a, 0x000d000a, 0x000e000b, 0x000e000b, 0x000e000b, + 0x000f000c}, + {0x000c000b, 0x000b000a, 0x000c0009, 0x000c000a, 0x000c000a, 0x000d000a, + 0x000d000a, 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000b, 0x000f000b, + 0x000f000c}, + {0x000d000b, 0x000c000a, 0x000c000a, 0x000c000a, 0x000d000a, 0x000d000a, + 0x000d000a, 0x000d000b, 0x000e000b, 0x000e000c, 0x000e000c, 0x000e000c, + 0x000f000c}}; + +const UCHAR FDKaacEnc_huff_ltab11[17][17] = { + {0x04, 0x05, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0b, 0x0c, 0x0c, 0x0a}, + {0x05, 0x04, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, + {0x06, 0x05, 0x05, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x07, 0x06, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x08, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x08}, + {0x0a, 0x09, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0b, 0x08}, + {0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0b, 0x0b, 0x08}, + {0x0b, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0b, 0x0a, 0x0b, 0x0b, 0x08}, + {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x08}, + {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0b, 0x0a, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x09}, + {0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0c, 0x09}, + {0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x09, 0x05}}; + +const UCHAR FDKaacEnc_huff_ltabscf[121] = { + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x12, 0x13, 0x12, + 0x11, 0x11, 0x10, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0e, + 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, + 0x0c, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x07, + 0x06, 0x06, 0x05, 0x04, 0x03, 0x01, 0x04, 0x04, 0x05, 0x06, 0x06, + 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x10, 0x0f, + 0x10, 0x0f, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13}; + +const USHORT FDKaacEnc_huff_ctab1[3][3][3][3] = {{{{0x07f8, 0x01f1, 0x07fd}, + {0x03f5, 0x0068, 0x03f0}, + {0x07f7, 0x01ec, 0x07f5}}, + {{0x03f1, 0x0072, 0x03f4}, + {0x0074, 0x0011, 0x0076}, + {0x01eb, 0x006c, 0x03f6}}, + {{0x07fc, 0x01e1, 0x07f1}, + {0x01f0, 0x0061, 0x01f6}, + {0x07f2, 0x01ea, 0x07fb}}}, + {{{0x01f2, 0x0069, 0x01ed}, + {0x0077, 0x0017, 0x006f}, + {0x01e6, 0x0064, 0x01e5}}, + {{0x0067, 0x0015, 0x0062}, + {0x0012, 0x0000, 0x0014}, + {0x0065, 0x0016, 0x006d}}, + {{0x01e9, 0x0063, 0x01e4}, + {0x006b, 0x0013, 0x0071}, + {0x01e3, 0x0070, 0x01f3}}}, + {{{0x07fe, 0x01e7, 0x07f3}, + {0x01ef, 0x0060, 0x01ee}, + {0x07f0, 0x01e2, 0x07fa}}, + {{0x03f3, 0x006a, 0x01e8}, + {0x0075, 0x0010, 0x0073}, + {0x01f4, 0x006e, 0x03f7}}, + {{0x07f6, 0x01e0, 0x07f9}, + {0x03f2, 0x0066, 0x01f5}, + {0x07ff, 0x01f7, 0x07f4}}}}; + +const USHORT FDKaacEnc_huff_ctab2[3][3][3][3] = {{{{0x01f3, 0x006f, 0x01fd}, + {0x00eb, 0x0023, 0x00ea}, + {0x01f7, 0x00e8, 0x01fa}}, + {{0x00f2, 0x002d, 0x0070}, + {0x0020, 0x0006, 0x002b}, + {0x006e, 0x0028, 0x00e9}}, + {{0x01f9, 0x0066, 0x00f8}, + {0x00e7, 0x001b, 0x00f1}, + {0x01f4, 0x006b, 0x01f5}}}, + {{{0x00ec, 0x002a, 0x006c}, + {0x002c, 0x000a, 0x0027}, + {0x0067, 0x001a, 0x00f5}}, + {{0x0024, 0x0008, 0x001f}, + {0x0009, 0x0000, 0x0007}, + {0x001d, 0x000b, 0x0030}}, + {{0x00ef, 0x001c, 0x0064}, + {0x001e, 0x000c, 0x0029}, + {0x00f3, 0x002f, 0x00f0}}}, + {{{0x01fc, 0x0071, 0x01f2}, + {0x00f4, 0x0021, 0x00e6}, + {0x00f7, 0x0068, 0x01f8}}, + {{0x00ee, 0x0022, 0x0065}, + {0x0031, 0x0002, 0x0026}, + {0x00ed, 0x0025, 0x006a}}, + {{0x01fb, 0x0072, 0x01fe}, + {0x0069, 0x002e, 0x00f6}, + {0x01ff, 0x006d, 0x01f6}}}}; + +const USHORT FDKaacEnc_huff_ctab3[3][3][3][3] = {{{{0x0000, 0x0009, 0x00ef}, + {0x000b, 0x0019, 0x00f0}, + {0x01eb, 0x01e6, 0x03f2}}, + {{0x000a, 0x0035, 0x01ef}, + {0x0034, 0x0037, 0x01e9}, + {0x01ed, 0x01e7, 0x03f3}}, + {{0x01ee, 0x03ed, 0x1ffa}, + {0x01ec, 0x01f2, 0x07f9}, + {0x07f8, 0x03f8, 0x0ff8}}}, + {{{0x0008, 0x0038, 0x03f6}, + {0x0036, 0x0075, 0x03f1}, + {0x03eb, 0x03ec, 0x0ff4}}, + {{0x0018, 0x0076, 0x07f4}, + {0x0039, 0x0074, 0x03ef}, + {0x01f3, 0x01f4, 0x07f6}}, + {{0x01e8, 0x03ea, 0x1ffc}, + {0x00f2, 0x01f1, 0x0ffb}, + {0x03f5, 0x07f3, 0x0ffc}}}, + {{{0x00ee, 0x03f7, 0x7ffe}, + {0x01f0, 0x07f5, 0x7ffd}, + {0x1ffb, 0x3ffa, 0xffff}}, + {{0x00f1, 0x03f0, 0x3ffc}, + {0x01ea, 0x03ee, 0x3ffb}, + {0x0ff6, 0x0ffa, 0x7ffc}}, + {{0x07f2, 0x0ff5, 0xfffe}, + {0x03f4, 0x07f7, 0x7ffb}, + {0x0ff7, 0x0ff9, 0x7ffa}}}}; + +const USHORT FDKaacEnc_huff_ctab4[3][3][3][3] = {{{{0x0007, 0x0016, 0x00f6}, + {0x0018, 0x0008, 0x00ef}, + {0x01ef, 0x00f3, 0x07f8}}, + {{0x0019, 0x0017, 0x00ed}, + {0x0015, 0x0001, 0x00e2}, + {0x00f0, 0x0070, 0x03f0}}, + {{0x01ee, 0x00f1, 0x07fa}, + {0x00ee, 0x00e4, 0x03f2}, + {0x07f6, 0x03ef, 0x07fd}}}, + {{{0x0005, 0x0014, 0x00f2}, + {0x0009, 0x0004, 0x00e5}, + {0x00f4, 0x00e8, 0x03f4}}, + {{0x0006, 0x0002, 0x00e7}, + {0x0003, 0x0000, 0x006b}, + {0x00e3, 0x0069, 0x01f3}}, + {{0x00eb, 0x00e6, 0x03f6}, + {0x006e, 0x006a, 0x01f4}, + {0x03ec, 0x01f0, 0x03f9}}}, + {{{0x00f5, 0x00ec, 0x07fb}, + {0x00ea, 0x006f, 0x03f7}, + {0x07f9, 0x03f3, 0x0fff}}, + {{0x00e9, 0x006d, 0x03f8}, + {0x006c, 0x0068, 0x01f5}, + {0x03ee, 0x01f2, 0x07f4}}, + {{0x07f7, 0x03f1, 0x0ffe}, + {0x03ed, 0x01f1, 0x07f5}, + {0x07fe, 0x03f5, 0x07fc}}}}; + +const USHORT FDKaacEnc_huff_ctab5[9][9] = { + {0x1fff, 0x0ff7, 0x07f4, 0x07e8, 0x03f1, 0x07ee, 0x07f9, 0x0ff8, 0x1ffd}, + {0x0ffd, 0x07f1, 0x03e8, 0x01e8, 0x00f0, 0x01ec, 0x03ee, 0x07f2, 0x0ffa}, + {0x0ff4, 0x03ef, 0x01f2, 0x00e8, 0x0070, 0x00ec, 0x01f0, 0x03ea, 0x07f3}, + {0x07eb, 0x01eb, 0x00ea, 0x001a, 0x0008, 0x0019, 0x00ee, 0x01ef, 0x07ed}, + {0x03f0, 0x00f2, 0x0073, 0x000b, 0x0000, 0x000a, 0x0071, 0x00f3, 0x07e9}, + {0x07ef, 0x01ee, 0x00ef, 0x0018, 0x0009, 0x001b, 0x00eb, 0x01e9, 0x07ec}, + {0x07f6, 0x03eb, 0x01f3, 0x00ed, 0x0072, 0x00e9, 0x01f1, 0x03ed, 0x07f7}, + {0x0ff6, 0x07f0, 0x03e9, 0x01ed, 0x00f1, 0x01ea, 0x03ec, 0x07f8, 0x0ff9}, + {0x1ffc, 0x0ffc, 0x0ff5, 0x07ea, 0x03f3, 0x03f2, 0x07f5, 0x0ffb, 0x1ffe}}; + +const USHORT FDKaacEnc_huff_ctab6[9][9] = { + {0x07fe, 0x03fd, 0x01f1, 0x01eb, 0x01f4, 0x01ea, 0x01f0, 0x03fc, 0x07fd}, + {0x03f6, 0x01e5, 0x00ea, 0x006c, 0x0071, 0x0068, 0x00f0, 0x01e6, 0x03f7}, + {0x01f3, 0x00ef, 0x0032, 0x0027, 0x0028, 0x0026, 0x0031, 0x00eb, 0x01f7}, + {0x01e8, 0x006f, 0x002e, 0x0008, 0x0004, 0x0006, 0x0029, 0x006b, 0x01ee}, + {0x01ef, 0x0072, 0x002d, 0x0002, 0x0000, 0x0003, 0x002f, 0x0073, 0x01fa}, + {0x01e7, 0x006e, 0x002b, 0x0007, 0x0001, 0x0005, 0x002c, 0x006d, 0x01ec}, + {0x01f9, 0x00ee, 0x0030, 0x0024, 0x002a, 0x0025, 0x0033, 0x00ec, 0x01f2}, + {0x03f8, 0x01e4, 0x00ed, 0x006a, 0x0070, 0x0069, 0x0074, 0x00f1, 0x03fa}, + {0x07ff, 0x03f9, 0x01f6, 0x01ed, 0x01f8, 0x01e9, 0x01f5, 0x03fb, 0x07fc}}; + +const USHORT FDKaacEnc_huff_ctab7[8][8] = { + {0x0000, 0x0005, 0x0037, 0x0074, 0x00f2, 0x01eb, 0x03ed, 0x07f7}, + {0x0004, 0x000c, 0x0035, 0x0071, 0x00ec, 0x00ee, 0x01ee, 0x01f5}, + {0x0036, 0x0034, 0x0072, 0x00ea, 0x00f1, 0x01e9, 0x01f3, 0x03f5}, + {0x0073, 0x0070, 0x00eb, 0x00f0, 0x01f1, 0x01f0, 0x03ec, 0x03fa}, + {0x00f3, 0x00ed, 0x01e8, 0x01ef, 0x03ef, 0x03f1, 0x03f9, 0x07fb}, + {0x01ed, 0x00ef, 0x01ea, 0x01f2, 0x03f3, 0x03f8, 0x07f9, 0x07fc}, + {0x03ee, 0x01ec, 0x01f4, 0x03f4, 0x03f7, 0x07f8, 0x0ffd, 0x0ffe}, + {0x07f6, 0x03f0, 0x03f2, 0x03f6, 0x07fa, 0x07fd, 0x0ffc, 0x0fff}}; + +const USHORT FDKaacEnc_huff_ctab8[8][8] = { + {0x000e, 0x0005, 0x0010, 0x0030, 0x006f, 0x00f1, 0x01fa, 0x03fe}, + {0x0003, 0x0000, 0x0004, 0x0012, 0x002c, 0x006a, 0x0075, 0x00f8}, + {0x000f, 0x0002, 0x0006, 0x0014, 0x002e, 0x0069, 0x0072, 0x00f5}, + {0x002f, 0x0011, 0x0013, 0x002a, 0x0032, 0x006c, 0x00ec, 0x00fa}, + {0x0071, 0x002b, 0x002d, 0x0031, 0x006d, 0x0070, 0x00f2, 0x01f9}, + {0x00ef, 0x0068, 0x0033, 0x006b, 0x006e, 0x00ee, 0x00f9, 0x03fc}, + {0x01f8, 0x0074, 0x0073, 0x00ed, 0x00f0, 0x00f6, 0x01f6, 0x01fd}, + {0x03fd, 0x00f3, 0x00f4, 0x00f7, 0x01f7, 0x01fb, 0x01fc, 0x03ff}}; + +const USHORT FDKaacEnc_huff_ctab9[13][13] = { + {0x0000, 0x0005, 0x0037, 0x00e7, 0x01de, 0x03ce, 0x03d9, 0x07c8, 0x07cd, + 0x0fc8, 0x0fdd, 0x1fe4, 0x1fec}, + {0x0004, 0x000c, 0x0035, 0x0072, 0x00ea, 0x00ed, 0x01e2, 0x03d1, 0x03d3, + 0x03e0, 0x07d8, 0x0fcf, 0x0fd5}, + {0x0036, 0x0034, 0x0071, 0x00e8, 0x00ec, 0x01e1, 0x03cf, 0x03dd, 0x03db, + 0x07d0, 0x0fc7, 0x0fd4, 0x0fe4}, + {0x00e6, 0x0070, 0x00e9, 0x01dd, 0x01e3, 0x03d2, 0x03dc, 0x07cc, 0x07ca, + 0x07de, 0x0fd8, 0x0fea, 0x1fdb}, + {0x01df, 0x00eb, 0x01dc, 0x01e6, 0x03d5, 0x03de, 0x07cb, 0x07dd, 0x07dc, + 0x0fcd, 0x0fe2, 0x0fe7, 0x1fe1}, + {0x03d0, 0x01e0, 0x01e4, 0x03d6, 0x07c5, 0x07d1, 0x07db, 0x0fd2, 0x07e0, + 0x0fd9, 0x0feb, 0x1fe3, 0x1fe9}, + {0x07c4, 0x01e5, 0x03d7, 0x07c6, 0x07cf, 0x07da, 0x0fcb, 0x0fda, 0x0fe3, + 0x0fe9, 0x1fe6, 0x1ff3, 0x1ff7}, + {0x07d3, 0x03d8, 0x03e1, 0x07d4, 0x07d9, 0x0fd3, 0x0fde, 0x1fdd, 0x1fd9, + 0x1fe2, 0x1fea, 0x1ff1, 0x1ff6}, + {0x07d2, 0x03d4, 0x03da, 0x07c7, 0x07d7, 0x07e2, 0x0fce, 0x0fdb, 0x1fd8, + 0x1fee, 0x3ff0, 0x1ff4, 0x3ff2}, + {0x07e1, 0x03df, 0x07c9, 0x07d6, 0x0fca, 0x0fd0, 0x0fe5, 0x0fe6, 0x1feb, + 0x1fef, 0x3ff3, 0x3ff4, 0x3ff5}, + {0x0fe0, 0x07ce, 0x07d5, 0x0fc6, 0x0fd1, 0x0fe1, 0x1fe0, 0x1fe8, 0x1ff0, + 0x3ff1, 0x3ff8, 0x3ff6, 0x7ffc}, + {0x0fe8, 0x07df, 0x0fc9, 0x0fd7, 0x0fdc, 0x1fdc, 0x1fdf, 0x1fed, 0x1ff5, + 0x3ff9, 0x3ffb, 0x7ffd, 0x7ffe}, + {0x1fe7, 0x0fcc, 0x0fd6, 0x0fdf, 0x1fde, 0x1fda, 0x1fe5, 0x1ff2, 0x3ffa, + 0x3ff7, 0x3ffc, 0x3ffd, 0x7fff}}; + +const USHORT FDKaacEnc_huff_ctab10[13][13] = { + {0x0022, 0x0008, 0x001d, 0x0026, 0x005f, 0x00d3, 0x01cf, 0x03d0, 0x03d7, + 0x03ed, 0x07f0, 0x07f6, 0x0ffd}, + {0x0007, 0x0000, 0x0001, 0x0009, 0x0020, 0x0054, 0x0060, 0x00d5, 0x00dc, + 0x01d4, 0x03cd, 0x03de, 0x07e7}, + {0x001c, 0x0002, 0x0006, 0x000c, 0x001e, 0x0028, 0x005b, 0x00cd, 0x00d9, + 0x01ce, 0x01dc, 0x03d9, 0x03f1}, + {0x0025, 0x000b, 0x000a, 0x000d, 0x0024, 0x0057, 0x0061, 0x00cc, 0x00dd, + 0x01cc, 0x01de, 0x03d3, 0x03e7}, + {0x005d, 0x0021, 0x001f, 0x0023, 0x0027, 0x0059, 0x0064, 0x00d8, 0x00df, + 0x01d2, 0x01e2, 0x03dd, 0x03ee}, + {0x00d1, 0x0055, 0x0029, 0x0056, 0x0058, 0x0062, 0x00ce, 0x00e0, 0x00e2, + 0x01da, 0x03d4, 0x03e3, 0x07eb}, + {0x01c9, 0x005e, 0x005a, 0x005c, 0x0063, 0x00ca, 0x00da, 0x01c7, 0x01ca, + 0x01e0, 0x03db, 0x03e8, 0x07ec}, + {0x01e3, 0x00d2, 0x00cb, 0x00d0, 0x00d7, 0x00db, 0x01c6, 0x01d5, 0x01d8, + 0x03ca, 0x03da, 0x07ea, 0x07f1}, + {0x01e1, 0x00d4, 0x00cf, 0x00d6, 0x00de, 0x00e1, 0x01d0, 0x01d6, 0x03d1, + 0x03d5, 0x03f2, 0x07ee, 0x07fb}, + {0x03e9, 0x01cd, 0x01c8, 0x01cb, 0x01d1, 0x01d7, 0x01df, 0x03cf, 0x03e0, + 0x03ef, 0x07e6, 0x07f8, 0x0ffa}, + {0x03eb, 0x01dd, 0x01d3, 0x01d9, 0x01db, 0x03d2, 0x03cc, 0x03dc, 0x03ea, + 0x07ed, 0x07f3, 0x07f9, 0x0ff9}, + {0x07f2, 0x03ce, 0x01e4, 0x03cb, 0x03d8, 0x03d6, 0x03e2, 0x03e5, 0x07e8, + 0x07f4, 0x07f5, 0x07f7, 0x0ffb}, + {0x07fa, 0x03ec, 0x03df, 0x03e1, 0x03e4, 0x03e6, 0x03f0, 0x07e9, 0x07ef, + 0x0ff8, 0x0ffe, 0x0ffc, 0x0fff}}; + +const USHORT FDKaacEnc_huff_ctab11[21][17] = { + {0x0000, 0x0006, 0x0019, 0x003d, 0x009c, 0x00c6, 0x01a7, 0x0390, 0x03c2, + 0x03df, 0x07e6, 0x07f3, 0x0ffb, 0x07ec, 0x0ffa, 0x0ffe, 0x038e}, + {0x0005, 0x0001, 0x0008, 0x0014, 0x0037, 0x0042, 0x0092, 0x00af, 0x0191, + 0x01a5, 0x01b5, 0x039e, 0x03c0, 0x03a2, 0x03cd, 0x07d6, 0x00ae}, + {0x0017, 0x0007, 0x0009, 0x0018, 0x0039, 0x0040, 0x008e, 0x00a3, 0x00b8, + 0x0199, 0x01ac, 0x01c1, 0x03b1, 0x0396, 0x03be, 0x03ca, 0x009d}, + {0x003c, 0x0015, 0x0016, 0x001a, 0x003b, 0x0044, 0x0091, 0x00a5, 0x00be, + 0x0196, 0x01ae, 0x01b9, 0x03a1, 0x0391, 0x03a5, 0x03d5, 0x0094}, + {0x009a, 0x0036, 0x0038, 0x003a, 0x0041, 0x008c, 0x009b, 0x00b0, 0x00c3, + 0x019e, 0x01ab, 0x01bc, 0x039f, 0x038f, 0x03a9, 0x03cf, 0x0093}, + {0x00bf, 0x003e, 0x003f, 0x0043, 0x0045, 0x009e, 0x00a7, 0x00b9, 0x0194, + 0x01a2, 0x01ba, 0x01c3, 0x03a6, 0x03a7, 0x03bb, 0x03d4, 0x009f}, + {0x01a0, 0x008f, 0x008d, 0x0090, 0x0098, 0x00a6, 0x00b6, 0x00c4, 0x019f, + 0x01af, 0x01bf, 0x0399, 0x03bf, 0x03b4, 0x03c9, 0x03e7, 0x00a8}, + {0x01b6, 0x00ab, 0x00a4, 0x00aa, 0x00b2, 0x00c2, 0x00c5, 0x0198, 0x01a4, + 0x01b8, 0x038c, 0x03a4, 0x03c4, 0x03c6, 0x03dd, 0x03e8, 0x00ad}, + {0x03af, 0x0192, 0x00bd, 0x00bc, 0x018e, 0x0197, 0x019a, 0x01a3, 0x01b1, + 0x038d, 0x0398, 0x03b7, 0x03d3, 0x03d1, 0x03db, 0x07dd, 0x00b4}, + {0x03de, 0x01a9, 0x019b, 0x019c, 0x01a1, 0x01aa, 0x01ad, 0x01b3, 0x038b, + 0x03b2, 0x03b8, 0x03ce, 0x03e1, 0x03e0, 0x07d2, 0x07e5, 0x00b7}, + {0x07e3, 0x01bb, 0x01a8, 0x01a6, 0x01b0, 0x01b2, 0x01b7, 0x039b, 0x039a, + 0x03ba, 0x03b5, 0x03d6, 0x07d7, 0x03e4, 0x07d8, 0x07ea, 0x00ba}, + {0x07e8, 0x03a0, 0x01bd, 0x01b4, 0x038a, 0x01c4, 0x0392, 0x03aa, 0x03b0, + 0x03bc, 0x03d7, 0x07d4, 0x07dc, 0x07db, 0x07d5, 0x07f0, 0x00c1}, + {0x07fb, 0x03c8, 0x03a3, 0x0395, 0x039d, 0x03ac, 0x03ae, 0x03c5, 0x03d8, + 0x03e2, 0x03e6, 0x07e4, 0x07e7, 0x07e0, 0x07e9, 0x07f7, 0x0190}, + {0x07f2, 0x0393, 0x01be, 0x01c0, 0x0394, 0x0397, 0x03ad, 0x03c3, 0x03c1, + 0x03d2, 0x07da, 0x07d9, 0x07df, 0x07eb, 0x07f4, 0x07fa, 0x0195}, + {0x07f8, 0x03bd, 0x039c, 0x03ab, 0x03a8, 0x03b3, 0x03b9, 0x03d0, 0x03e3, + 0x03e5, 0x07e2, 0x07de, 0x07ed, 0x07f1, 0x07f9, 0x07fc, 0x0193}, + {0x0ffd, 0x03dc, 0x03b6, 0x03c7, 0x03cc, 0x03cb, 0x03d9, 0x03da, 0x07d3, + 0x07e1, 0x07ee, 0x07ef, 0x07f5, 0x07f6, 0x0ffc, 0x0fff, 0x019d}, + {0x01c2, 0x00b5, 0x00a1, 0x0096, 0x0097, 0x0095, 0x0099, 0x00a0, 0x00a2, + 0x00ac, 0x00a9, 0x00b1, 0x00b3, 0x00bb, 0x00c0, 0x018f, 0x0004}, + {0x0018, 0x002e, 0x0000, 0x005a, 0x00a5, 0x00f8, 0x00b7, 0x0094, 0x00f9, + 0x004d, 0x0021, 0x002b, 0x004f, 0x007b, 0x00bc, 0x0046, 0x0015}, + {0x0042, 0x0037, 0x0078, 0x000d, 0x0068, 0x005f, 0x000d, 0x005e, 0x005a, + 0x00be, 0x0063, 0x007e, 0x001f, 0x0092, 0x001a, 0x00ab, 0x0032}, + {0x00e6, 0x0037, 0x0000, 0x0058, 0x000b, 0x005a, 0x00e1, 0x005d, 0x0029, + 0x0017, 0x007e, 0x0069, 0x00aa, 0x0054, 0x0029, 0x0032, 0x0041}, + {0x0046, 0x00ea, 0x0034, 0x00ea, 0x0011, 0x001b, 0x00a9, 0x0094, 0x00e2, + 0x0031, 0x00d0, 0x00e5, 0x0007, 0x0070, 0x0069, 0x003e, 0x0021}}; + +const ULONG FDKaacEnc_huff_ctabscf[121] = { + 0x0003ffe8, 0x0003ffe6, 0x0003ffe7, 0x0003ffe5, 0x0007fff5, 0x0007fff1, + 0x0007ffed, 0x0007fff6, 0x0007ffee, 0x0007ffef, 0x0007fff0, 0x0007fffc, + 0x0007fffd, 0x0007ffff, 0x0007fffe, 0x0007fff7, 0x0007fff8, 0x0007fffb, + 0x0007fff9, 0x0003ffe4, 0x0007fffa, 0x0003ffe3, 0x0001ffef, 0x0001fff0, + 0x0000fff5, 0x0001ffee, 0x0000fff2, 0x0000fff3, 0x0000fff4, 0x0000fff1, + 0x00007ff6, 0x00007ff7, 0x00003ff9, 0x00003ff5, 0x00003ff7, 0x00003ff3, + 0x00003ff6, 0x00003ff2, 0x00001ff7, 0x00001ff5, 0x00000ff9, 0x00000ff7, + 0x00000ff6, 0x000007f9, 0x00000ff4, 0x000007f8, 0x000003f9, 0x000003f7, + 0x000003f5, 0x000001f8, 0x000001f7, 0x000000fa, 0x000000f8, 0x000000f6, + 0x00000079, 0x0000003a, 0x00000038, 0x0000001a, 0x0000000b, 0x00000004, + 0x00000000, 0x0000000a, 0x0000000c, 0x0000001b, 0x00000039, 0x0000003b, + 0x00000078, 0x0000007a, 0x000000f7, 0x000000f9, 0x000001f6, 0x000001f9, + 0x000003f4, 0x000003f6, 0x000003f8, 0x000007f5, 0x000007f4, 0x000007f6, + 0x000007f7, 0x00000ff5, 0x00000ff8, 0x00001ff4, 0x00001ff6, 0x00001ff8, + 0x00003ff8, 0x00003ff4, 0x0000fff0, 0x00007ff4, 0x0000fff6, 0x00007ff5, + 0x0003ffe2, 0x0007ffd9, 0x0007ffda, 0x0007ffdb, 0x0007ffdc, 0x0007ffdd, + 0x0007ffde, 0x0007ffd8, 0x0007ffd2, 0x0007ffd3, 0x0007ffd4, 0x0007ffd5, + 0x0007ffd6, 0x0007fff2, 0x0007ffdf, 0x0007ffe7, 0x0007ffe8, 0x0007ffe9, + 0x0007ffea, 0x0007ffeb, 0x0007ffe6, 0x0007ffe0, 0x0007ffe1, 0x0007ffe2, + 0x0007ffe3, 0x0007ffe4, 0x0007ffe5, 0x0007ffd7, 0x0007ffec, 0x0007fff4, + 0x0007fff3}; /* table of (0.50000...1.00000) ^0.75 */ -const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = -{ - QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c), QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab), - QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a), QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3), - QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d), QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd), - QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4), QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4), - QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a), QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1), - QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725), QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d), - QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf), QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0), - QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1), QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4), - QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656), QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306), - QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e), QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38), - QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d), QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492), - QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad), QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242), - QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2), QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e), - QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6), QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6), - QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c), QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2), - QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812), QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6), - QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34), QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2), - QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895), QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631), - QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8), QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc), - QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d), QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b), - QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33), QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3), - QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037), QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da), - QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6), QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4), - QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd), QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7), - QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca), QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a), - QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d), QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485), - QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167), QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933), - QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b), QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90), - QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2), QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e), - QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4), QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50), - QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680), QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f), - QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8), QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636), - QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643), QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418), - QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed), QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa), - QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277), QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a), - QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98), QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8), - QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd), QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd), - QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a), QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7), - QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718), QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace), - QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9), QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc), - QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976), QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027), - QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e), QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a), - QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39), QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9), - QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767), QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811), - QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01), QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064), - QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866), QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331), - QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1), QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce), - QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3), QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89), - QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8), QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa), - QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86), QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174), - QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b), QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21), - QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e), QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7), - QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673), QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6), - QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095), QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75), - QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb), QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a), - QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506), QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852), - QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191), QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6), - QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673), QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259), - QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc), QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb), - QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78), QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414), - QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0), QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a), - QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264), QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd), - QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093), QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307), - QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36), QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40) -}; +const FIXP_QTD FDKaacEnc_mTab_3_4[MANT_SIZE] = { + QTC(0x4c1bf829), QTC(0x4c3880de), QTC(0x4c550603), QTC(0x4c71879c), + QTC(0x4c8e05aa), QTC(0x4caa8030), QTC(0x4cc6f72f), QTC(0x4ce36aab), + QTC(0x4cffdaa4), QTC(0x4d1c471d), QTC(0x4d38b019), QTC(0x4d55159a), + QTC(0x4d7177a1), QTC(0x4d8dd631), QTC(0x4daa314b), QTC(0x4dc688f3), + QTC(0x4de2dd2a), QTC(0x4dff2df2), QTC(0x4e1b7b4d), QTC(0x4e37c53d), + QTC(0x4e540bc5), QTC(0x4e704ee6), QTC(0x4e8c8ea3), QTC(0x4ea8cafd), + QTC(0x4ec503f7), QTC(0x4ee13992), QTC(0x4efd6bd0), QTC(0x4f199ab4), + QTC(0x4f35c640), QTC(0x4f51ee75), QTC(0x4f6e1356), QTC(0x4f8a34e4), + QTC(0x4fa65321), QTC(0x4fc26e10), QTC(0x4fde85b2), QTC(0x4ffa9a0a), + QTC(0x5016ab18), QTC(0x5032b8e0), QTC(0x504ec362), QTC(0x506acaa1), + QTC(0x5086cea0), QTC(0x50a2cf5e), QTC(0x50becce0), QTC(0x50dac725), + QTC(0x50f6be31), QTC(0x5112b205), QTC(0x512ea2a3), QTC(0x514a900d), + QTC(0x51667a45), QTC(0x5182614c), QTC(0x519e4524), QTC(0x51ba25cf), + QTC(0x51d60350), QTC(0x51f1dda7), QTC(0x520db4d6), QTC(0x522988e0), + QTC(0x524559c6), QTC(0x52612789), QTC(0x527cf22d), QTC(0x5298b9b1), + QTC(0x52b47e19), QTC(0x52d03f65), QTC(0x52ebfd98), QTC(0x5307b8b4), + QTC(0x532370b9), QTC(0x533f25aa), QTC(0x535ad789), QTC(0x53768656), + QTC(0x53923215), QTC(0x53addac6), QTC(0x53c9806b), QTC(0x53e52306), + QTC(0x5400c298), QTC(0x541c5f24), QTC(0x5437f8ab), QTC(0x54538f2e), + QTC(0x546f22af), QTC(0x548ab330), QTC(0x54a640b3), QTC(0x54c1cb38), + QTC(0x54dd52c2), QTC(0x54f8d753), QTC(0x551458eb), QTC(0x552fd78d), + QTC(0x554b5339), QTC(0x5566cbf3), QTC(0x558241bb), QTC(0x559db492), + QTC(0x55b9247b), QTC(0x55d49177), QTC(0x55effb87), QTC(0x560b62ad), + QTC(0x5626c6eb), QTC(0x56422842), QTC(0x565d86b4), QTC(0x5678e242), + QTC(0x56943aee), QTC(0x56af90b9), QTC(0x56cae3a4), QTC(0x56e633b2), + QTC(0x570180e4), QTC(0x571ccb3b), QTC(0x573812b8), QTC(0x5753575e), + QTC(0x576e992e), QTC(0x5789d829), QTC(0x57a51450), QTC(0x57c04da6), + QTC(0x57db842b), QTC(0x57f6b7e1), QTC(0x5811e8c9), QTC(0x582d16e6), + QTC(0x58484238), QTC(0x58636ac0), QTC(0x587e9081), QTC(0x5899b37c), + QTC(0x58b4d3b1), QTC(0x58cff123), QTC(0x58eb0bd3), QTC(0x590623c2), + QTC(0x592138f2), QTC(0x593c4b63), QTC(0x59575b19), QTC(0x59726812), + QTC(0x598d7253), QTC(0x59a879da), QTC(0x59c37eab), QTC(0x59de80c6), + QTC(0x59f9802d), QTC(0x5a147ce0), QTC(0x5a2f76e2), QTC(0x5a4a6e34), + QTC(0x5a6562d6), QTC(0x5a8054cb), QTC(0x5a9b4414), QTC(0x5ab630b2), + QTC(0x5ad11aa6), QTC(0x5aec01f1), QTC(0x5b06e696), QTC(0x5b21c895), + QTC(0x5b3ca7ef), QTC(0x5b5784a6), QTC(0x5b725ebc), QTC(0x5b8d3631), + QTC(0x5ba80b06), QTC(0x5bc2dd3e), QTC(0x5bddacd9), QTC(0x5bf879d8), + QTC(0x5c13443d), QTC(0x5c2e0c09), QTC(0x5c48d13e), QTC(0x5c6393dc), + QTC(0x5c7e53e5), QTC(0x5c99115a), QTC(0x5cb3cc3c), QTC(0x5cce848d), + QTC(0x5ce93a4e), QTC(0x5d03ed80), QTC(0x5d1e9e24), QTC(0x5d394c3b), + QTC(0x5d53f7c7), QTC(0x5d6ea0c9), QTC(0x5d894742), QTC(0x5da3eb33), + QTC(0x5dbe8c9e), QTC(0x5dd92b84), QTC(0x5df3c7e5), QTC(0x5e0e61c3), + QTC(0x5e28f920), QTC(0x5e438dfc), QTC(0x5e5e2059), QTC(0x5e78b037), + QTC(0x5e933d99), QTC(0x5eadc87e), QTC(0x5ec850e9), QTC(0x5ee2d6da), + QTC(0x5efd5a53), QTC(0x5f17db54), QTC(0x5f3259e0), QTC(0x5f4cd5f6), + QTC(0x5f674f99), QTC(0x5f81c6c8), QTC(0x5f9c3b87), QTC(0x5fb6add4), + QTC(0x5fd11db3), QTC(0x5feb8b23), QTC(0x6005f626), QTC(0x60205ebd), + QTC(0x603ac4e9), QTC(0x605528ac), QTC(0x606f8a05), QTC(0x6089e8f7), + QTC(0x60a44583), QTC(0x60be9fa9), QTC(0x60d8f76b), QTC(0x60f34cca), + QTC(0x610d9fc7), QTC(0x6127f062), QTC(0x61423e9e), QTC(0x615c8a7a), + QTC(0x6176d3f9), QTC(0x61911b1b), QTC(0x61ab5fe1), QTC(0x61c5a24d), + QTC(0x61dfe25f), QTC(0x61fa2018), QTC(0x62145b7a), QTC(0x622e9485), + QTC(0x6248cb3b), QTC(0x6262ff9d), QTC(0x627d31ab), QTC(0x62976167), + QTC(0x62b18ed1), QTC(0x62cbb9eb), QTC(0x62e5e2b6), QTC(0x63000933), + QTC(0x631a2d62), QTC(0x63344f45), QTC(0x634e6edd), QTC(0x63688c2b), + QTC(0x6382a730), QTC(0x639cbfec), QTC(0x63b6d661), QTC(0x63d0ea90), + QTC(0x63eafc7a), QTC(0x64050c1f), QTC(0x641f1982), QTC(0x643924a2), + QTC(0x64532d80), QTC(0x646d341f), QTC(0x6487387e), QTC(0x64a13a9e), + QTC(0x64bb3a81), QTC(0x64d53828), QTC(0x64ef3393), QTC(0x65092cc4), + QTC(0x652323bb), QTC(0x653d1879), QTC(0x65570b00), QTC(0x6570fb50), + QTC(0x658ae96b), QTC(0x65a4d550), QTC(0x65bebf01), QTC(0x65d8a680), + QTC(0x65f28bcc), QTC(0x660c6ee8), QTC(0x66264fd3), QTC(0x66402e8f), + QTC(0x665a0b1c), QTC(0x6673e57d), QTC(0x668dbdb0), QTC(0x66a793b8), + QTC(0x66c16795), QTC(0x66db3949), QTC(0x66f508d4), QTC(0x670ed636), + QTC(0x6728a172), QTC(0x67426a87), QTC(0x675c3177), QTC(0x6775f643), + QTC(0x678fb8eb), QTC(0x67a97971), QTC(0x67c337d5), QTC(0x67dcf418), + QTC(0x67f6ae3b), QTC(0x6810663f), QTC(0x682a1c25), QTC(0x6843cfed), + QTC(0x685d8199), QTC(0x68773129), QTC(0x6890de9f), QTC(0x68aa89fa), + QTC(0x68c4333d), QTC(0x68ddda67), QTC(0x68f77f7a), QTC(0x69112277), + QTC(0x692ac35e), QTC(0x69446230), QTC(0x695dfeee), QTC(0x6977999a), + QTC(0x69913232), QTC(0x69aac8ba), QTC(0x69c45d31), QTC(0x69ddef98), + QTC(0x69f77ff0), QTC(0x6a110e3a), QTC(0x6a2a9a77), QTC(0x6a4424a8), + QTC(0x6a5daccc), QTC(0x6a7732e6), QTC(0x6a90b6f6), QTC(0x6aaa38fd), + QTC(0x6ac3b8fb), QTC(0x6add36f2), QTC(0x6af6b2e2), QTC(0x6b102ccd), + QTC(0x6b29a4b2), QTC(0x6b431a92), QTC(0x6b5c8e6f), QTC(0x6b76004a), + QTC(0x6b8f7022), QTC(0x6ba8ddf9), QTC(0x6bc249d0), QTC(0x6bdbb3a7), + QTC(0x6bf51b80), QTC(0x6c0e815a), QTC(0x6c27e537), QTC(0x6c414718), + QTC(0x6c5aa6fd), QTC(0x6c7404e7), QTC(0x6c8d60d7), QTC(0x6ca6bace), + QTC(0x6cc012cc), QTC(0x6cd968d2), QTC(0x6cf2bce1), QTC(0x6d0c0ef9), + QTC(0x6d255f1d), QTC(0x6d3ead4b), QTC(0x6d57f985), QTC(0x6d7143cc), + QTC(0x6d8a8c21), QTC(0x6da3d283), QTC(0x6dbd16f5), QTC(0x6dd65976), + QTC(0x6def9a08), QTC(0x6e08d8ab), QTC(0x6e221560), QTC(0x6e3b5027), + QTC(0x6e548902), QTC(0x6e6dbff1), QTC(0x6e86f4f5), QTC(0x6ea0280e), + QTC(0x6eb9593e), QTC(0x6ed28885), QTC(0x6eebb5e3), QTC(0x6f04e15a), + QTC(0x6f1e0aea), QTC(0x6f373294), QTC(0x6f505859), QTC(0x6f697c39), + QTC(0x6f829e35), QTC(0x6f9bbe4e), QTC(0x6fb4dc85), QTC(0x6fcdf8d9), + QTC(0x6fe7134d), QTC(0x70002be0), QTC(0x70194293), QTC(0x70325767), + QTC(0x704b6a5d), QTC(0x70647b76), QTC(0x707d8ab1), QTC(0x70969811), + QTC(0x70afa394), QTC(0x70c8ad3d), QTC(0x70e1b50c), QTC(0x70fabb01), + QTC(0x7113bf1d), QTC(0x712cc161), QTC(0x7145c1ce), QTC(0x715ec064), + QTC(0x7177bd24), QTC(0x7190b80f), QTC(0x71a9b124), QTC(0x71c2a866), + QTC(0x71db9dd4), QTC(0x71f49170), QTC(0x720d8339), QTC(0x72267331), + QTC(0x723f6159), QTC(0x72584db0), QTC(0x72713838), QTC(0x728a20f1), + QTC(0x72a307db), QTC(0x72bbecf9), QTC(0x72d4d049), QTC(0x72edb1ce), + QTC(0x73069187), QTC(0x731f6f75), QTC(0x73384b98), QTC(0x735125f3), + QTC(0x7369fe84), QTC(0x7382d54d), QTC(0x739baa4e), QTC(0x73b47d89), + QTC(0x73cd4efd), QTC(0x73e61eab), QTC(0x73feec94), QTC(0x7417b8b8), + QTC(0x74308319), QTC(0x74494bb6), QTC(0x74621291), QTC(0x747ad7aa), + QTC(0x74939b02), QTC(0x74ac5c98), QTC(0x74c51c6f), QTC(0x74ddda86), + QTC(0x74f696de), QTC(0x750f5178), QTC(0x75280a54), QTC(0x7540c174), + QTC(0x755976d7), QTC(0x75722a7e), QTC(0x758adc69), QTC(0x75a38c9b), + QTC(0x75bc3b12), QTC(0x75d4e7cf), QTC(0x75ed92d4), QTC(0x76063c21), + QTC(0x761ee3b6), QTC(0x76378994), QTC(0x76502dbc), QTC(0x7668d02e), + QTC(0x768170eb), QTC(0x769a0ff3), QTC(0x76b2ad47), QTC(0x76cb48e7), + QTC(0x76e3e2d5), QTC(0x76fc7b10), QTC(0x7715119a), QTC(0x772da673), + QTC(0x7746399b), QTC(0x775ecb13), QTC(0x77775adc), QTC(0x778fe8f6), + QTC(0x77a87561), QTC(0x77c1001f), QTC(0x77d98930), QTC(0x77f21095), + QTC(0x780a964d), QTC(0x78231a5b), QTC(0x783b9cbd), QTC(0x78541d75), + QTC(0x786c9c84), QTC(0x788519e9), QTC(0x789d95a6), QTC(0x78b60fbb), + QTC(0x78ce8828), QTC(0x78e6feef), QTC(0x78ff740f), QTC(0x7917e78a), + QTC(0x7930595f), QTC(0x7948c990), QTC(0x7961381d), QTC(0x7979a506), + QTC(0x7992104c), QTC(0x79aa79f0), QTC(0x79c2e1f1), QTC(0x79db4852), + QTC(0x79f3ad11), QTC(0x7a0c1031), QTC(0x7a2471b0), QTC(0x7a3cd191), + QTC(0x7a552fd3), QTC(0x7a6d8c76), QTC(0x7a85e77d), QTC(0x7a9e40e6), + QTC(0x7ab698b2), QTC(0x7aceeee3), QTC(0x7ae74378), QTC(0x7aff9673), + QTC(0x7b17e7d2), QTC(0x7b303799), QTC(0x7b4885c5), QTC(0x7b60d259), + QTC(0x7b791d55), QTC(0x7b9166b9), QTC(0x7ba9ae86), QTC(0x7bc1f4bc), + QTC(0x7bda395c), QTC(0x7bf27c66), QTC(0x7c0abddb), QTC(0x7c22fdbb), + QTC(0x7c3b3c07), QTC(0x7c5378c0), QTC(0x7c6bb3e5), QTC(0x7c83ed78), + QTC(0x7c9c2579), QTC(0x7cb45be9), QTC(0x7ccc90c7), QTC(0x7ce4c414), + QTC(0x7cfcf5d2), QTC(0x7d152600), QTC(0x7d2d549f), QTC(0x7d4581b0), + QTC(0x7d5dad32), QTC(0x7d75d727), QTC(0x7d8dff8f), QTC(0x7da6266a), + QTC(0x7dbe4bba), QTC(0x7dd66f7d), QTC(0x7dee91b6), QTC(0x7e06b264), + QTC(0x7e1ed188), QTC(0x7e36ef22), QTC(0x7e4f0b34), QTC(0x7e6725bd), + QTC(0x7e7f3ebd), QTC(0x7e975636), QTC(0x7eaf6c28), QTC(0x7ec78093), + QTC(0x7edf9378), QTC(0x7ef7a4d7), QTC(0x7f0fb4b1), QTC(0x7f27c307), + QTC(0x7f3fcfd8), QTC(0x7f57db25), QTC(0x7f6fe4ef), QTC(0x7f87ed36), + QTC(0x7f9ff3fb), QTC(0x7fb7f93e), QTC(0x7fcffcff), QTC(0x7fe7ff40)}; /* table of pow(2.0,0.25*q)/2.0, q[0..4) */ -const FIXP_QTD FDKaacEnc_quantTableQ[4] = { QTC(0x40000000), QTC(0x4c1bf7ff), QTC(0x5a82797f), QTC(0x6ba27e7f) }; +const FIXP_QTD FDKaacEnc_quantTableQ[4] = {QTC(0x40000000), QTC(0x4c1bf7ff), + QTC(0x5a82797f), QTC(0x6ba27e7f)}; /* table of pow(2.0,0.75*e)/8.0, e[0..4) */ -const FIXP_QTD FDKaacEnc_quantTableE[4] = { QTC(0x10000000), QTC(0x1ae89f99), QTC(0x2d413ccd), QTC(0x4c1bf828) }; - +const FIXP_QTD FDKaacEnc_quantTableE[4] = {QTC(0x10000000), QTC(0x1ae89f99), + QTC(0x2d413ccd), QTC(0x4c1bf828)}; /* table to count used number of bits */ -const SHORT FDKaacEnc_sideInfoTabLong[MAX_SFB_LONG + 1] = -{ - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, - 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, - 0x000e, 0x000e, 0x000e, 0x000e -}; - - -const SHORT FDKaacEnc_sideInfoTabShort[MAX_SFB_SHORT + 1] = -{ - 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a, - 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d -}; - - - - - +const SHORT FDKaacEnc_sideInfoTabLong[] = { + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, + 0x0009, 0x0009, 0x0009, 0x0009, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, + 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e, 0x000e}; + +const SHORT FDKaacEnc_sideInfoTabShort[] = { + 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x000a, + 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000d, 0x000d}; /* Psy Configuration constants */ const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024 = { - 40, - { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 16, 16, 16, - 20, 20, 20, 20, 24, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80 } -}; + 40, {12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, + 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, + 28, 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80}}; const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024 = { - 43, - { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, - 64, 64, 64 } -}; + 43, {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, + 28, 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, - 52, 52, 64, 64, 64, 64, 64 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, + 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28, 32, 36, 36, 40, 44, 48, - 52, 52, 64, 64, 64, 64, 64 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, + 28, 28, 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128 = { - 15, - { 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20 } -}; + 15, {4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20}}; const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024 = { - 51, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 } -}; + 51, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024 = { - 49, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 96 } -}; + 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}}; const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024 = { - 49, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, - 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 96 } -}; + 49, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 96}}; const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128 = { - 14, - { 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16 } -}; + 14, {4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16}}; const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024 = { - 47, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, - 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40 } -}; + 47, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, + 8, 8, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}; const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024 = { - 41, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64 } -}; + 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, + 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024 = { - 41, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64 } -}; + 41, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, + 36, 44, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}}; const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = { - 12, - { 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36 } -}; - + 12, {4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36}}; /* TNS filter coefficients @@ -655,578 +815,1672 @@ const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128 = { /* 3 bit resolution */ -const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]= -{ - (FIXP_DBL)0x81f1d201, (FIXP_DBL)0x91261481, (FIXP_DBL)0xadb92301, (FIXP_DBL)0xd438af00, (FIXP_DBL)0x00000000, (FIXP_DBL)0x37898080, (FIXP_DBL)0x64130dff, (FIXP_DBL)0x7cca6fff -}; -const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]={ - (FIXP_DBL)0x80000001 /*-4*/, (FIXP_DBL)0x87b826df /*-3*/, (FIXP_DBL)0x9df24154 /*-2*/, (FIXP_DBL)0xbfffffe5 /*-1*/, - (FIXP_DBL)0xe9c5e578 /* 0*/, (FIXP_DBL)0x1c7b90f0 /* 1*/, (FIXP_DBL)0x4fce83a9 /* 2*/, (FIXP_DBL)0x7352f2c3 /* 3*/ +const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8] = { + FX_DBL2FXCONST_LPC(0x81f1d201), FX_DBL2FXCONST_LPC(0x91261481), + FX_DBL2FXCONST_LPC(0xadb92301), FX_DBL2FXCONST_LPC(0xd438af00), + FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x37898080), + FX_DBL2FXCONST_LPC(0x64130dff), FX_DBL2FXCONST_LPC(0x7cca6fff)}; +const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8] = { + FX_DBL2FXCONST_LPC(0x80000001) /*-4*/, + FX_DBL2FXCONST_LPC(0x87b826df) /*-3*/, + FX_DBL2FXCONST_LPC(0x9df24154) /*-2*/, + FX_DBL2FXCONST_LPC(0xbfffffe5) /*-1*/, + FX_DBL2FXCONST_LPC(0xe9c5e578) /* 0*/, + FX_DBL2FXCONST_LPC(0x1c7b90f0) /* 1*/, + FX_DBL2FXCONST_LPC(0x4fce83a9) /* 2*/, + FX_DBL2FXCONST_LPC(0x7352f2c3) /* 3*/ }; /* 4 bit resolution */ -const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]= -{ - (FIXP_DBL)0x808bc881, (FIXP_DBL)0x84e2e581, (FIXP_DBL)0x8d6b4a01, (FIXP_DBL)0x99da9201, (FIXP_DBL)0xa9c45701, (FIXP_DBL)0xbc9dde81, (FIXP_DBL)0xd1c2d500, (FIXP_DBL)0xe87ae540, - (FIXP_DBL)0x00000000, (FIXP_DBL)0x1a9cd9c0, (FIXP_DBL)0x340ff240, (FIXP_DBL)0x4b3c8bff, (FIXP_DBL)0x5f1f5e7f, (FIXP_DBL)0x6ed9eb7f, (FIXP_DBL)0x79bc387f, (FIXP_DBL)0x7f4c7e7f -}; -const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]= -{ - (FIXP_DBL)0x80000001 /*-8*/, (FIXP_DBL)0x822deff0 /*-7*/, (FIXP_DBL)0x88a4bfe6 /*-6*/, (FIXP_DBL)0x932c159d /*-5*/, - (FIXP_DBL)0xa16827c2 /*-4*/, (FIXP_DBL)0xb2dcde27 /*-3*/, (FIXP_DBL)0xc6f20b91 /*-2*/, (FIXP_DBL)0xdcf89c64 /*-1*/, - (FIXP_DBL)0xf4308ce1 /* 0*/, (FIXP_DBL)0x0d613054 /* 1*/, (FIXP_DBL)0x278dde80 /* 2*/, (FIXP_DBL)0x4000001b /* 3*/, - (FIXP_DBL)0x55a6127b /* 4*/, (FIXP_DBL)0x678dde8f /* 5*/, (FIXP_DBL)0x74ef0ed7 /* 6*/, (FIXP_DBL)0x7d33f0da /* 7*/ +const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16] = { + FX_DBL2FXCONST_LPC(0x808bc881), FX_DBL2FXCONST_LPC(0x84e2e581), + FX_DBL2FXCONST_LPC(0x8d6b4a01), FX_DBL2FXCONST_LPC(0x99da9201), + FX_DBL2FXCONST_LPC(0xa9c45701), FX_DBL2FXCONST_LPC(0xbc9dde81), + FX_DBL2FXCONST_LPC(0xd1c2d500), FX_DBL2FXCONST_LPC(0xe87ae540), + FX_DBL2FXCONST_LPC(0x00000000), FX_DBL2FXCONST_LPC(0x1a9cd9c0), + FX_DBL2FXCONST_LPC(0x340ff240), FX_DBL2FXCONST_LPC(0x4b3c8bff), + FX_DBL2FXCONST_LPC(0x5f1f5e7f), FX_DBL2FXCONST_LPC(0x6ed9eb7f), + FX_DBL2FXCONST_LPC(0x79bc387f), FX_DBL2FXCONST_LPC(0x7f4c7e7f)}; +const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16] = { + FX_DBL2FXCONST_LPC(0x80000001) /*-8*/, + FX_DBL2FXCONST_LPC(0x822deff0) /*-7*/, + FX_DBL2FXCONST_LPC(0x88a4bfe6) /*-6*/, + FX_DBL2FXCONST_LPC(0x932c159d) /*-5*/, + FX_DBL2FXCONST_LPC(0xa16827c2) /*-4*/, + FX_DBL2FXCONST_LPC(0xb2dcde27) /*-3*/, + FX_DBL2FXCONST_LPC(0xc6f20b91) /*-2*/, + FX_DBL2FXCONST_LPC(0xdcf89c64) /*-1*/, + FX_DBL2FXCONST_LPC(0xf4308ce1) /* 0*/, + FX_DBL2FXCONST_LPC(0x0d613054) /* 1*/, + FX_DBL2FXCONST_LPC(0x278dde80) /* 2*/, + FX_DBL2FXCONST_LPC(0x4000001b) /* 3*/, + FX_DBL2FXCONST_LPC(0x55a6127b) /* 4*/, + FX_DBL2FXCONST_LPC(0x678dde8f) /* 5*/, + FX_DBL2FXCONST_LPC(0x74ef0ed7) /* 6*/, + FX_DBL2FXCONST_LPC(0x7d33f0da) /* 7*/ }; -const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]={ - FL2FXCONST_DBL(0.3968502629920499),FL2FXCONST_DBL(0.3978840634868335),FL2FXCONST_DBL(0.3989185359354711),FL2FXCONST_DBL(0.3999536794661432), - FL2FXCONST_DBL(0.4009894932098531),FL2FXCONST_DBL(0.4020259763004115),FL2FXCONST_DBL(0.4030631278744227),FL2FXCONST_DBL(0.4041009470712695), - FL2FXCONST_DBL(0.4051394330330996),FL2FXCONST_DBL(0.4061785849048110),FL2FXCONST_DBL(0.4072184018340380),FL2FXCONST_DBL(0.4082588829711372), - FL2FXCONST_DBL(0.4093000274691739),FL2FXCONST_DBL(0.4103418344839078),FL2FXCONST_DBL(0.4113843031737798),FL2FXCONST_DBL(0.4124274326998980), - FL2FXCONST_DBL(0.4134712222260245),FL2FXCONST_DBL(0.4145156709185620),FL2FXCONST_DBL(0.4155607779465400),FL2FXCONST_DBL(0.4166065424816022), - FL2FXCONST_DBL(0.4176529636979932),FL2FXCONST_DBL(0.4187000407725452),FL2FXCONST_DBL(0.4197477728846652),FL2FXCONST_DBL(0.4207961592163222), - FL2FXCONST_DBL(0.4218451989520345),FL2FXCONST_DBL(0.4228948912788567),FL2FXCONST_DBL(0.4239452353863673),FL2FXCONST_DBL(0.4249962304666564), - FL2FXCONST_DBL(0.4260478757143130),FL2FXCONST_DBL(0.4271001703264124),FL2FXCONST_DBL(0.4281531135025046),FL2FXCONST_DBL(0.4292067044446017), - FL2FXCONST_DBL(0.4302609423571658),FL2FXCONST_DBL(0.4313158264470970),FL2FXCONST_DBL(0.4323713559237216),FL2FXCONST_DBL(0.4334275299987803), - FL2FXCONST_DBL(0.4344843478864161),FL2FXCONST_DBL(0.4355418088031630),FL2FXCONST_DBL(0.4365999119679339),FL2FXCONST_DBL(0.4376586566020096), - FL2FXCONST_DBL(0.4387180419290272),FL2FXCONST_DBL(0.4397780671749683),FL2FXCONST_DBL(0.4408387315681480),FL2FXCONST_DBL(0.4419000343392039), - FL2FXCONST_DBL(0.4429619747210847),FL2FXCONST_DBL(0.4440245519490388),FL2FXCONST_DBL(0.4450877652606038),FL2FXCONST_DBL(0.4461516138955953), - FL2FXCONST_DBL(0.4472160970960963),FL2FXCONST_DBL(0.4482812141064458),FL2FXCONST_DBL(0.4493469641732286),FL2FXCONST_DBL(0.4504133465452648), - FL2FXCONST_DBL(0.4514803604735984),FL2FXCONST_DBL(0.4525480052114875),FL2FXCONST_DBL(0.4536162800143939),FL2FXCONST_DBL(0.4546851841399719), - FL2FXCONST_DBL(0.4557547168480591),FL2FXCONST_DBL(0.4568248774006652),FL2FXCONST_DBL(0.4578956650619623),FL2FXCONST_DBL(0.4589670790982746), - FL2FXCONST_DBL(0.4600391187780688),FL2FXCONST_DBL(0.4611117833719430),FL2FXCONST_DBL(0.4621850721526184),FL2FXCONST_DBL(0.4632589843949278), - FL2FXCONST_DBL(0.4643335193758069),FL2FXCONST_DBL(0.4654086763742842),FL2FXCONST_DBL(0.4664844546714713),FL2FXCONST_DBL(0.4675608535505532), - FL2FXCONST_DBL(0.4686378722967790),FL2FXCONST_DBL(0.4697155101974522),FL2FXCONST_DBL(0.4707937665419216),FL2FXCONST_DBL(0.4718726406215713), - FL2FXCONST_DBL(0.4729521317298118),FL2FXCONST_DBL(0.4740322391620711),FL2FXCONST_DBL(0.4751129622157845),FL2FXCONST_DBL(0.4761943001903867), - FL2FXCONST_DBL(0.4772762523873015),FL2FXCONST_DBL(0.4783588181099338),FL2FXCONST_DBL(0.4794419966636599),FL2FXCONST_DBL(0.4805257873558190), - FL2FXCONST_DBL(0.4816101894957042),FL2FXCONST_DBL(0.4826952023945537),FL2FXCONST_DBL(0.4837808253655421),FL2FXCONST_DBL(0.4848670577237714), - FL2FXCONST_DBL(0.4859538987862632),FL2FXCONST_DBL(0.4870413478719488),FL2FXCONST_DBL(0.4881294043016621),FL2FXCONST_DBL(0.4892180673981298), - FL2FXCONST_DBL(0.4903073364859640),FL2FXCONST_DBL(0.4913972108916533),FL2FXCONST_DBL(0.4924876899435545),FL2FXCONST_DBL(0.4935787729718844), - FL2FXCONST_DBL(0.4946704593087116),FL2FXCONST_DBL(0.4957627482879484),FL2FXCONST_DBL(0.4968556392453423),FL2FXCONST_DBL(0.4979491315184684), - FL2FXCONST_DBL(0.4990432244467211),FL2FXCONST_DBL(0.5001379173713062),FL2FXCONST_DBL(0.5012332096352328),FL2FXCONST_DBL(0.5023291005833056), - FL2FXCONST_DBL(0.5034255895621171),FL2FXCONST_DBL(0.5045226759200399),FL2FXCONST_DBL(0.5056203590072181),FL2FXCONST_DBL(0.5067186381755611), - FL2FXCONST_DBL(0.5078175127787346),FL2FXCONST_DBL(0.5089169821721536),FL2FXCONST_DBL(0.5100170457129749),FL2FXCONST_DBL(0.5111177027600893), - FL2FXCONST_DBL(0.5122189526741143),FL2FXCONST_DBL(0.5133207948173868),FL2FXCONST_DBL(0.5144232285539552),FL2FXCONST_DBL(0.5155262532495726), - FL2FXCONST_DBL(0.5166298682716894),FL2FXCONST_DBL(0.5177340729894460),FL2FXCONST_DBL(0.5188388667736652),FL2FXCONST_DBL(0.5199442489968457), - FL2FXCONST_DBL(0.5210502190331544),FL2FXCONST_DBL(0.5221567762584198),FL2FXCONST_DBL(0.5232639200501247),FL2FXCONST_DBL(0.5243716497873989), - FL2FXCONST_DBL(0.5254799648510130),FL2FXCONST_DBL(0.5265888646233705),FL2FXCONST_DBL(0.5276983484885021),FL2FXCONST_DBL(0.5288084158320574), - FL2FXCONST_DBL(0.5299190660412995),FL2FXCONST_DBL(0.5310302985050975),FL2FXCONST_DBL(0.5321421126139198),FL2FXCONST_DBL(0.5332545077598274), - FL2FXCONST_DBL(0.5343674833364678),FL2FXCONST_DBL(0.5354810387390675),FL2FXCONST_DBL(0.5365951733644262),FL2FXCONST_DBL(0.5377098866109097), - FL2FXCONST_DBL(0.5388251778784438),FL2FXCONST_DBL(0.5399410465685075),FL2FXCONST_DBL(0.5410574920841272),FL2FXCONST_DBL(0.5421745138298695), - FL2FXCONST_DBL(0.5432921112118353),FL2FXCONST_DBL(0.5444102836376534),FL2FXCONST_DBL(0.5455290305164744),FL2FXCONST_DBL(0.5466483512589642), - FL2FXCONST_DBL(0.5477682452772976),FL2FXCONST_DBL(0.5488887119851529),FL2FXCONST_DBL(0.5500097507977050),FL2FXCONST_DBL(0.5511313611316194), - FL2FXCONST_DBL(0.5522535424050467),FL2FXCONST_DBL(0.5533762940376158),FL2FXCONST_DBL(0.5544996154504284),FL2FXCONST_DBL(0.5556235060660528), - FL2FXCONST_DBL(0.5567479653085183),FL2FXCONST_DBL(0.5578729926033087),FL2FXCONST_DBL(0.5589985873773569),FL2FXCONST_DBL(0.5601247490590389), - FL2FXCONST_DBL(0.5612514770781683),FL2FXCONST_DBL(0.5623787708659898),FL2FXCONST_DBL(0.5635066298551742),FL2FXCONST_DBL(0.5646350534798125), - FL2FXCONST_DBL(0.5657640411754097),FL2FXCONST_DBL(0.5668935923788799),FL2FXCONST_DBL(0.5680237065285404),FL2FXCONST_DBL(0.5691543830641059), - FL2FXCONST_DBL(0.5702856214266832),FL2FXCONST_DBL(0.5714174210587655),FL2FXCONST_DBL(0.5725497814042271),FL2FXCONST_DBL(0.5736827019083177), - FL2FXCONST_DBL(0.5748161820176573),FL2FXCONST_DBL(0.5759502211802304),FL2FXCONST_DBL(0.5770848188453810),FL2FXCONST_DBL(0.5782199744638067), - FL2FXCONST_DBL(0.5793556874875542),FL2FXCONST_DBL(0.5804919573700131),FL2FXCONST_DBL(0.5816287835659116),FL2FXCONST_DBL(0.5827661655313104), - FL2FXCONST_DBL(0.5839041027235979),FL2FXCONST_DBL(0.5850425946014850),FL2FXCONST_DBL(0.5861816406250000),FL2FXCONST_DBL(0.5873212402554834), - FL2FXCONST_DBL(0.5884613929555826),FL2FXCONST_DBL(0.5896020981892474),FL2FXCONST_DBL(0.5907433554217242),FL2FXCONST_DBL(0.5918851641195517), - FL2FXCONST_DBL(0.5930275237505556),FL2FXCONST_DBL(0.5941704337838434),FL2FXCONST_DBL(0.5953138936897999),FL2FXCONST_DBL(0.5964579029400819), - FL2FXCONST_DBL(0.5976024610076139),FL2FXCONST_DBL(0.5987475673665825),FL2FXCONST_DBL(0.5998932214924321),FL2FXCONST_DBL(0.6010394228618597), - FL2FXCONST_DBL(0.6021861709528106),FL2FXCONST_DBL(0.6033334652444733),FL2FXCONST_DBL(0.6044813052172748),FL2FXCONST_DBL(0.6056296903528761), - FL2FXCONST_DBL(0.6067786201341671),FL2FXCONST_DBL(0.6079280940452625),FL2FXCONST_DBL(0.6090781115714966),FL2FXCONST_DBL(0.6102286721994192), - FL2FXCONST_DBL(0.6113797754167908),FL2FXCONST_DBL(0.6125314207125777),FL2FXCONST_DBL(0.6136836075769482),FL2FXCONST_DBL(0.6148363355012674), - FL2FXCONST_DBL(0.6159896039780929),FL2FXCONST_DBL(0.6171434125011708),FL2FXCONST_DBL(0.6182977605654305),FL2FXCONST_DBL(0.6194526476669808), - FL2FXCONST_DBL(0.6206080733031054),FL2FXCONST_DBL(0.6217640369722584),FL2FXCONST_DBL(0.6229205381740598),FL2FXCONST_DBL(0.6240775764092919), - FL2FXCONST_DBL(0.6252351511798939),FL2FXCONST_DBL(0.6263932619889586),FL2FXCONST_DBL(0.6275519083407275),FL2FXCONST_DBL(0.6287110897405869), - FL2FXCONST_DBL(0.6298708056950635),FL2FXCONST_DBL(0.6310310557118203),FL2FXCONST_DBL(0.6321918392996523),FL2FXCONST_DBL(0.6333531559684823), - FL2FXCONST_DBL(0.6345150052293571),FL2FXCONST_DBL(0.6356773865944432),FL2FXCONST_DBL(0.6368402995770224),FL2FXCONST_DBL(0.6380037436914881), - FL2FXCONST_DBL(0.6391677184533411),FL2FXCONST_DBL(0.6403322233791856),FL2FXCONST_DBL(0.6414972579867254),FL2FXCONST_DBL(0.6426628217947594), - FL2FXCONST_DBL(0.6438289143231779),FL2FXCONST_DBL(0.6449955350929588),FL2FXCONST_DBL(0.6461626836261636),FL2FXCONST_DBL(0.6473303594459330), - FL2FXCONST_DBL(0.6484985620764839),FL2FXCONST_DBL(0.6496672910431047),FL2FXCONST_DBL(0.6508365458721518),FL2FXCONST_DBL(0.6520063260910459), - FL2FXCONST_DBL(0.6531766312282679),FL2FXCONST_DBL(0.6543474608133552),FL2FXCONST_DBL(0.6555188143768979),FL2FXCONST_DBL(0.6566906914505349), - FL2FXCONST_DBL(0.6578630915669509),FL2FXCONST_DBL(0.6590360142598715),FL2FXCONST_DBL(0.6602094590640603),FL2FXCONST_DBL(0.6613834255153149), - FL2FXCONST_DBL(0.6625579131504635),FL2FXCONST_DBL(0.6637329215073610),FL2FXCONST_DBL(0.6649084501248851),FL2FXCONST_DBL(0.6660844985429335), - FL2FXCONST_DBL(0.6672610663024197),FL2FXCONST_DBL(0.6684381529452691),FL2FXCONST_DBL(0.6696157580144163),FL2FXCONST_DBL(0.6707938810538011), - FL2FXCONST_DBL(0.6719725216083646),FL2FXCONST_DBL(0.6731516792240465),FL2FXCONST_DBL(0.6743313534477807),FL2FXCONST_DBL(0.6755115438274927), - FL2FXCONST_DBL(0.6766922499120955),FL2FXCONST_DBL(0.6778734712514865),FL2FXCONST_DBL(0.6790552073965435),FL2FXCONST_DBL(0.6802374578991223), - FL2FXCONST_DBL(0.6814202223120524),FL2FXCONST_DBL(0.6826035001891340),FL2FXCONST_DBL(0.6837872910851345),FL2FXCONST_DBL(0.6849715945557853), - FL2FXCONST_DBL(0.6861564101577784),FL2FXCONST_DBL(0.6873417374487629),FL2FXCONST_DBL(0.6885275759873420),FL2FXCONST_DBL(0.6897139253330697), - FL2FXCONST_DBL(0.6909007850464473),FL2FXCONST_DBL(0.6920881546889198),FL2FXCONST_DBL(0.6932760338228737),FL2FXCONST_DBL(0.6944644220116332), - FL2FXCONST_DBL(0.6956533188194565),FL2FXCONST_DBL(0.6968427238115332),FL2FXCONST_DBL(0.6980326365539813),FL2FXCONST_DBL(0.6992230566138435), - FL2FXCONST_DBL(0.7004139835590845),FL2FXCONST_DBL(0.7016054169585869),FL2FXCONST_DBL(0.7027973563821499),FL2FXCONST_DBL(0.7039898014004843), - FL2FXCONST_DBL(0.7051827515852106),FL2FXCONST_DBL(0.7063762065088554),FL2FXCONST_DBL(0.7075701657448483),FL2FXCONST_DBL(0.7087646288675196), - FL2FXCONST_DBL(0.7099595954520960),FL2FXCONST_DBL(0.7111550650746988),FL2FXCONST_DBL(0.7123510373123402),FL2FXCONST_DBL(0.7135475117429202), - FL2FXCONST_DBL(0.7147444879452244),FL2FXCONST_DBL(0.7159419654989200),FL2FXCONST_DBL(0.7171399439845538),FL2FXCONST_DBL(0.7183384229835486), - FL2FXCONST_DBL(0.7195374020782005),FL2FXCONST_DBL(0.7207368808516762),FL2FXCONST_DBL(0.7219368588880097),FL2FXCONST_DBL(0.7231373357720997), - FL2FXCONST_DBL(0.7243383110897066),FL2FXCONST_DBL(0.7255397844274496),FL2FXCONST_DBL(0.7267417553728043),FL2FXCONST_DBL(0.7279442235140992), - FL2FXCONST_DBL(0.7291471884405130),FL2FXCONST_DBL(0.7303506497420724),FL2FXCONST_DBL(0.7315546070096487),FL2FXCONST_DBL(0.7327590598349553), - FL2FXCONST_DBL(0.7339640078105445),FL2FXCONST_DBL(0.7351694505298055),FL2FXCONST_DBL(0.7363753875869610),FL2FXCONST_DBL(0.7375818185770647), - FL2FXCONST_DBL(0.7387887430959987),FL2FXCONST_DBL(0.7399961607404706),FL2FXCONST_DBL(0.7412040711080108),FL2FXCONST_DBL(0.7424124737969701), - FL2FXCONST_DBL(0.7436213684065166),FL2FXCONST_DBL(0.7448307545366334),FL2FXCONST_DBL(0.7460406317881158),FL2FXCONST_DBL(0.7472509997625686), - FL2FXCONST_DBL(0.7484618580624036),FL2FXCONST_DBL(0.7496732062908372),FL2FXCONST_DBL(0.7508850440518872),FL2FXCONST_DBL(0.7520973709503704), - FL2FXCONST_DBL(0.7533101865919009),FL2FXCONST_DBL(0.7545234905828862),FL2FXCONST_DBL(0.7557372825305252),FL2FXCONST_DBL(0.7569515620428062), - FL2FXCONST_DBL(0.7581663287285035),FL2FXCONST_DBL(0.7593815821971756),FL2FXCONST_DBL(0.7605973220591619),FL2FXCONST_DBL(0.7618135479255810), - FL2FXCONST_DBL(0.7630302594083277),FL2FXCONST_DBL(0.7642474561200708),FL2FXCONST_DBL(0.7654651376742505),FL2FXCONST_DBL(0.7666833036850760), - FL2FXCONST_DBL(0.7679019537675227),FL2FXCONST_DBL(0.7691210875373307),FL2FXCONST_DBL(0.7703407046110011),FL2FXCONST_DBL(0.7715608046057948), - FL2FXCONST_DBL(0.7727813871397293),FL2FXCONST_DBL(0.7740024518315765),FL2FXCONST_DBL(0.7752239983008605),FL2FXCONST_DBL(0.7764460261678551), - FL2FXCONST_DBL(0.7776685350535814),FL2FXCONST_DBL(0.7788915245798054),FL2FXCONST_DBL(0.7801149943690360),FL2FXCONST_DBL(0.7813389440445223), - FL2FXCONST_DBL(0.7825633732302513),FL2FXCONST_DBL(0.7837882815509458),FL2FXCONST_DBL(0.7850136686320621),FL2FXCONST_DBL(0.7862395340997874), - FL2FXCONST_DBL(0.7874658775810378),FL2FXCONST_DBL(0.7886926987034559),FL2FXCONST_DBL(0.7899199970954088),FL2FXCONST_DBL(0.7911477723859853), - FL2FXCONST_DBL(0.7923760242049944),FL2FXCONST_DBL(0.7936047521829623),FL2FXCONST_DBL(0.7948339559511308),FL2FXCONST_DBL(0.7960636351414546), - FL2FXCONST_DBL(0.7972937893865995),FL2FXCONST_DBL(0.7985244183199399),FL2FXCONST_DBL(0.7997555215755570),FL2FXCONST_DBL(0.8009870987882359), - FL2FXCONST_DBL(0.8022191495934644),FL2FXCONST_DBL(0.8034516736274301),FL2FXCONST_DBL(0.8046846705270185),FL2FXCONST_DBL(0.8059181399298110), - FL2FXCONST_DBL(0.8071520814740822),FL2FXCONST_DBL(0.8083864947987989),FL2FXCONST_DBL(0.8096213795436166),FL2FXCONST_DBL(0.8108567353488784), - FL2FXCONST_DBL(0.8120925618556127),FL2FXCONST_DBL(0.8133288587055308),FL2FXCONST_DBL(0.8145656255410253),FL2FXCONST_DBL(0.8158028620051674), - FL2FXCONST_DBL(0.8170405677417053),FL2FXCONST_DBL(0.8182787423950622),FL2FXCONST_DBL(0.8195173856103341),FL2FXCONST_DBL(0.8207564970332875), - FL2FXCONST_DBL(0.8219960763103580),FL2FXCONST_DBL(0.8232361230886477),FL2FXCONST_DBL(0.8244766370159234),FL2FXCONST_DBL(0.8257176177406150), - FL2FXCONST_DBL(0.8269590649118125),FL2FXCONST_DBL(0.8282009781792650),FL2FXCONST_DBL(0.8294433571933784),FL2FXCONST_DBL(0.8306862016052132), - FL2FXCONST_DBL(0.8319295110664831),FL2FXCONST_DBL(0.8331732852295520),FL2FXCONST_DBL(0.8344175237474336),FL2FXCONST_DBL(0.8356622262737878), - FL2FXCONST_DBL(0.8369073924629202),FL2FXCONST_DBL(0.8381530219697793),FL2FXCONST_DBL(0.8393991144499545),FL2FXCONST_DBL(0.8406456695596752), - FL2FXCONST_DBL(0.8418926869558079),FL2FXCONST_DBL(0.8431401662958544),FL2FXCONST_DBL(0.8443881072379507),FL2FXCONST_DBL(0.8456365094408642), - FL2FXCONST_DBL(0.8468853725639923),FL2FXCONST_DBL(0.8481346962673606),FL2FXCONST_DBL(0.8493844802116208),FL2FXCONST_DBL(0.8506347240580492), - FL2FXCONST_DBL(0.8518854274685442),FL2FXCONST_DBL(0.8531365901056253),FL2FXCONST_DBL(0.8543882116324307),FL2FXCONST_DBL(0.8556402917127157), - FL2FXCONST_DBL(0.8568928300108512),FL2FXCONST_DBL(0.8581458261918209),FL2FXCONST_DBL(0.8593992799212207),FL2FXCONST_DBL(0.8606531908652563), - FL2FXCONST_DBL(0.8619075586907414),FL2FXCONST_DBL(0.8631623830650962),FL2FXCONST_DBL(0.8644176636563452),FL2FXCONST_DBL(0.8656734001331161), - FL2FXCONST_DBL(0.8669295921646375),FL2FXCONST_DBL(0.8681862394207371),FL2FXCONST_DBL(0.8694433415718407),FL2FXCONST_DBL(0.8707008982889695), - FL2FXCONST_DBL(0.8719589092437391),FL2FXCONST_DBL(0.8732173741083574),FL2FXCONST_DBL(0.8744762925556232),FL2FXCONST_DBL(0.8757356642589241), - FL2FXCONST_DBL(0.8769954888922352),FL2FXCONST_DBL(0.8782557661301171),FL2FXCONST_DBL(0.8795164956477146),FL2FXCONST_DBL(0.8807776771207545), - FL2FXCONST_DBL(0.8820393102255443),FL2FXCONST_DBL(0.8833013946389704),FL2FXCONST_DBL(0.8845639300384969),FL2FXCONST_DBL(0.8858269161021629), - FL2FXCONST_DBL(0.8870903525085819),FL2FXCONST_DBL(0.8883542389369399),FL2FXCONST_DBL(0.8896185750669933),FL2FXCONST_DBL(0.8908833605790678), - FL2FXCONST_DBL(0.8921485951540565),FL2FXCONST_DBL(0.8934142784734187),FL2FXCONST_DBL(0.8946804102191776),FL2FXCONST_DBL(0.8959469900739191), - FL2FXCONST_DBL(0.8972140177207906),FL2FXCONST_DBL(0.8984814928434985),FL2FXCONST_DBL(0.8997494151263077),FL2FXCONST_DBL(0.9010177842540390), - FL2FXCONST_DBL(0.9022865999120682),FL2FXCONST_DBL(0.9035558617863242),FL2FXCONST_DBL(0.9048255695632878),FL2FXCONST_DBL(0.9060957229299895), - FL2FXCONST_DBL(0.9073663215740092),FL2FXCONST_DBL(0.9086373651834729),FL2FXCONST_DBL(0.9099088534470528),FL2FXCONST_DBL(0.9111807860539647), - FL2FXCONST_DBL(0.9124531626939672),FL2FXCONST_DBL(0.9137259830573594),FL2FXCONST_DBL(0.9149992468349805),FL2FXCONST_DBL(0.9162729537182071), - FL2FXCONST_DBL(0.9175471033989524),FL2FXCONST_DBL(0.9188216955696648),FL2FXCONST_DBL(0.9200967299233258),FL2FXCONST_DBL(0.9213722061534494), - FL2FXCONST_DBL(0.9226481239540795),FL2FXCONST_DBL(0.9239244830197896),FL2FXCONST_DBL(0.9252012830456805),FL2FXCONST_DBL(0.9264785237273793), - FL2FXCONST_DBL(0.9277562047610376),FL2FXCONST_DBL(0.9290343258433305),FL2FXCONST_DBL(0.9303128866714547),FL2FXCONST_DBL(0.9315918869431275), - FL2FXCONST_DBL(0.9328713263565848),FL2FXCONST_DBL(0.9341512046105802),FL2FXCONST_DBL(0.9354315214043836),FL2FXCONST_DBL(0.9367122764377792), - FL2FXCONST_DBL(0.9379934694110648),FL2FXCONST_DBL(0.9392751000250497),FL2FXCONST_DBL(0.9405571679810542),FL2FXCONST_DBL(0.9418396729809072), - FL2FXCONST_DBL(0.9431226147269456),FL2FXCONST_DBL(0.9444059929220124),FL2FXCONST_DBL(0.9456898072694558),FL2FXCONST_DBL(0.9469740574731275), - FL2FXCONST_DBL(0.9482587432373810),FL2FXCONST_DBL(0.9495438642670713),FL2FXCONST_DBL(0.9508294202675522),FL2FXCONST_DBL(0.9521154109446763), - FL2FXCONST_DBL(0.9534018360047926),FL2FXCONST_DBL(0.9546886951547455),FL2FXCONST_DBL(0.9559759881018738),FL2FXCONST_DBL(0.9572637145540087), - FL2FXCONST_DBL(0.9585518742194732),FL2FXCONST_DBL(0.9598404668070802),FL2FXCONST_DBL(0.9611294920261317),FL2FXCONST_DBL(0.9624189495864168), - FL2FXCONST_DBL(0.9637088391982110),FL2FXCONST_DBL(0.9649991605722750),FL2FXCONST_DBL(0.9662899134198524),FL2FXCONST_DBL(0.9675810974526697), - FL2FXCONST_DBL(0.9688727123829343),FL2FXCONST_DBL(0.9701647579233330),FL2FXCONST_DBL(0.9714572337870316),FL2FXCONST_DBL(0.9727501396876727), - FL2FXCONST_DBL(0.9740434753393749),FL2FXCONST_DBL(0.9753372404567313),FL2FXCONST_DBL(0.9766314347548087),FL2FXCONST_DBL(0.9779260579491460), - FL2FXCONST_DBL(0.9792211097557527),FL2FXCONST_DBL(0.9805165898911081),FL2FXCONST_DBL(0.9818124980721600),FL2FXCONST_DBL(0.9831088340163232), - FL2FXCONST_DBL(0.9844055974414786),FL2FXCONST_DBL(0.9857027880659716),FL2FXCONST_DBL(0.9870004056086111),FL2FXCONST_DBL(0.9882984497886684), - FL2FXCONST_DBL(0.9895969203258759),FL2FXCONST_DBL(0.9908958169404255),FL2FXCONST_DBL(0.9921951393529680),FL2FXCONST_DBL(0.9934948872846116), - FL2FXCONST_DBL(0.9947950604569206),FL2FXCONST_DBL(0.9960956585919144),FL2FXCONST_DBL(0.9973966814120665),FL2FXCONST_DBL(0.9986981286403025) -}; - -const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = -{ - {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), - FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), - FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), - FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)}, - - {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), - FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), - FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), - FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)}, - - {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), - FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), - FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), - FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)}, - - {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), - FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), - FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), - FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)} -}; - -const UCHAR FDKaacEnc_specExpTableComb[4][14] = -{ - {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, - {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, - {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18}, - {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19} -}; - +const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512] = { + FL2FXCONST_DBL(0.3968502629920499), FL2FXCONST_DBL(0.3978840634868335), + FL2FXCONST_DBL(0.3989185359354711), FL2FXCONST_DBL(0.3999536794661432), + FL2FXCONST_DBL(0.4009894932098531), FL2FXCONST_DBL(0.4020259763004115), + FL2FXCONST_DBL(0.4030631278744227), FL2FXCONST_DBL(0.4041009470712695), + FL2FXCONST_DBL(0.4051394330330996), FL2FXCONST_DBL(0.4061785849048110), + FL2FXCONST_DBL(0.4072184018340380), FL2FXCONST_DBL(0.4082588829711372), + FL2FXCONST_DBL(0.4093000274691739), FL2FXCONST_DBL(0.4103418344839078), + FL2FXCONST_DBL(0.4113843031737798), FL2FXCONST_DBL(0.4124274326998980), + FL2FXCONST_DBL(0.4134712222260245), FL2FXCONST_DBL(0.4145156709185620), + FL2FXCONST_DBL(0.4155607779465400), FL2FXCONST_DBL(0.4166065424816022), + FL2FXCONST_DBL(0.4176529636979932), FL2FXCONST_DBL(0.4187000407725452), + FL2FXCONST_DBL(0.4197477728846652), FL2FXCONST_DBL(0.4207961592163222), + FL2FXCONST_DBL(0.4218451989520345), FL2FXCONST_DBL(0.4228948912788567), + FL2FXCONST_DBL(0.4239452353863673), FL2FXCONST_DBL(0.4249962304666564), + FL2FXCONST_DBL(0.4260478757143130), FL2FXCONST_DBL(0.4271001703264124), + FL2FXCONST_DBL(0.4281531135025046), FL2FXCONST_DBL(0.4292067044446017), + FL2FXCONST_DBL(0.4302609423571658), FL2FXCONST_DBL(0.4313158264470970), + FL2FXCONST_DBL(0.4323713559237216), FL2FXCONST_DBL(0.4334275299987803), + FL2FXCONST_DBL(0.4344843478864161), FL2FXCONST_DBL(0.4355418088031630), + FL2FXCONST_DBL(0.4365999119679339), FL2FXCONST_DBL(0.4376586566020096), + FL2FXCONST_DBL(0.4387180419290272), FL2FXCONST_DBL(0.4397780671749683), + FL2FXCONST_DBL(0.4408387315681480), FL2FXCONST_DBL(0.4419000343392039), + FL2FXCONST_DBL(0.4429619747210847), FL2FXCONST_DBL(0.4440245519490388), + FL2FXCONST_DBL(0.4450877652606038), FL2FXCONST_DBL(0.4461516138955953), + FL2FXCONST_DBL(0.4472160970960963), FL2FXCONST_DBL(0.4482812141064458), + FL2FXCONST_DBL(0.4493469641732286), FL2FXCONST_DBL(0.4504133465452648), + FL2FXCONST_DBL(0.4514803604735984), FL2FXCONST_DBL(0.4525480052114875), + FL2FXCONST_DBL(0.4536162800143939), FL2FXCONST_DBL(0.4546851841399719), + FL2FXCONST_DBL(0.4557547168480591), FL2FXCONST_DBL(0.4568248774006652), + FL2FXCONST_DBL(0.4578956650619623), FL2FXCONST_DBL(0.4589670790982746), + FL2FXCONST_DBL(0.4600391187780688), FL2FXCONST_DBL(0.4611117833719430), + FL2FXCONST_DBL(0.4621850721526184), FL2FXCONST_DBL(0.4632589843949278), + FL2FXCONST_DBL(0.4643335193758069), FL2FXCONST_DBL(0.4654086763742842), + FL2FXCONST_DBL(0.4664844546714713), FL2FXCONST_DBL(0.4675608535505532), + FL2FXCONST_DBL(0.4686378722967790), FL2FXCONST_DBL(0.4697155101974522), + FL2FXCONST_DBL(0.4707937665419216), FL2FXCONST_DBL(0.4718726406215713), + FL2FXCONST_DBL(0.4729521317298118), FL2FXCONST_DBL(0.4740322391620711), + FL2FXCONST_DBL(0.4751129622157845), FL2FXCONST_DBL(0.4761943001903867), + FL2FXCONST_DBL(0.4772762523873015), FL2FXCONST_DBL(0.4783588181099338), + FL2FXCONST_DBL(0.4794419966636599), FL2FXCONST_DBL(0.4805257873558190), + FL2FXCONST_DBL(0.4816101894957042), FL2FXCONST_DBL(0.4826952023945537), + FL2FXCONST_DBL(0.4837808253655421), FL2FXCONST_DBL(0.4848670577237714), + FL2FXCONST_DBL(0.4859538987862632), FL2FXCONST_DBL(0.4870413478719488), + FL2FXCONST_DBL(0.4881294043016621), FL2FXCONST_DBL(0.4892180673981298), + FL2FXCONST_DBL(0.4903073364859640), FL2FXCONST_DBL(0.4913972108916533), + FL2FXCONST_DBL(0.4924876899435545), FL2FXCONST_DBL(0.4935787729718844), + FL2FXCONST_DBL(0.4946704593087116), FL2FXCONST_DBL(0.4957627482879484), + FL2FXCONST_DBL(0.4968556392453423), FL2FXCONST_DBL(0.4979491315184684), + FL2FXCONST_DBL(0.4990432244467211), FL2FXCONST_DBL(0.5001379173713062), + FL2FXCONST_DBL(0.5012332096352328), FL2FXCONST_DBL(0.5023291005833056), + FL2FXCONST_DBL(0.5034255895621171), FL2FXCONST_DBL(0.5045226759200399), + FL2FXCONST_DBL(0.5056203590072181), FL2FXCONST_DBL(0.5067186381755611), + FL2FXCONST_DBL(0.5078175127787346), FL2FXCONST_DBL(0.5089169821721536), + FL2FXCONST_DBL(0.5100170457129749), FL2FXCONST_DBL(0.5111177027600893), + FL2FXCONST_DBL(0.5122189526741143), FL2FXCONST_DBL(0.5133207948173868), + FL2FXCONST_DBL(0.5144232285539552), FL2FXCONST_DBL(0.5155262532495726), + FL2FXCONST_DBL(0.5166298682716894), FL2FXCONST_DBL(0.5177340729894460), + FL2FXCONST_DBL(0.5188388667736652), FL2FXCONST_DBL(0.5199442489968457), + FL2FXCONST_DBL(0.5210502190331544), FL2FXCONST_DBL(0.5221567762584198), + FL2FXCONST_DBL(0.5232639200501247), FL2FXCONST_DBL(0.5243716497873989), + FL2FXCONST_DBL(0.5254799648510130), FL2FXCONST_DBL(0.5265888646233705), + FL2FXCONST_DBL(0.5276983484885021), FL2FXCONST_DBL(0.5288084158320574), + FL2FXCONST_DBL(0.5299190660412995), FL2FXCONST_DBL(0.5310302985050975), + FL2FXCONST_DBL(0.5321421126139198), FL2FXCONST_DBL(0.5332545077598274), + FL2FXCONST_DBL(0.5343674833364678), FL2FXCONST_DBL(0.5354810387390675), + FL2FXCONST_DBL(0.5365951733644262), FL2FXCONST_DBL(0.5377098866109097), + FL2FXCONST_DBL(0.5388251778784438), FL2FXCONST_DBL(0.5399410465685075), + FL2FXCONST_DBL(0.5410574920841272), FL2FXCONST_DBL(0.5421745138298695), + FL2FXCONST_DBL(0.5432921112118353), FL2FXCONST_DBL(0.5444102836376534), + FL2FXCONST_DBL(0.5455290305164744), FL2FXCONST_DBL(0.5466483512589642), + FL2FXCONST_DBL(0.5477682452772976), FL2FXCONST_DBL(0.5488887119851529), + FL2FXCONST_DBL(0.5500097507977050), FL2FXCONST_DBL(0.5511313611316194), + FL2FXCONST_DBL(0.5522535424050467), FL2FXCONST_DBL(0.5533762940376158), + FL2FXCONST_DBL(0.5544996154504284), FL2FXCONST_DBL(0.5556235060660528), + FL2FXCONST_DBL(0.5567479653085183), FL2FXCONST_DBL(0.5578729926033087), + FL2FXCONST_DBL(0.5589985873773569), FL2FXCONST_DBL(0.5601247490590389), + FL2FXCONST_DBL(0.5612514770781683), FL2FXCONST_DBL(0.5623787708659898), + FL2FXCONST_DBL(0.5635066298551742), FL2FXCONST_DBL(0.5646350534798125), + FL2FXCONST_DBL(0.5657640411754097), FL2FXCONST_DBL(0.5668935923788799), + FL2FXCONST_DBL(0.5680237065285404), FL2FXCONST_DBL(0.5691543830641059), + FL2FXCONST_DBL(0.5702856214266832), FL2FXCONST_DBL(0.5714174210587655), + FL2FXCONST_DBL(0.5725497814042271), FL2FXCONST_DBL(0.5736827019083177), + FL2FXCONST_DBL(0.5748161820176573), FL2FXCONST_DBL(0.5759502211802304), + FL2FXCONST_DBL(0.5770848188453810), FL2FXCONST_DBL(0.5782199744638067), + FL2FXCONST_DBL(0.5793556874875542), FL2FXCONST_DBL(0.5804919573700131), + FL2FXCONST_DBL(0.5816287835659116), FL2FXCONST_DBL(0.5827661655313104), + FL2FXCONST_DBL(0.5839041027235979), FL2FXCONST_DBL(0.5850425946014850), + FL2FXCONST_DBL(0.5861816406250000), FL2FXCONST_DBL(0.5873212402554834), + FL2FXCONST_DBL(0.5884613929555826), FL2FXCONST_DBL(0.5896020981892474), + FL2FXCONST_DBL(0.5907433554217242), FL2FXCONST_DBL(0.5918851641195517), + FL2FXCONST_DBL(0.5930275237505556), FL2FXCONST_DBL(0.5941704337838434), + FL2FXCONST_DBL(0.5953138936897999), FL2FXCONST_DBL(0.5964579029400819), + FL2FXCONST_DBL(0.5976024610076139), FL2FXCONST_DBL(0.5987475673665825), + FL2FXCONST_DBL(0.5998932214924321), FL2FXCONST_DBL(0.6010394228618597), + FL2FXCONST_DBL(0.6021861709528106), FL2FXCONST_DBL(0.6033334652444733), + FL2FXCONST_DBL(0.6044813052172748), FL2FXCONST_DBL(0.6056296903528761), + FL2FXCONST_DBL(0.6067786201341671), FL2FXCONST_DBL(0.6079280940452625), + FL2FXCONST_DBL(0.6090781115714966), FL2FXCONST_DBL(0.6102286721994192), + FL2FXCONST_DBL(0.6113797754167908), FL2FXCONST_DBL(0.6125314207125777), + FL2FXCONST_DBL(0.6136836075769482), FL2FXCONST_DBL(0.6148363355012674), + FL2FXCONST_DBL(0.6159896039780929), FL2FXCONST_DBL(0.6171434125011708), + FL2FXCONST_DBL(0.6182977605654305), FL2FXCONST_DBL(0.6194526476669808), + FL2FXCONST_DBL(0.6206080733031054), FL2FXCONST_DBL(0.6217640369722584), + FL2FXCONST_DBL(0.6229205381740598), FL2FXCONST_DBL(0.6240775764092919), + FL2FXCONST_DBL(0.6252351511798939), FL2FXCONST_DBL(0.6263932619889586), + FL2FXCONST_DBL(0.6275519083407275), FL2FXCONST_DBL(0.6287110897405869), + FL2FXCONST_DBL(0.6298708056950635), FL2FXCONST_DBL(0.6310310557118203), + FL2FXCONST_DBL(0.6321918392996523), FL2FXCONST_DBL(0.6333531559684823), + FL2FXCONST_DBL(0.6345150052293571), FL2FXCONST_DBL(0.6356773865944432), + FL2FXCONST_DBL(0.6368402995770224), FL2FXCONST_DBL(0.6380037436914881), + FL2FXCONST_DBL(0.6391677184533411), FL2FXCONST_DBL(0.6403322233791856), + FL2FXCONST_DBL(0.6414972579867254), FL2FXCONST_DBL(0.6426628217947594), + FL2FXCONST_DBL(0.6438289143231779), FL2FXCONST_DBL(0.6449955350929588), + FL2FXCONST_DBL(0.6461626836261636), FL2FXCONST_DBL(0.6473303594459330), + FL2FXCONST_DBL(0.6484985620764839), FL2FXCONST_DBL(0.6496672910431047), + FL2FXCONST_DBL(0.6508365458721518), FL2FXCONST_DBL(0.6520063260910459), + FL2FXCONST_DBL(0.6531766312282679), FL2FXCONST_DBL(0.6543474608133552), + FL2FXCONST_DBL(0.6555188143768979), FL2FXCONST_DBL(0.6566906914505349), + FL2FXCONST_DBL(0.6578630915669509), FL2FXCONST_DBL(0.6590360142598715), + FL2FXCONST_DBL(0.6602094590640603), FL2FXCONST_DBL(0.6613834255153149), + FL2FXCONST_DBL(0.6625579131504635), FL2FXCONST_DBL(0.6637329215073610), + FL2FXCONST_DBL(0.6649084501248851), FL2FXCONST_DBL(0.6660844985429335), + FL2FXCONST_DBL(0.6672610663024197), FL2FXCONST_DBL(0.6684381529452691), + FL2FXCONST_DBL(0.6696157580144163), FL2FXCONST_DBL(0.6707938810538011), + FL2FXCONST_DBL(0.6719725216083646), FL2FXCONST_DBL(0.6731516792240465), + FL2FXCONST_DBL(0.6743313534477807), FL2FXCONST_DBL(0.6755115438274927), + FL2FXCONST_DBL(0.6766922499120955), FL2FXCONST_DBL(0.6778734712514865), + FL2FXCONST_DBL(0.6790552073965435), FL2FXCONST_DBL(0.6802374578991223), + FL2FXCONST_DBL(0.6814202223120524), FL2FXCONST_DBL(0.6826035001891340), + FL2FXCONST_DBL(0.6837872910851345), FL2FXCONST_DBL(0.6849715945557853), + FL2FXCONST_DBL(0.6861564101577784), FL2FXCONST_DBL(0.6873417374487629), + FL2FXCONST_DBL(0.6885275759873420), FL2FXCONST_DBL(0.6897139253330697), + FL2FXCONST_DBL(0.6909007850464473), FL2FXCONST_DBL(0.6920881546889198), + FL2FXCONST_DBL(0.6932760338228737), FL2FXCONST_DBL(0.6944644220116332), + FL2FXCONST_DBL(0.6956533188194565), FL2FXCONST_DBL(0.6968427238115332), + FL2FXCONST_DBL(0.6980326365539813), FL2FXCONST_DBL(0.6992230566138435), + FL2FXCONST_DBL(0.7004139835590845), FL2FXCONST_DBL(0.7016054169585869), + FL2FXCONST_DBL(0.7027973563821499), FL2FXCONST_DBL(0.7039898014004843), + FL2FXCONST_DBL(0.7051827515852106), FL2FXCONST_DBL(0.7063762065088554), + FL2FXCONST_DBL(0.7075701657448483), FL2FXCONST_DBL(0.7087646288675196), + FL2FXCONST_DBL(0.7099595954520960), FL2FXCONST_DBL(0.7111550650746988), + FL2FXCONST_DBL(0.7123510373123402), FL2FXCONST_DBL(0.7135475117429202), + FL2FXCONST_DBL(0.7147444879452244), FL2FXCONST_DBL(0.7159419654989200), + FL2FXCONST_DBL(0.7171399439845538), FL2FXCONST_DBL(0.7183384229835486), + FL2FXCONST_DBL(0.7195374020782005), FL2FXCONST_DBL(0.7207368808516762), + FL2FXCONST_DBL(0.7219368588880097), FL2FXCONST_DBL(0.7231373357720997), + FL2FXCONST_DBL(0.7243383110897066), FL2FXCONST_DBL(0.7255397844274496), + FL2FXCONST_DBL(0.7267417553728043), FL2FXCONST_DBL(0.7279442235140992), + FL2FXCONST_DBL(0.7291471884405130), FL2FXCONST_DBL(0.7303506497420724), + FL2FXCONST_DBL(0.7315546070096487), FL2FXCONST_DBL(0.7327590598349553), + FL2FXCONST_DBL(0.7339640078105445), FL2FXCONST_DBL(0.7351694505298055), + FL2FXCONST_DBL(0.7363753875869610), FL2FXCONST_DBL(0.7375818185770647), + FL2FXCONST_DBL(0.7387887430959987), FL2FXCONST_DBL(0.7399961607404706), + FL2FXCONST_DBL(0.7412040711080108), FL2FXCONST_DBL(0.7424124737969701), + FL2FXCONST_DBL(0.7436213684065166), FL2FXCONST_DBL(0.7448307545366334), + FL2FXCONST_DBL(0.7460406317881158), FL2FXCONST_DBL(0.7472509997625686), + FL2FXCONST_DBL(0.7484618580624036), FL2FXCONST_DBL(0.7496732062908372), + FL2FXCONST_DBL(0.7508850440518872), FL2FXCONST_DBL(0.7520973709503704), + FL2FXCONST_DBL(0.7533101865919009), FL2FXCONST_DBL(0.7545234905828862), + FL2FXCONST_DBL(0.7557372825305252), FL2FXCONST_DBL(0.7569515620428062), + FL2FXCONST_DBL(0.7581663287285035), FL2FXCONST_DBL(0.7593815821971756), + FL2FXCONST_DBL(0.7605973220591619), FL2FXCONST_DBL(0.7618135479255810), + FL2FXCONST_DBL(0.7630302594083277), FL2FXCONST_DBL(0.7642474561200708), + FL2FXCONST_DBL(0.7654651376742505), FL2FXCONST_DBL(0.7666833036850760), + FL2FXCONST_DBL(0.7679019537675227), FL2FXCONST_DBL(0.7691210875373307), + FL2FXCONST_DBL(0.7703407046110011), FL2FXCONST_DBL(0.7715608046057948), + FL2FXCONST_DBL(0.7727813871397293), FL2FXCONST_DBL(0.7740024518315765), + FL2FXCONST_DBL(0.7752239983008605), FL2FXCONST_DBL(0.7764460261678551), + FL2FXCONST_DBL(0.7776685350535814), FL2FXCONST_DBL(0.7788915245798054), + FL2FXCONST_DBL(0.7801149943690360), FL2FXCONST_DBL(0.7813389440445223), + FL2FXCONST_DBL(0.7825633732302513), FL2FXCONST_DBL(0.7837882815509458), + FL2FXCONST_DBL(0.7850136686320621), FL2FXCONST_DBL(0.7862395340997874), + FL2FXCONST_DBL(0.7874658775810378), FL2FXCONST_DBL(0.7886926987034559), + FL2FXCONST_DBL(0.7899199970954088), FL2FXCONST_DBL(0.7911477723859853), + FL2FXCONST_DBL(0.7923760242049944), FL2FXCONST_DBL(0.7936047521829623), + FL2FXCONST_DBL(0.7948339559511308), FL2FXCONST_DBL(0.7960636351414546), + FL2FXCONST_DBL(0.7972937893865995), FL2FXCONST_DBL(0.7985244183199399), + FL2FXCONST_DBL(0.7997555215755570), FL2FXCONST_DBL(0.8009870987882359), + FL2FXCONST_DBL(0.8022191495934644), FL2FXCONST_DBL(0.8034516736274301), + FL2FXCONST_DBL(0.8046846705270185), FL2FXCONST_DBL(0.8059181399298110), + FL2FXCONST_DBL(0.8071520814740822), FL2FXCONST_DBL(0.8083864947987989), + FL2FXCONST_DBL(0.8096213795436166), FL2FXCONST_DBL(0.8108567353488784), + FL2FXCONST_DBL(0.8120925618556127), FL2FXCONST_DBL(0.8133288587055308), + FL2FXCONST_DBL(0.8145656255410253), FL2FXCONST_DBL(0.8158028620051674), + FL2FXCONST_DBL(0.8170405677417053), FL2FXCONST_DBL(0.8182787423950622), + FL2FXCONST_DBL(0.8195173856103341), FL2FXCONST_DBL(0.8207564970332875), + FL2FXCONST_DBL(0.8219960763103580), FL2FXCONST_DBL(0.8232361230886477), + FL2FXCONST_DBL(0.8244766370159234), FL2FXCONST_DBL(0.8257176177406150), + FL2FXCONST_DBL(0.8269590649118125), FL2FXCONST_DBL(0.8282009781792650), + FL2FXCONST_DBL(0.8294433571933784), FL2FXCONST_DBL(0.8306862016052132), + FL2FXCONST_DBL(0.8319295110664831), FL2FXCONST_DBL(0.8331732852295520), + FL2FXCONST_DBL(0.8344175237474336), FL2FXCONST_DBL(0.8356622262737878), + FL2FXCONST_DBL(0.8369073924629202), FL2FXCONST_DBL(0.8381530219697793), + FL2FXCONST_DBL(0.8393991144499545), FL2FXCONST_DBL(0.8406456695596752), + FL2FXCONST_DBL(0.8418926869558079), FL2FXCONST_DBL(0.8431401662958544), + FL2FXCONST_DBL(0.8443881072379507), FL2FXCONST_DBL(0.8456365094408642), + FL2FXCONST_DBL(0.8468853725639923), FL2FXCONST_DBL(0.8481346962673606), + FL2FXCONST_DBL(0.8493844802116208), FL2FXCONST_DBL(0.8506347240580492), + FL2FXCONST_DBL(0.8518854274685442), FL2FXCONST_DBL(0.8531365901056253), + FL2FXCONST_DBL(0.8543882116324307), FL2FXCONST_DBL(0.8556402917127157), + FL2FXCONST_DBL(0.8568928300108512), FL2FXCONST_DBL(0.8581458261918209), + FL2FXCONST_DBL(0.8593992799212207), FL2FXCONST_DBL(0.8606531908652563), + FL2FXCONST_DBL(0.8619075586907414), FL2FXCONST_DBL(0.8631623830650962), + FL2FXCONST_DBL(0.8644176636563452), FL2FXCONST_DBL(0.8656734001331161), + FL2FXCONST_DBL(0.8669295921646375), FL2FXCONST_DBL(0.8681862394207371), + FL2FXCONST_DBL(0.8694433415718407), FL2FXCONST_DBL(0.8707008982889695), + FL2FXCONST_DBL(0.8719589092437391), FL2FXCONST_DBL(0.8732173741083574), + FL2FXCONST_DBL(0.8744762925556232), FL2FXCONST_DBL(0.8757356642589241), + FL2FXCONST_DBL(0.8769954888922352), FL2FXCONST_DBL(0.8782557661301171), + FL2FXCONST_DBL(0.8795164956477146), FL2FXCONST_DBL(0.8807776771207545), + FL2FXCONST_DBL(0.8820393102255443), FL2FXCONST_DBL(0.8833013946389704), + FL2FXCONST_DBL(0.8845639300384969), FL2FXCONST_DBL(0.8858269161021629), + FL2FXCONST_DBL(0.8870903525085819), FL2FXCONST_DBL(0.8883542389369399), + FL2FXCONST_DBL(0.8896185750669933), FL2FXCONST_DBL(0.8908833605790678), + FL2FXCONST_DBL(0.8921485951540565), FL2FXCONST_DBL(0.8934142784734187), + FL2FXCONST_DBL(0.8946804102191776), FL2FXCONST_DBL(0.8959469900739191), + FL2FXCONST_DBL(0.8972140177207906), FL2FXCONST_DBL(0.8984814928434985), + FL2FXCONST_DBL(0.8997494151263077), FL2FXCONST_DBL(0.9010177842540390), + FL2FXCONST_DBL(0.9022865999120682), FL2FXCONST_DBL(0.9035558617863242), + FL2FXCONST_DBL(0.9048255695632878), FL2FXCONST_DBL(0.9060957229299895), + FL2FXCONST_DBL(0.9073663215740092), FL2FXCONST_DBL(0.9086373651834729), + FL2FXCONST_DBL(0.9099088534470528), FL2FXCONST_DBL(0.9111807860539647), + FL2FXCONST_DBL(0.9124531626939672), FL2FXCONST_DBL(0.9137259830573594), + FL2FXCONST_DBL(0.9149992468349805), FL2FXCONST_DBL(0.9162729537182071), + FL2FXCONST_DBL(0.9175471033989524), FL2FXCONST_DBL(0.9188216955696648), + FL2FXCONST_DBL(0.9200967299233258), FL2FXCONST_DBL(0.9213722061534494), + FL2FXCONST_DBL(0.9226481239540795), FL2FXCONST_DBL(0.9239244830197896), + FL2FXCONST_DBL(0.9252012830456805), FL2FXCONST_DBL(0.9264785237273793), + FL2FXCONST_DBL(0.9277562047610376), FL2FXCONST_DBL(0.9290343258433305), + FL2FXCONST_DBL(0.9303128866714547), FL2FXCONST_DBL(0.9315918869431275), + FL2FXCONST_DBL(0.9328713263565848), FL2FXCONST_DBL(0.9341512046105802), + FL2FXCONST_DBL(0.9354315214043836), FL2FXCONST_DBL(0.9367122764377792), + FL2FXCONST_DBL(0.9379934694110648), FL2FXCONST_DBL(0.9392751000250497), + FL2FXCONST_DBL(0.9405571679810542), FL2FXCONST_DBL(0.9418396729809072), + FL2FXCONST_DBL(0.9431226147269456), FL2FXCONST_DBL(0.9444059929220124), + FL2FXCONST_DBL(0.9456898072694558), FL2FXCONST_DBL(0.9469740574731275), + FL2FXCONST_DBL(0.9482587432373810), FL2FXCONST_DBL(0.9495438642670713), + FL2FXCONST_DBL(0.9508294202675522), FL2FXCONST_DBL(0.9521154109446763), + FL2FXCONST_DBL(0.9534018360047926), FL2FXCONST_DBL(0.9546886951547455), + FL2FXCONST_DBL(0.9559759881018738), FL2FXCONST_DBL(0.9572637145540087), + FL2FXCONST_DBL(0.9585518742194732), FL2FXCONST_DBL(0.9598404668070802), + FL2FXCONST_DBL(0.9611294920261317), FL2FXCONST_DBL(0.9624189495864168), + FL2FXCONST_DBL(0.9637088391982110), FL2FXCONST_DBL(0.9649991605722750), + FL2FXCONST_DBL(0.9662899134198524), FL2FXCONST_DBL(0.9675810974526697), + FL2FXCONST_DBL(0.9688727123829343), FL2FXCONST_DBL(0.9701647579233330), + FL2FXCONST_DBL(0.9714572337870316), FL2FXCONST_DBL(0.9727501396876727), + FL2FXCONST_DBL(0.9740434753393749), FL2FXCONST_DBL(0.9753372404567313), + FL2FXCONST_DBL(0.9766314347548087), FL2FXCONST_DBL(0.9779260579491460), + FL2FXCONST_DBL(0.9792211097557527), FL2FXCONST_DBL(0.9805165898911081), + FL2FXCONST_DBL(0.9818124980721600), FL2FXCONST_DBL(0.9831088340163232), + FL2FXCONST_DBL(0.9844055974414786), FL2FXCONST_DBL(0.9857027880659716), + FL2FXCONST_DBL(0.9870004056086111), FL2FXCONST_DBL(0.9882984497886684), + FL2FXCONST_DBL(0.9895969203258759), FL2FXCONST_DBL(0.9908958169404255), + FL2FXCONST_DBL(0.9921951393529680), FL2FXCONST_DBL(0.9934948872846116), + FL2FXCONST_DBL(0.9947950604569206), FL2FXCONST_DBL(0.9960956585919144), + FL2FXCONST_DBL(0.9973966814120665), FL2FXCONST_DBL(0.9986981286403025)}; + +const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14] = { + {FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), + FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), + FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), + FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366), + FL2FXCONST_DBL(0.7937005259840998), FL2FXCONST_DBL(0.5000000000000000), + FL2FXCONST_DBL(0.6299605249474366), FL2FXCONST_DBL(0.7937005259840998), + FL2FXCONST_DBL(0.5000000000000000), FL2FXCONST_DBL(0.6299605249474366)}, + + {FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), + FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), + FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), + FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408), + FL2FXCONST_DBL(0.9438743126816935), FL2FXCONST_DBL(0.5946035575013605), + FL2FXCONST_DBL(0.7491535384383408), FL2FXCONST_DBL(0.9438743126816935), + FL2FXCONST_DBL(0.5946035575013605), FL2FXCONST_DBL(0.7491535384383408)}, + + {FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), + FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), + FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), + FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393), + FL2FXCONST_DBL(0.5612310241546865), FL2FXCONST_DBL(0.7071067811865476), + FL2FXCONST_DBL(0.8908987181403393), FL2FXCONST_DBL(0.5612310241546865), + FL2FXCONST_DBL(0.7071067811865476), FL2FXCONST_DBL(0.8908987181403393)}, + + {FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), + FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), + FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), + FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477), + FL2FXCONST_DBL(0.6674199270850172), FL2FXCONST_DBL(0.8408964152537145), + FL2FXCONST_DBL(0.5297315471796477), FL2FXCONST_DBL(0.6674199270850172), + FL2FXCONST_DBL(0.8408964152537145), FL2FXCONST_DBL(0.5297315471796477)}}; + +const UCHAR FDKaacEnc_specExpTableComb[4][14] = { + {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, + {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18}, + {1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 18}, + {1, 3, 4, 5, 7, 8, 9, 11, 12, 13, 15, 16, 17, 19}}; #define WTS0 1 #define WTS1 0 #define WTS2 -2 const FIXP_WTB ELDAnalysis512[1536] = { - /* part 0 */ - WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0), WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28), - WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298), WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88), - WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400), WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8), - WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8), WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40), - WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990), WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0), - WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0), WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0), - WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40), WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330), - WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80), WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0), - WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0), WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60), - WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0), WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0), - WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00), WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0), - WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0), WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190), - WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080), WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0), - WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060), WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40), - WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260), WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040), - WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0), WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920), - WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0), WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0), - WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0), WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0), - WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0), WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0), - WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640), WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420), - WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540), WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0), - WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80), WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0), - WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380), WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640), - WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40), WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180), - WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80), WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80), - WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80), WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780), - WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0), WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0), - WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100), WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780), - WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000), WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0), - WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540), WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300), - WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200), WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440), - WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80), WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0), - WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900), WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0), - WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640), WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40), - WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0), WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840), - WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640), WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00), - WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940), WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0), - WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0), WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940), - WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640), WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0), - WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581), WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801), - WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781), WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001), - WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81), WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681), - WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801), WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01), - WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481), WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401), - WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01), WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401), - WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81), WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01), - WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01), WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601), - WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081), WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281), - WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901), WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381), - WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01), WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801), - WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81), WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01), - WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201), WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601), - WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81), WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381), - WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381), WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881), - WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481), WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081), - WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801), WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201), - WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981), WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301), - WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801), WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81), - WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381), WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501), - WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881), WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081), - WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901), WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501), - WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281), WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801), - WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481), WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101), - WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101), WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081), - /* part 1 */ - WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101), WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881), - WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81), WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981), - WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81), WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01), - WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81), WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981), - WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101), WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101), - WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81), WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481), - WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501), WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881), - WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401), WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081), - WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701), WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601), - WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981), WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181), - WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01), WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801), - WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981), WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301), - WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381), WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81), - WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901), WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301), - WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681), WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701), - WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01), WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81), - WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81), WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101), - WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101), WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381), - WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001), WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01), - WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01), WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481), - WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01), WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401), - WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781), WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01), - WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81), WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381), - WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81), WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481), - WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801), WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081), - WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481), WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01), - WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981), WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81), - WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201), WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81), - WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401), WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201), - WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01), WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081), - WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801), WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401), - WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01), WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81), - WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f), WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff), - WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f), WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff), - WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0), WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680), - WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800), WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40), - WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400), WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200), - WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0), WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0), - WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0), WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80), - WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0), WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800), - WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40), WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000), - WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40), WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0), - WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80), WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360), - WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240), WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0), - WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80), WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50), - WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0), WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80), - WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8), WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408), - WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008), WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - /* part 2 */ - WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a), WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c), - WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18), WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4), - WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e), WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c), - WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20), WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc), - WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec), WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c), - WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c), WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68), - WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8), WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68), - WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438), WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48), - WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0), WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8), - WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418), WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0), - WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030), WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0), - WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064), WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c), - WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0), WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40), - WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc), WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4), - WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92), WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330), - WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9), WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4), - WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4), WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4), - WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8), WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428), - WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10), WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0), - WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0), WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80), - WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30), WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0), - WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20), WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380), - WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900), WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80), - WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0), WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400), - WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820), WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640), - WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580), WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00), - WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40), WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840), - WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0), WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0), - WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200), WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00), - WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040), WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f), - WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f), WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff), - WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f), WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f), - WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94), WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c), - WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d), WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e), - WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288), WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90), - WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718), WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0), - WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860), WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470), - WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90), WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880), - WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0), WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60), - WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0), WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40), - WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0), WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440), - WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400), WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0), - WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00), WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0), - WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80), WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0), - WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80), WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00), - WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00), WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff), - WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f), WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff), - WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff), WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f), - WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff), WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f), - WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f), WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff), - WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f), WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff), - WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff), WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff), - WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f), WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff), - WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff), WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f), - WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f), WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f), - WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f), WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f), - WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f), WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100), - WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40), WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880), - WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00), WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80), - WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00), WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140), - WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600), WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800), - WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0), WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0), - WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80), WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0), - WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080), WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40) -}; + /* part 0 */ + WTC0(0xfac5a770), WTC0(0xfaafbab8), WTC0(0xfa996a40), WTC0(0xfa82bbd0), + WTC0(0xfa6bb538), WTC0(0xfa545c38), WTC0(0xfa3cb698), WTC0(0xfa24ca28), + WTC0(0xfa0c9ca8), WTC0(0xf9f433e8), WTC0(0xf9db9580), WTC0(0xf9c2c298), + WTC0(0xf9a9b800), WTC0(0xf9907250), WTC0(0xf976ee38), WTC0(0xf95d2b88), + WTC0(0xf9432d10), WTC0(0xf928f5c0), WTC0(0xf90e8868), WTC0(0xf8f3e400), + WTC0(0xf8d903a0), WTC0(0xf8bde238), WTC0(0xf8a27af0), WTC0(0xf886cde8), + WTC0(0xf86ae020), WTC0(0xf84eb6c0), WTC0(0xf83256f8), WTC0(0xf815c4b8), + WTC0(0xf7f902c0), WTC0(0xf7dc13b0), WTC0(0xf7befa60), WTC0(0xf7a1ba40), + WTC0(0xf78457c0), WTC0(0xf766d780), WTC0(0xf7493d90), WTC0(0xf72b8990), + WTC0(0xf70db5f0), WTC0(0xf6efbd30), WTC0(0xf6d19a20), WTC0(0xf6b352e0), + WTC0(0xf694f8c0), WTC0(0xf6769da0), WTC0(0xf6585310), WTC0(0xf63a28d0), + WTC0(0xf61c2c60), WTC0(0xf5fe6b10), WTC0(0xf5e0f250), WTC0(0xf5c3ceb0), + WTC0(0xf5a70be0), WTC0(0xf58ab5a0), WTC0(0xf56ed7b0), WTC0(0xf5537e40), + WTC0(0xf538b610), WTC0(0xf51e8bf0), WTC0(0xf5050c90), WTC0(0xf4ec4330), + WTC0(0xf4d439b0), WTC0(0xf4bcf9b0), WTC0(0xf4a68ce0), WTC0(0xf490fa80), + WTC0(0xf47c4760), WTC0(0xf4687830), WTC0(0xf4558f00), WTC0(0xf4434fc0), + WTC0(0xf4314070), WTC0(0xf41ee450), WTC0(0xf40bc130), WTC0(0xf3f799c0), + WTC0(0xf3e26d30), WTC0(0xf3cc3d70), WTC0(0xf3b50c80), WTC0(0xf39cdd60), + WTC0(0xf383b440), WTC0(0xf3699550), WTC0(0xf34e84c0), WTC0(0xf33286b0), + WTC0(0xf3159f10), WTC0(0xf2f7d1b0), WTC0(0xf2d92290), WTC0(0xf2b994d0), + WTC0(0xf2992ad0), WTC0(0xf277e6d0), WTC0(0xf255cb60), WTC0(0xf232dd00), + WTC0(0xf20f2240), WTC0(0xf1eaa1d0), WTC0(0xf1c56240), WTC0(0xf19f63d0), + WTC0(0xf178a0f0), WTC0(0xf15113a0), WTC0(0xf128b5c0), WTC0(0xf0ff7fd0), + WTC0(0xf0d56860), WTC0(0xf0aa6610), WTC0(0xf07e6fd0), WTC0(0xf0518190), + WTC0(0xf0239cd0), WTC0(0xeff4c320), WTC0(0xefc4f720), WTC0(0xef945080), + WTC0(0xef62fce0), WTC0(0xef312a40), WTC0(0xeeff05c0), WTC0(0xeecca2c0), + WTC0(0xee99faa0), WTC0(0xee6705a0), WTC0(0xee33bb60), WTC0(0xee000060), + WTC0(0xedcba660), WTC0(0xed967e80), WTC0(0xed605b80), WTC0(0xed293b40), + WTC0(0xecf146a0), WTC0(0xecb8a8a0), WTC0(0xec7f8bc0), WTC0(0xec461260), + WTC0(0xec0c5720), WTC0(0xebd27440), WTC0(0xeb988220), WTC0(0xeb5e7040), + WTC0(0xeb2404c0), WTC0(0xeae90440), WTC0(0xeaad33c0), WTC0(0xea7066c0), + WTC0(0xea327f60), WTC0(0xe9f36000), WTC0(0xe9b2ed60), WTC0(0xe9713920), + WTC0(0xe92e81e0), WTC0(0xe8eb08c0), WTC0(0xe8a70e60), WTC0(0xe862d8e0), + WTC0(0xe81eb340), WTC0(0xe7dae8a0), WTC0(0xe797c1a0), WTC0(0xe7554ca0), + WTC0(0xe7135dc0), WTC0(0xe6d1c6a0), WTC0(0xe6905720), WTC0(0xe64eb9c0), + WTC0(0xe60c7300), WTC0(0xe5c90600), WTC0(0xe583f920), WTC0(0xe53d1ce0), + WTC0(0xe4f48c80), WTC0(0xe4aa6640), WTC0(0xe45ecaa0), WTC0(0xe4120be0), + WTC0(0xe3c4ae60), WTC0(0xe3773860), WTC0(0xe32a2ea0), WTC0(0xe2ddeea0), + WTC0(0xe292af00), WTC0(0xe248a4a0), WTC0(0xe2000140), WTC0(0xe1b8b640), + WTC0(0xe1727440), WTC0(0xe12ce900), WTC0(0xe0e7c280), WTC0(0xe0a2b420), + WTC0(0xe05d76c0), WTC0(0xe017c360), WTC0(0xdfd15440), WTC0(0xdf8a0540), + WTC0(0xdf41d300), WTC0(0xdef8bb40), WTC0(0xdeaebd40), WTC0(0xde63e7c0), + WTC0(0xde185940), WTC0(0xddcc3180), WTC0(0xdd7f9000), WTC0(0xdd329e80), + WTC0(0xdce58e80), WTC0(0xdc989300), WTC0(0xdc4bde40), WTC0(0xdbff96c0), + WTC0(0xdbb3d780), WTC0(0xdb68bb80), WTC0(0xdb1e5c80), WTC0(0xdad4c380), + WTC0(0xda8be840), WTC0(0xda43c1c0), WTC0(0xd9fc4740), WTC0(0xd9b56640), + WTC0(0xd96f0440), WTC0(0xd9290600), WTC0(0xd8e35080), WTC0(0xd89dcd40), + WTC0(0xd8586b40), WTC0(0xd8131940), WTC0(0xd7cdc640), WTC0(0xd7886180), + WTC0(0xd742dc80), WTC0(0xd6fd2780), WTC0(0xd6b73400), WTC0(0xd670fd80), + WTC0(0xd62a8a40), WTC0(0xd5e3e080), WTC0(0xd59d0840), WTC0(0xd5562b80), + WTC0(0xd50f9540), WTC0(0xd4c992c0), WTC0(0xd4846f80), WTC0(0xd4405a80), + WTC0(0xd3fd6580), WTC0(0xd3bba140), WTC0(0xd37b1c80), WTC0(0xd33bb780), + WTC0(0xd2fd2400), WTC0(0xd2bf1240), WTC0(0xd2813300), WTC0(0xd2435ac0), + WTC0(0xd2057fc0), WTC0(0xd1c79a00), WTC0(0xd189a240), WTC0(0xd14b9dc0), + WTC0(0xd10d9e00), WTC0(0xd0cfb580), WTC0(0xd091f6c0), WTC0(0xd0548100), + WTC0(0xd0177f40), WTC0(0xcfdb1cc0), WTC0(0xcf9f84c0), WTC0(0xcf64d780), + WTC0(0xcf2b2b00), WTC0(0xcef29440), WTC0(0xcebb2640), WTC0(0xce84c000), + WTC0(0xce4f0bc0), WTC0(0xce19b200), WTC0(0xcde45d40), WTC0(0xcdaeedc0), + WTC0(0xcd7979c0), WTC0(0xcd4419c0), WTC0(0xcd0ee6c0), WTC0(0xccda0540), + WTC0(0xcca5a500), WTC0(0xcc71f640), WTC0(0xcc3f2800), WTC0(0xcc0d4300), + WTC0(0xcbdc2a00), WTC0(0xcbabbe80), WTC0(0xcb7be200), WTC0(0xcb4c8200), + WTC0(0xcb1d9800), WTC0(0xcaef1d40), WTC0(0xcac10bc0), WTC0(0xca936440), + WTC0(0xca662d00), WTC0(0xca396d40), WTC0(0xca0d2b80), WTC0(0xc9e16f80), + WTC0(0xc9b63f80), WTC0(0xc98ba2c0), WTC0(0xc961a000), WTC0(0xc9383ec0), + WTC0(0xc90a0440), WTC0(0xc8e0d280), WTC0(0xc8b73b80), WTC0(0xc88d4900), + WTC0(0xc86304c0), WTC0(0xc83878c0), WTC0(0xc80dae80), WTC0(0xc7e2afc0), + WTC0(0xc7b78640), WTC0(0xc78c3c40), WTC0(0xc760da80), WTC0(0xc7356640), + WTC0(0xc709de40), WTC0(0xc6de41c0), WTC0(0xc6b28fc0), WTC0(0xc686bd40), + WTC0(0xc65ab600), WTC0(0xc62e6580), WTC0(0xc601b880), WTC0(0xc5d4bac0), + WTC0(0xc5a79640), WTC0(0xc57a76c0), WTC0(0xc54d8780), WTC0(0xc520e840), + WTC0(0xc4f4acc0), WTC0(0xc4c8e880), WTC0(0xc49dad80), WTC0(0xc472e640), + WTC0(0xc44856c0), WTC0(0xc41dc140), WTC0(0xc3f2e940), WTC0(0xc3c7bc00), + WTC0(0xc39c4f00), WTC0(0xc370b9c0), WTC0(0xc34513c0), WTC0(0xc3197940), + WTC0(0xc2ee0a00), WTC0(0xc2c2e640), WTC0(0xc2982d80), WTC0(0xc26df5c0), + WTC0(0xc2444b00), WTC0(0xc21b3940), WTC0(0xc1f2cbc0), WTC0(0xc1cb05c0), + WTC0(0xc1a3e340), WTC0(0xc17d5f00), WTC0(0xc15773c0), WTC0(0xc1320940), + WTC0(0xc10cf480), WTC0(0xc0e80a00), WTC0(0xc0c31f00), WTC0(0xc09e2640), + WTC0(0xc0792ec0), WTC0(0xc0544940), WTC0(0xc02f86c0), WTC0(0xc00b04c0), + WTC0(0xbfe6ed01), WTC0(0xbfc36a01), WTC0(0xbfa0a581), WTC0(0xbf7eb581), + WTC0(0xbf5d9a81), WTC0(0xbf3d5501), WTC0(0xbf1de601), WTC0(0xbeff4801), + WTC0(0xbee17201), WTC0(0xbec45881), WTC0(0xbea7f301), WTC0(0xbe8c3781), + WTC0(0xbe712001), WTC0(0xbe56a381), WTC0(0xbe3cbc01), WTC0(0xbe236001), + WTC0(0xbe0a8581), WTC0(0xbdf22181), WTC0(0xbdda2a01), WTC0(0xbdc29a81), + WTC0(0xbdab7181), WTC0(0xbd94b001), WTC0(0xbd7e5581), WTC0(0xbd686681), + WTC0(0xbd52eb01), WTC0(0xbd3deb81), WTC0(0xbd297181), WTC0(0xbd158801), + WTC0(0xbd023f01), WTC0(0xbcefa601), WTC0(0xbcddcc81), WTC0(0xbcccbd01), + WTC0(0xbcbc7e01), WTC0(0xbcad1501), WTC0(0xbc9e8801), WTC0(0xbc90d481), + WTC0(0xbc83f201), WTC0(0xbc77d601), WTC0(0xbc6c7781), WTC0(0xbc61c401), + WTC0(0xbc57a301), WTC0(0xbc4dfb81), WTC0(0xbc44b481), WTC0(0xbc3bbc01), + WTC0(0xbc330781), WTC0(0xbc2a8c81), WTC0(0xbc224181), WTC0(0xbc1a2401), + WTC0(0xbc123b81), WTC0(0xbc0a8f01), WTC0(0xbc032601), WTC0(0xbbfc0f81), + WTC0(0xbbf56181), WTC0(0xbbef3301), WTC0(0xbbe99981), WTC0(0xbbe49d01), + WTC0(0xbbe03801), WTC0(0xbbdc6481), WTC0(0xbbd91b81), WTC0(0xbbd64d01), + WTC0(0xbbd3e101), WTC0(0xbbd1bd81), WTC0(0xbbcfca81), WTC0(0xbbce0601), + WTC0(0xbbcc8201), WTC0(0xbbcb5301), WTC0(0xbbca8d01), WTC0(0xbbca5081), + WTC0(0xbbcaca01), WTC0(0xbbcc2681), WTC0(0xbbce9181), WTC0(0xbbd21281), + WTC0(0xbbd68c81), WTC0(0xbbdbe201), WTC0(0xbbe1f401), WTC0(0xbbe89901), + WTC0(0xbbef9b81), WTC0(0xbbf6c601), WTC0(0xbbfde481), WTC0(0xbc04e381), + WTC0(0xbc0bcf81), WTC0(0xbc12b801), WTC0(0xbc19ab01), WTC0(0xbc20ae01), + WTC0(0xbc27bd81), WTC0(0xbc2ed681), WTC0(0xbc35f501), WTC0(0xbc3d1801), + WTC0(0xbc444081), WTC0(0xbc4b6e81), WTC0(0xbc52a381), WTC0(0xbc59df81), + WTC0(0xbc612301), WTC0(0xbc686e01), WTC0(0xbc6fc101), WTC0(0xbc771c01), + WTC0(0xbc7e7e01), WTC0(0xbc85e801), WTC0(0xbc8d5901), WTC0(0xbc94d201), + WTC0(0xbc9c5281), WTC0(0xbca3db01), WTC0(0xbcab6c01), WTC0(0xbcb30601), + WTC0(0xbcbaa801), WTC0(0xbcc25181), WTC0(0xbcca0301), WTC0(0xbcd1bb81), + WTC0(0xbcd97c81), WTC0(0xbce14601), WTC0(0xbce91801), WTC0(0xbcf0f381), + WTC0(0xbcf8d781), WTC0(0xbd00c381), WTC0(0xbd08b781), WTC0(0xbd10b381), + WTC0(0xbd18b781), WTC0(0xbd20c401), WTC0(0xbd28d981), WTC0(0xbd30f881), + WTC0(0xbd391f81), WTC0(0xbd414f01), WTC0(0xbd498601), WTC0(0xbd51c481), + WTC0(0xbd5a0b01), WTC0(0xbd625981), WTC0(0xbd6ab101), WTC0(0xbd731081), + WTC0(0xbd7b7781), WTC0(0xbd83e681), WTC0(0xbd8c5c01), WTC0(0xbd94d801), + WTC0(0xbd9d5b81), WTC0(0xbda5e601), WTC0(0xbdae7881), WTC0(0xbdb71201), + WTC0(0xbdbfb281), WTC0(0xbdc85981), WTC0(0xbdd10681), WTC0(0xbdd9b981), + WTC0(0xbde27201), WTC0(0xbdeb3101), WTC0(0xbdf3f701), WTC0(0xbdfcc301), + WTC0(0xbe059481), WTC0(0xbe0e6c01), WTC0(0xbe174781), WTC0(0xbe202801), + WTC0(0xbe290d01), WTC0(0xbe31f701), WTC0(0xbe3ae601), WTC0(0xbe43da81), + WTC0(0xbe4cd381), WTC0(0xbe55d001), WTC0(0xbe5ed081), WTC0(0xbe67d381), + WTC0(0xbe70da01), WTC0(0xbe79e481), WTC0(0xbe82f301), WTC0(0xbe8c0501), + WTC0(0xbe951a81), WTC0(0xbe9e3281), WTC0(0xbea74c81), WTC0(0xbeb06881), + WTC0(0xbeb98681), WTC0(0xbec2a781), WTC0(0xbecbca81), WTC0(0xbed4f081), + WTC0(0xbede1901), WTC0(0xbee74281), WTC0(0xbef06d01), WTC0(0xbef99901), + WTC0(0xbf02c581), WTC0(0xbf0bf381), WTC0(0xbf152381), WTC0(0xbf1e5501), + WTC0(0xbf278801), WTC0(0xbf30bb01), WTC0(0xbf39ee81), WTC0(0xbf432281), + WTC0(0xbf4c5681), WTC0(0xbf558b01), WTC0(0xbf5ec101), WTC0(0xbf67f801), + WTC0(0xbf712f01), WTC0(0xbf7a6681), WTC0(0xbf839d81), WTC0(0xbf8cd481), + WTC0(0xbf960b01), WTC0(0xbf9f4181), WTC0(0xbfa87901), WTC0(0xbfb1b101), + WTC0(0xbfbae981), WTC0(0xbfc42201), WTC0(0xbfcd5a01), WTC0(0xbfd69101), + WTC0(0xbfdfc781), WTC0(0xbfe8fc01), WTC0(0xbff22f81), WTC0(0xbffb6081), + /* part 1 */ + WTC1(0x80093e01), WTC1(0x801b9b01), WTC1(0x802df701), WTC1(0x80405101), + WTC1(0x8052a881), WTC1(0x8064fc81), WTC1(0x80774c81), WTC1(0x80899881), + WTC1(0x809bdf01), WTC1(0x80ae1f81), WTC1(0x80c05a01), WTC1(0x80d28d81), + WTC1(0x80e4bb81), WTC1(0x80f6e481), WTC1(0x81090981), WTC1(0x811b2981), + WTC1(0x812d4481), WTC1(0x813f5981), WTC1(0x81516701), WTC1(0x81636d81), + WTC1(0x81756d81), WTC1(0x81876781), WTC1(0x81995c01), WTC1(0x81ab4b01), + WTC1(0x81bd3401), WTC1(0x81cf1581), WTC1(0x81e0ee81), WTC1(0x81f2bf81), + WTC1(0x82048881), WTC1(0x82164a81), WTC1(0x82280581), WTC1(0x8239b981), + WTC1(0x824b6601), WTC1(0x825d0901), WTC1(0x826ea201), WTC1(0x82803101), + WTC1(0x8291b601), WTC1(0x82a33281), WTC1(0x82b4a601), WTC1(0x82c61101), + WTC1(0x82d77201), WTC1(0x82e8c801), WTC1(0x82fa1181), WTC1(0x830b4f81), + WTC1(0x831c8101), WTC1(0x832da781), WTC1(0x833ec381), WTC1(0x834fd481), + WTC1(0x8360d901), WTC1(0x8371d081), WTC1(0x8382ba01), WTC1(0x83939501), + WTC1(0x83a46181), WTC1(0x83b52101), WTC1(0x83c5d381), WTC1(0x83d67881), + WTC1(0x83e70f01), WTC1(0x83f79681), WTC1(0x84080d81), WTC1(0x84187401), + WTC1(0x8428ca01), WTC1(0x84391081), WTC1(0x84494881), WTC1(0x84597081), + WTC1(0x84698881), WTC1(0x84798f81), WTC1(0x84898481), WTC1(0x84996701), + WTC1(0x84a93801), WTC1(0x84b8f801), WTC1(0x84c8a701), WTC1(0x84d84601), + WTC1(0x84e7d381), WTC1(0x84f74e01), WTC1(0x8506b581), WTC1(0x85160981), + WTC1(0x85254a81), WTC1(0x85347901), WTC1(0x85439601), WTC1(0x8552a181), + WTC1(0x85619a01), WTC1(0x85707f81), WTC1(0x857f5101), WTC1(0x858e0e01), + WTC1(0x859cb781), WTC1(0x85ab4f01), WTC1(0x85b9d481), WTC1(0x85c84801), + WTC1(0x85d6a981), WTC1(0x85e4f801), WTC1(0x85f33281), WTC1(0x86015981), + WTC1(0x860f6e01), WTC1(0x861d7081), WTC1(0x862b6201), WTC1(0x86394301), + WTC1(0x86471281), WTC1(0x8654d001), WTC1(0x86627b01), WTC1(0x86701381), + WTC1(0x867d9a81), WTC1(0x868b1001), WTC1(0x86987581), WTC1(0x86a5ca81), + WTC1(0x86b30f01), WTC1(0x86c04381), WTC1(0x86cd6681), WTC1(0x86da7901), + WTC1(0x86e77b81), WTC1(0x86f46d81), WTC1(0x87014f81), WTC1(0x870e2301), + WTC1(0x871ae981), WTC1(0x8727a381), WTC1(0x87345381), WTC1(0x8740f681), + WTC1(0x874d8681), WTC1(0x8759fd01), WTC1(0x87665481), WTC1(0x87729701), + WTC1(0x877ede01), WTC1(0x878b4301), WTC1(0x8797dd81), WTC1(0x87a48b01), + WTC1(0x87b0ef01), WTC1(0x87bcab81), WTC1(0x87c76201), WTC1(0x87d0ca81), + WTC1(0x87fdd781), WTC1(0x881dd301), WTC1(0x88423301), WTC1(0x886a8a81), + WTC1(0x88962981), WTC1(0x88c45e81), WTC1(0x88f47901), WTC1(0x8925f101), + WTC1(0x89586901), WTC1(0x898b8301), WTC1(0x89bee581), WTC1(0x89f26101), + WTC1(0x8a25f301), WTC1(0x8a599a81), WTC1(0x8a8d5801), WTC1(0x8ac13381), + WTC1(0x8af53e81), WTC1(0x8b298b81), WTC1(0x8b5e2c81), WTC1(0x8b933001), + WTC1(0x8bc8a401), WTC1(0x8bfe9401), WTC1(0x8c350d01), WTC1(0x8c6c1b01), + WTC1(0x8ca3cb01), WTC1(0x8cdc2901), WTC1(0x8d154081), WTC1(0x8d4f1b01), + WTC1(0x8d89be81), WTC1(0x8dc53001), WTC1(0x8e017581), WTC1(0x8e3e9481), + WTC1(0x8e7c9301), WTC1(0x8ebb7581), WTC1(0x8efb4181), WTC1(0x8f3bfb01), + WTC1(0x8f7da401), WTC1(0x8fc03f01), WTC1(0x9003ce81), WTC1(0x90485401), + WTC1(0x908dd101), WTC1(0x90d44781), WTC1(0x911bb981), WTC1(0x91642781), + WTC1(0x91ad9281), WTC1(0x91f7f981), WTC1(0x92435d01), WTC1(0x928fbe01), + WTC1(0x92dd1b01), WTC1(0x932b7501), WTC1(0x937acb01), WTC1(0x93cb1c81), + WTC1(0x941c6901), WTC1(0x946eaf81), WTC1(0x94c1ee01), WTC1(0x95162381), + WTC1(0x956b4f81), WTC1(0x95c17081), WTC1(0x96188501), WTC1(0x96708b81), + WTC1(0x96c98381), WTC1(0x97236b01), WTC1(0x977e4181), WTC1(0x97da0481), + WTC1(0x9836b201), WTC1(0x98944901), WTC1(0x98f2c601), WTC1(0x99522801), + WTC1(0x99b26c81), WTC1(0x9a139101), WTC1(0x9a759301), WTC1(0x9ad87081), + WTC1(0x9b3c2801), WTC1(0x9ba0b701), WTC1(0x9c061b81), WTC1(0x9c6c5481), + WTC1(0x9cd35f81), WTC1(0x9d3b3b81), WTC1(0x9da3e601), WTC1(0x9e0d5e01), + WTC1(0x9e779f81), WTC1(0x9ee2a901), WTC1(0x9f4e7801), WTC1(0x9fbb0981), + WTC1(0xa0285d81), WTC1(0xa0967201), WTC1(0xa1054701), WTC1(0xa174da81), + WTC1(0xa1e52a81), WTC1(0xa2563501), WTC1(0xa2c7f801), WTC1(0xa33a7201), + WTC1(0xa3ada281), WTC1(0xa4218801), WTC1(0xa4962181), WTC1(0xa50b6e81), + WTC1(0xa5816e81), WTC1(0xa5f81f81), WTC1(0xa66f8201), WTC1(0xa6e79401), + WTC1(0xa7605601), WTC1(0xa7d9c681), WTC1(0xa853e501), WTC1(0xa8ceb201), + WTC1(0xa94a2c01), WTC1(0xa9c65401), WTC1(0xaa432981), WTC1(0xaac0ad01), + WTC1(0xab3edf01), WTC1(0xabbdc001), WTC1(0xac3d5001), WTC1(0xacbd9081), + WTC1(0xad3e8101), WTC1(0xadc02281), WTC1(0xae427481), WTC1(0xaec57801), + WTC1(0xaf492f01), WTC1(0xafcd9a81), WTC1(0xb052bc01), WTC1(0xb0d89401), + WTC1(0xb15f2381), WTC1(0xb1e66a01), WTC1(0xb26e6881), WTC1(0xb2f71f01), + WTC1(0xb3808d81), WTC1(0xb40ab501), WTC1(0xb4959501), WTC1(0xb5212e81), + WTC1(0x4a6cf67f), WTC1(0x49dffeff), WTC1(0x495265ff), WTC1(0x48c4277f), + WTC1(0x4835407f), WTC1(0x47a5aeff), WTC1(0x471570ff), WTC1(0x468484ff), + WTC1(0x45f2eaff), WTC1(0x4560a2ff), WTC1(0x44cdad7f), WTC1(0x443a0c7f), + WTC1(0x43a5c07f), WTC1(0x4310caff), WTC1(0x427b2bff), WTC1(0x41e4e3ff), + WTC1(0x414df2ff), WTC1(0x40b6557f), WTC1(0x401e06ff), WTC1(0x3f8503c0), + WTC1(0x3eeb4e00), WTC1(0x3e50ebc0), WTC1(0x3db5e680), WTC1(0x3d1a4680), + WTC1(0x3c7e10c0), WTC1(0x3be14cc0), WTC1(0x3b4402c0), WTC1(0x3aa63800), + WTC1(0x3a07e840), WTC1(0x39690880), WTC1(0x38c98700), WTC1(0x38295b40), + WTC1(0x37888a80), WTC1(0x36e71d40), WTC1(0x36451d80), WTC1(0x35a29400), + WTC1(0x34ff8800), WTC1(0x345c04c0), WTC1(0x33b81940), WTC1(0x3313d200), + WTC1(0x326f3800), WTC1(0x31ca5600), WTC1(0x31253840), WTC1(0x307fe8c0), + WTC1(0x2fda6e40), WTC1(0x2f34ce40), WTC1(0x2e8f0e40), WTC1(0x2de92ec0), + WTC1(0x2d432780), WTC1(0x2c9cea40), WTC1(0x2bf66300), WTC1(0x2b4f88c0), + WTC1(0x2aa864c0), WTC1(0x2a010240), WTC1(0x29596e40), WTC1(0x28b1ba80), + WTC1(0x2809ff40), WTC1(0x27625b80), WTC1(0x26baf580), WTC1(0x2613e7c0), + WTC1(0x256d3dc0), WTC1(0x24c70300), WTC1(0x24214380), WTC1(0x237c0800), + WTC1(0x22d75400), WTC1(0x22332a80), WTC1(0x218f8cc0), WTC1(0x20ec7e40), + WTC1(0x204a04c0), WTC1(0x1fa82540), WTC1(0x1f06e300), WTC1(0x1e664000), + WTC1(0x1dc63bc0), WTC1(0x1d26d3c0), WTC1(0x1c8803a0), WTC1(0x1be9cc40), + WTC1(0x1b4c34c0), WTC1(0x1aaf4480), WTC1(0x1a130260), WTC1(0x197774a0), + WTC1(0x18dca260), WTC1(0x184294e0), WTC1(0x17a95840), WTC1(0x1710fd80), + WTC1(0x16799ce0), WTC1(0x15e35340), WTC1(0x154e41a0), WTC1(0x14ba8360), + WTC1(0x14282be0), WTC1(0x13975100), WTC1(0x13080aa0), WTC1(0x127a6240), + WTC1(0x11ee50a0), WTC1(0x1163cc80), WTC1(0x10dacb20), WTC1(0x105333a0), + WTC1(0x0fccdb30), WTC1(0x0f478f40), WTC1(0x0ec31700), WTC1(0x0e3f4e80), + WTC1(0x0dbc27f0), WTC1(0x0d399000), WTC1(0x0cb76d00), WTC1(0x0c359d50), + WTC1(0x0bb3fd50), WTC1(0x0b326bd0), WTC1(0x0ab0ca80), WTC1(0x0a2f0dc0), + WTC1(0x09ad40c0), WTC1(0x092b7a90), WTC1(0x08a9db80), WTC1(0x08285c80), + WTC1(0x07a6c7b8), WTC1(0x0724e4e0), WTC1(0x06a27b80), WTC1(0x061f52f8), + WTC1(0x059b2ad0), WTC1(0x0515b568), WTC1(0x048ea058), WTC1(0x04066408), + WTC1(0x037e52d8), WTC1(0x02f7d3c8), WTC1(0x0274614c), WTC1(0x01f63008), + WTC1(0x0180403a), WTC1(0x0115c442), WTC1(0x00ba09e2), WTC1(0x006f077c), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + /* part 2 */ + WTC2(0xfff36be1), WTC2(0xffdafbc1), WTC2(0xffc28035), WTC2(0xffa9fe8a), + WTC2(0xff917c08), WTC2(0xff78fdfc), WTC2(0xff6089af), WTC2(0xff48246c), + WTC2(0xff2fd37f), WTC2(0xff179c31), WTC2(0xfeff83b6), WTC2(0xfee78d18), + WTC2(0xfecfb93e), WTC2(0xfeb808f2), WTC2(0xfea07d06), WTC2(0xfe8916b4), + WTC2(0xfe71d7a0), WTC2(0xfe5ac174), WTC2(0xfe43d5d6), WTC2(0xfe2d167e), + WTC2(0xfe16852e), WTC2(0xfe0023a6), WTC2(0xfde9f3f8), WTC2(0xfdd3ff7c), + WTC2(0xfdbe56c0), WTC2(0xfda90aa8), WTC2(0xfd942b78), WTC2(0xfd7fbb20), + WTC2(0xfd6bad50), WTC2(0xfd57f510), WTC2(0xfd44857c), WTC2(0xfd3153fc), + WTC2(0xfd1e5840), WTC2(0xfd0b8a0c), WTC2(0xfcf8e180), WTC2(0xfce65eec), + WTC2(0xfcd40ad0), WTC2(0xfcc1ee0c), WTC2(0xfcb011e8), WTC2(0xfc9e896c), + WTC2(0xfc8d716c), WTC2(0xfc7ce720), WTC2(0xfc6d072c), WTC2(0xfc5de09c), + WTC2(0xfc4f74e8), WTC2(0xfc41c4e8), WTC2(0xfc34d0dc), WTC2(0xfc288a68), + WTC2(0xfc1cd49c), WTC2(0xfc1191e0), WTC2(0xfc06a4d0), WTC2(0xfbfbf3e8), + WTC2(0xfbf16990), WTC2(0xfbe6f068), WTC2(0xfbdc7428), WTC2(0xfbd1fc68), + WTC2(0xfbc7ac50), WTC2(0xfbbda868), WTC2(0xfbb41500), WTC2(0xfbab1438), + WTC2(0xfba2c5f8), WTC2(0xfb9b4a00), WTC2(0xfb94bfa8), WTC2(0xfb8f3b48), + WTC2(0xfb8ac638), WTC2(0xfb876970), WTC2(0xfb852d20), WTC2(0xfb840ae0), + WTC2(0xfb83ed60), WTC2(0xfb84bec0), WTC2(0xfb866918), WTC2(0xfb88d4a8), + WTC2(0xfb8be810), WTC2(0xfb8f89d0), WTC2(0xfb93a080), WTC2(0xfb981418), + WTC2(0xfb9ccdf0), WTC2(0xfba1b770), WTC2(0xfba6bae0), WTC2(0xfbabd5c0), + WTC2(0xfbb118d8), WTC2(0xfbb695c0), WTC2(0xfbbc5e90), WTC2(0xfbc29030), + WTC2(0xfbc95268), WTC2(0xfbd0cd78), WTC2(0xfbd929c8), WTC2(0xfbe294d0), + WTC2(0xfbed4108), WTC2(0xfbf96118), WTC2(0xfc0726c8), WTC2(0xfc16b064), + WTC2(0xfc280890), WTC2(0xfc3b3920), WTC2(0xfc504a98), WTC2(0xfc67271c), + WTC2(0xfc7f9a74), WTC2(0xfc996f18), WTC2(0xfcb46eb8), WTC2(0xfcd050b0), + WTC2(0xfcecba24), WTC2(0xfd094f64), WTC2(0xfd25b720), WTC2(0xfd41ce40), + WTC2(0xfd5da7f8), WTC2(0xfd7959d8), WTC2(0xfd94fb74), WTC2(0xfdb0d3fc), + WTC2(0xfdcd5a34), WTC2(0xfdeb06e4), WTC2(0xfe0a5184), WTC2(0xfe2b92c4), + WTC2(0xfe4f0486), WTC2(0xfe74df54), WTC2(0xfe9d5886), WTC2(0xfec85b92), + WTC2(0xfef58a16), WTC2(0xff248275), WTC2(0xff54e401), WTC2(0xff866330), + WTC2(0xffb8c99b), WTC2(0xffebe1c9), WTC2(0x001f786a), WTC2(0x00538bf9), + WTC2(0x00884cbc), WTC2(0x00bded23), WTC2(0x00f49f54), WTC2(0x012c8ee4), + WTC2(0x0165e0d2), WTC2(0x01a0b9d6), WTC2(0x01dd3d80), WTC2(0x021b74d4), + WTC2(0x025b4e48), WTC2(0x029cb730), WTC2(0x02df9d0c), WTC2(0x0323f1a4), + WTC2(0x0369ab00), WTC2(0x03b0bf5c), WTC2(0x03f925a0), WTC2(0x0442e3d8), + WTC2(0x048e0f40), WTC2(0x04dabdb0), WTC2(0x05290430), WTC2(0x0578e428), + WTC2(0x05ca4b60), WTC2(0x061d26c0), WTC2(0x067163d8), WTC2(0x06c6ff10), + WTC2(0x071e03b0), WTC2(0x07767da0), WTC2(0x07d07918), WTC2(0x082c08e0), + WTC2(0x08894660), WTC2(0x08e84b70), WTC2(0x094930b0), WTC2(0x09abf8d0), + WTC2(0x0a109020), WTC2(0x0a76e210), WTC2(0x0adeda50), WTC2(0x0b486b80), + WTC2(0x0bb38f00), WTC2(0x0c203e80), WTC2(0x0c8e73e0), WTC2(0x0cfe2c30), + WTC2(0x0d6f6820), WTC2(0x0de22850), WTC2(0x0e566d90), WTC2(0x0ecc3dd0), + WTC2(0x0f43a3a0), WTC2(0x0fbca9f0), WTC2(0x10375b80), WTC2(0x10b3be20), + WTC2(0x1131d280), WTC2(0x11b19960), WTC2(0x123313a0), WTC2(0x12b64380), + WTC2(0x133b2d00), WTC2(0x13c1d440), WTC2(0x144a3d60), WTC2(0x14d46900), + WTC2(0x15605480), WTC2(0x15edfd20), WTC2(0x167d6040), WTC2(0x170e7e80), + WTC2(0x17a15b80), WTC2(0x1835fb00), WTC2(0x18cc60a0), WTC2(0x19648dc0), + WTC2(0x19fe80e0), WTC2(0x1a9a38a0), WTC2(0x1b37b3e0), WTC2(0x1bd6f400), + WTC2(0x1c77fd20), WTC2(0x1d1ad400), WTC2(0x1dbf7c80), WTC2(0x1e65f820), + WTC2(0x1f0e4540), WTC2(0x1fb861e0), WTC2(0x20644cc0), WTC2(0x21120640), + WTC2(0x21c19240), WTC2(0x2272f480), WTC2(0x23263000), WTC2(0x23db4580), + WTC2(0x24923340), WTC2(0x254af700), WTC2(0x26058e80), WTC2(0x26c1fa00), + WTC2(0x27803d00), WTC2(0x28405a40), WTC2(0x29025500), WTC2(0x29c62d40), + WTC2(0x2a8be0c0), WTC2(0x2b536cc0), WTC2(0x2c1ccf80), WTC2(0x2ce80840), + WTC2(0x2db519c0), WTC2(0x2e840600), WTC2(0x2f54cf80), WTC2(0x302775c0), + WTC2(0x30fbf640), WTC2(0x31d24e00), WTC2(0x32aa7a00), WTC2(0x338479c0), + WTC2(0x34604e40), WTC2(0x353df900), WTC2(0x361d7ac0), WTC2(0x36fed200), + WTC2(0x37e1fb40), WTC2(0x38c6f240), WTC2(0x39adb2c0), WTC2(0x3a963a00), + WTC2(0x3b808740), WTC2(0x3c6c9880), WTC2(0x3d5a6cc0), WTC2(0x3e4a0040), + WTC2(0x3f3b4bc0), WTC2(0x402e48ff), WTC2(0x4122f17f), WTC2(0x42193f7f), + WTC2(0x43112eff), WTC2(0x440abbff), WTC2(0x4505e2ff), WTC2(0x46029e7f), + WTC2(0x4700e9ff), WTC2(0x4800bfff), WTC2(0x49021bff), WTC2(0x4a050eff), + WTC2(0x4b09bc7f), WTC2(0x4c104aff), WTC2(0x4d18df7f), WTC2(0x4e23a07f), + WTC2(0x4f30b2ff), WTC2(0x50403c7f), WTC2(0x515262ff), WTC2(0x52674b7f), + WTC2(0x001678b2), WTC2(0x00061a3b), WTC2(0xfffb4622), WTC2(0xfff5ea94), + WTC2(0xfff5f5b9), WTC2(0xfffb55bd), WTC2(0x0005f8cb), WTC2(0x0015cd0c), + WTC2(0x002ac0ac), WTC2(0x0044c1d5), WTC2(0x0063beb2), WTC2(0x0087a56d), + WTC2(0x00b06431), WTC2(0x00dde929), WTC2(0x01102280), WTC2(0x0146fe5e), + WTC2(0x01826af2), WTC2(0x01c25662), WTC2(0x0206aedc), WTC2(0x024f6288), + WTC2(0x029c5f94), WTC2(0x02ed9424), WTC2(0x0342ee6c), WTC2(0x039c5c90), + WTC2(0x03f9ccbc), WTC2(0x045b2d18), WTC2(0x04c06bd8), WTC2(0x05297718), + WTC2(0x05963d10), WTC2(0x0606abe8), WTC2(0x067ab1c0), WTC2(0x06f23cd0), + WTC2(0x076d3b40), WTC2(0x07eb9b38), WTC2(0x086d4ae0), WTC2(0x08f23860), + WTC2(0x097a51f0), WTC2(0x0a0585b0), WTC2(0x0a93c1d0), WTC2(0x0b24f470), + WTC2(0x0bb90bc0), WTC2(0x0c4ff5f0), WTC2(0x0ce9a130), WTC2(0x0d85fb90), + WTC2(0x0e24f360), WTC2(0x0ec676b0), WTC2(0x0f6a73b0), WTC2(0x1010d880), + WTC2(0x10b99360), WTC2(0x11649280), WTC2(0x1211c400), WTC2(0x12c115e0), + WTC2(0x137276a0), WTC2(0x1425d420), WTC2(0x14db1ca0), WTC2(0x15923e60), + WTC2(0x164b2780), WTC2(0x1705c620), WTC2(0x17c20860), WTC2(0x187fdca0), + WTC2(0x193f30e0), WTC2(0x19fff340), WTC2(0x1ac21200), WTC2(0x1b857b40), + WTC2(0x1c4a1d40), WTC2(0x1d0fe600), WTC2(0x1dd6c3e0), WTC2(0x1e9ea4e0), + WTC2(0x1f677740), WTC2(0x20312940), WTC2(0x20fba8c0), WTC2(0x21c6e440), + WTC2(0x2292c9c0), WTC2(0x235f4780), WTC2(0x242c4b80), WTC2(0x24f9c400), + WTC2(0x25c79f40), WTC2(0x2695cb40), WTC2(0x27643680), WTC2(0x2832cec0), + WTC2(0x29018240), WTC2(0x29d03f80), WTC2(0x2a9ef480), WTC2(0x2b6d8f00), + WTC2(0x2c3bfdc0), WTC2(0x2d0a2ec0), WTC2(0x2dd81000), WTC2(0x2ea58fc0), + WTC2(0x2f729c40), WTC2(0x303f2380), WTC2(0x310b1400), WTC2(0x31d65b80), + WTC2(0x32a0e840), WTC2(0x336aa8c0), WTC2(0x34338ac0), WTC2(0x34fb7cc0), + WTC2(0x35c26cc0), WTC2(0x36884900), WTC2(0x374cff80), WTC2(0x38107e80), + WTC2(0x38d2b440), WTC2(0x39938ec0), WTC2(0x3a52fc40), WTC2(0x3b10eb00), + WTC2(0x3bcd4900), WTC2(0x3c880480), WTC2(0x3d410bc0), WTC2(0x3df84d00), + WTC2(0x3eadb600), WTC2(0x3f613540), WTC2(0x4012b8ff), WTC2(0x40c22eff), + WTC2(0x416f85ff), WTC2(0x421aab7f), WTC2(0x42c38e7f), WTC2(0x436a1c7f), + WTC2(0x440e437f), WTC2(0x44aff27f), WTC2(0x454f167f), WTC2(0x45eb9eff), + WTC2(0x468578ff), WTC2(0x471c937f), WTC2(0x47b0dc7f), WTC2(0x484241ff), + WTC2(0x48d0b1ff), WTC2(0x495c1a7f), WTC2(0x49e46a7f), WTC2(0x4a698f7f), + WTC2(0x4aeb77ff), WTC2(0x4b6a11ff), WTC2(0x4be54b7f), WTC2(0x4c5d12ff), + WTC2(0x4cd155ff), WTC2(0x4d4203ff), WTC2(0x4daf09ff), WTC2(0x4e18567f), + WTC2(0x4e7dd77f), WTC2(0x4edf7b7f), WTC2(0x4f3d307f), WTC2(0x4f96e47f), + WTC2(0x4fec85ff), WTC2(0x503e02ff), WTC2(0x508b497f), WTC2(0x50d447ff), + WTC2(0x5118ec7f), WTC2(0x515924ff), WTC2(0x5194dfff), WTC2(0x51cc0b7f), + WTC2(0x51fe95ff), WTC2(0x522c6cff), WTC2(0x52557eff), WTC2(0x5279b9ff), + WTC2(0x52990c7f), WTC2(0x52b364ff), WTC2(0x52c8b07f), WTC2(0x52d8ddff), + WTC2(0x52e3db7f), WTC2(0x52e996ff), WTC2(0x52e9ff7f), WTC2(0x52e501ff), + WTC2(0x52da8cff), WTC2(0x52ca8f7f), WTC2(0x52b4f67f), WTC2(0x5299b07f), + WTC2(0x5278ac7f), WTC2(0x5251d77f), WTC2(0x52251fff), WTC2(0x51f274ff), + WTC2(0x51b9c37f), WTC2(0x517af9ff), WTC2(0x5136077f), WTC2(0x50ead8ff), + WTC2(0x50995cff), WTC2(0x504181ff), WTC2(0x4fe335ff), WTC2(0x4f7e677f), + WTC2(0x4f1303ff), WTC2(0x4ea0f9ff), WTC2(0x4e2837ff), WTC2(0x4da8ab7f), + WTC2(0x4d2242ff), WTC2(0x4c94ecff), WTC2(0x4c0096ff), WTC2(0x4b652f7f), + WTC2(0x4ac2a4ff), WTC2(0x4a18e4ff), WTC2(0x4967ddff), WTC2(0x48af7e7f), + WTC2(0x47efb3ff), WTC2(0x47286cff), WTC2(0x4659ad7f), WTC2(0x45856f7f), + WTC2(0x44afa3ff), WTC2(0x43dc507f), WTC2(0x430f657f), WTC2(0x424ad47f), + WTC2(0x418e927f), WTC2(0x40da7bff), WTC2(0x402e6f7f), WTC2(0x3f8a3100), + WTC2(0x3eed6f40), WTC2(0x3e57d700), WTC2(0x3dc914c0), WTC2(0x3d40cc40), + WTC2(0x3cbe98c0), WTC2(0x3c421540), WTC2(0x3bcadbc0), WTC2(0x3b588880), + WTC2(0x3aeab780), WTC2(0x3a810540), WTC2(0x3a1b0e00), WTC2(0x39b86d00), + WTC2(0x3958bcc0), WTC2(0x38fb9700), WTC2(0x38a095c0), WTC2(0x38473d80), + WTC2(0x37eeff40), WTC2(0x37974b40), WTC2(0x373f9500), WTC2(0x36e7ae00), + WTC2(0x368fc4c0), WTC2(0x36380b80), WTC2(0x35e0b300), WTC2(0x3589c140), + WTC2(0x35331180), WTC2(0x34dc7c80), WTC2(0x3485dc80), WTC2(0x342f1600), + WTC2(0x33d81780), WTC2(0x3380d0c0), WTC2(0x33293100), WTC2(0x32d11800), + WTC2(0x32785780), WTC2(0x321ec0c0), WTC2(0x31c42680), WTC2(0x316885c0), + WTC2(0x310c0580), WTC2(0x30aecec0), WTC2(0x30510940), WTC2(0x2ff2b8c0), + WTC2(0x2f93bf40), WTC2(0x2f33fc00), WTC2(0x2ed350c0), WTC2(0x2e71ba80), + WTC2(0x2e0f5340), WTC2(0x2dac35c0), WTC2(0x2d487c80), WTC2(0x2ce431c0), + WTC2(0x2c7f4fc0), WTC2(0x2c19d080), WTC2(0x2bb3ad80), WTC2(0x2b4ce080), + WTC2(0x2ae56340), WTC2(0x2a7d2f80), WTC2(0x2a143f00), WTC2(0x29aa8b40)}; const FIXP_WTB ELDAnalysis480[1440] = { - WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110), WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28), - WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8), WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0), - WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8), WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148), - WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0), WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0), - WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0), WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250), - WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0), WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390), - WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30), WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0), - WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0), WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370), - WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60), WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820), - WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670), WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0), - WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450), WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0), - WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10), WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460), - WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440), WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640), - WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120), WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0), - WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000), WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0), - WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0), WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0), - WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300), WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0), - WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0), WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520), - WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0), WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0), - WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0), WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000), - WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980), WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0), - WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640), WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600), - WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740), WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00), - WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80), WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0), - WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300), WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40), - WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80), WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80), - WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0), WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40), - WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0), WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780), - WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0), WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0), - WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180), WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00), - WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100), WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0), - WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80), WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0), - WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80), WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0), - WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0), WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00), - WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140), WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0), - WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0), WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0), - WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880), WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01), - WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301), WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81), - WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001), WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381), - WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281), WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81), - WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001), WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301), - WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01), WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01), - WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81), WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281), - WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501), WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81), - WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481), WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301), - WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801), WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381), - WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01), WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881), - WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81), WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81), - WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481), WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001), - WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81), WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281), - WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01), WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801), - WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201), WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01), - WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01), WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701), - WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301), WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681), - WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301), WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01), - WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581), WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181), - WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801), WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01), - WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501), WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01), - WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81), WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01), - WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181), WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01), - /* part 1 */ - WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481), WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01), - WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401), WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01), - WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81), WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681), - WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401), WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901), - WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301), WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01), - WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881), WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801), - WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01), WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981), - WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581), WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201), - WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381), WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881), - WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81), WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581), - WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81), WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801), - WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581), WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01), - WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601), WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281), - WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201), WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601), - WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81), WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81), - WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481), WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101), - WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01), WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01), - WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981), WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781), - WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781), WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201), - WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81), WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001), - WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301), WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01), - WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981), WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81), - WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681), WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281), - WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081), WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81), - WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081), WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081), - WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01), WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001), - WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001), WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01), - WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01), WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181), - WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001), WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601), - WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181), WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381), - WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f), WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f), - WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff), WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f), - WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00), WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500), - WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0), WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00), - WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900), WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280), - WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180), WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080), - WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0), WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00), - WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0), WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800), - WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140), WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0), - WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840), WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300), - WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60), WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0), - WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90), WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40), - WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410), WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0), - WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348), WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698), - WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e), WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), - /* part 2 */ - WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1), WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c), - WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a), WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce), - WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc), WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834), - WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4), WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc), - WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0), WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0), - WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060), WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150), - WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740), WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48), - WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40), WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0), - WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8), WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0), - WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08), WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8), - WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0), WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0), - WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8), WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc), - WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0), WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8), - WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc), WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7), - WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d), WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6), - WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4), WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4), - WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0), WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0), - WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0), WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0), - WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40), WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600), - WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510), WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10), - WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0), WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300), - WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360), WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0), - WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60), WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540), - WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640), WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80), - WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840), WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080), - WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680), WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0), - WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0), WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080), - WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480), WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff), - WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff), WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f), - WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff), WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff), - WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064), WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c), - WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74), WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70), - WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4), WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78), - WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020), WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0), - WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900), WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0), - WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400), WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60), - WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0), WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020), - WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00), WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80), - WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440), WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040), - WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00), WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0), - WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340), WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000), - WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640), WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0), - WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0), WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480), - WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f), WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f), - WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f), WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff), - WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff), WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f), - WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff), WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f), - WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff), WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff), - WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff), WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff), - WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f), WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f), - WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff), WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff), - WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f), WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f), - WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f), WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff), - WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100), WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0), - WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0), WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0), - WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0), WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00), - WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0), WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880), - WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0), WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80), - WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480), WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700), - WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0), WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0) + WTC0(0xfacfbef0), WTC0(0xfab88c18), WTC0(0xfaa0e520), WTC0(0xfa88d110), + WTC0(0xfa7056e8), WTC0(0xfa577db0), WTC0(0xfa3e4c70), WTC0(0xfa24ca28), + WTC0(0xfa0afde0), WTC0(0xf9f0eea0), WTC0(0xf9d6a2c8), WTC0(0xf9bc1ab8), + WTC0(0xf9a15230), WTC0(0xf9864510), WTC0(0xf96af058), WTC0(0xf94f55c0), + WTC0(0xf93378e0), WTC0(0xf9175d80), WTC0(0xf8fb0468), WTC0(0xf8de68b8), + WTC0(0xf8c18438), WTC0(0xf8a450d8), WTC0(0xf886cde8), WTC0(0xf8690148), + WTC0(0xf84af148), WTC0(0xf82ca410), WTC0(0xf80e1e18), WTC0(0xf7ef62a0), + WTC0(0xf7d074e0), WTC0(0xf7b15870), WTC0(0xf7921240), WTC0(0xf772a7a0), + WTC0(0xf7531e50), WTC0(0xf7337820), WTC0(0xf713afd0), WTC0(0xf6f3bea0), + WTC0(0xf6d39dc0), WTC0(0xf6b352e0), WTC0(0xf692f280), WTC0(0xf6729250), + WTC0(0xf65247a0), WTC0(0xf63224c0), WTC0(0xf6123a00), WTC0(0xf5f297c0), + WTC0(0xf5d34dd0), WTC0(0xf5b46b10), WTC0(0xf595fd90), WTC0(0xf5781390), + WTC0(0xf55abba0), WTC0(0xf53e0510), WTC0(0xf521ff70), WTC0(0xf506ba30), + WTC0(0xf4ec4330), WTC0(0xf4d2a680), WTC0(0xf4b9efe0), WTC0(0xf4a22ac0), + WTC0(0xf48b5f70), WTC0(0xf4759310), WTC0(0xf460cde0), WTC0(0xf44cfcc0), + WTC0(0xf439aff0), WTC0(0xf4264e00), WTC0(0xf4123d90), WTC0(0xf3fd1370), + WTC0(0xf3e6be00), WTC0(0xf3cf41a0), WTC0(0xf3b6a030), WTC0(0xf39cdd60), + WTC0(0xf381fe00), WTC0(0xf3660760), WTC0(0xf348fe70), WTC0(0xf32ae820), + WTC0(0xf30bc940), WTC0(0xf2eba690), WTC0(0xf2ca8480), WTC0(0xf2a86670), + WTC0(0xf2854f40), WTC0(0xf2614190), WTC0(0xf23c41e0), WTC0(0xf21657a0), + WTC0(0xf1ef8ae0), WTC0(0xf1c7e3e0), WTC0(0xf19f63d0), WTC0(0xf1760450), + WTC0(0xf14bbdf0), WTC0(0xf1208960), WTC0(0xf0f45cd0), WTC0(0xf0c72ce0), + WTC0(0xf098ee00), WTC0(0xf06996f0), WTC0(0xf0392620), WTC0(0xf0079e10), + WTC0(0xefd4ffc0), WTC0(0xefa15ca0), WTC0(0xef6ce600), WTC0(0xef37d460), + WTC0(0xef025f80), WTC0(0xeecca2c0), WTC0(0xee969760), WTC0(0xee603440), + WTC0(0xee296d20), WTC0(0xedf21c00), WTC0(0xedba07e0), WTC0(0xed80f640), + WTC0(0xed46bf40), WTC0(0xed0b7b00), WTC0(0xeccf5fc0), WTC0(0xec92a120), + WTC0(0xec556d60), WTC0(0xec17e700), WTC0(0xebda2d40), WTC0(0xeb9c5fa0), + WTC0(0xeb5e7040), WTC0(0xeb201b20), WTC0(0xeae117c0), WTC0(0xeaa12000), + WTC0(0xea600180), WTC0(0xea1d9940), WTC0(0xe9d9c160), WTC0(0xe99468a0), + WTC0(0xe94dc040), WTC0(0xe9061940), WTC0(0xe8bdc140), WTC0(0xe8750ae0), + WTC0(0xe82c4fa0), WTC0(0xe7e3ea40), WTC0(0xe79c35e0), WTC0(0xe7554ca0), + WTC0(0xe70efc00), WTC0(0xe6c90c20), WTC0(0xe6833f00), WTC0(0xe63d2300), + WTC0(0xe5f620a0), WTC0(0xe5ad9dc0), WTC0(0xe5632080), WTC0(0xe5169da0), + WTC0(0xe4c83e60), WTC0(0xe4782400), WTC0(0xe4269840), WTC0(0xe3d42dc0), + WTC0(0xe38188c0), WTC0(0xe32f4be0), WTC0(0xe2ddeea0), WTC0(0xe28db520), + WTC0(0xe23ee000), WTC0(0xe1f1a580), WTC0(0xe1a5e3a0), WTC0(0xe15b35a0), + WTC0(0xe1113860), WTC0(0xe0c78a00), WTC0(0xe07dd0e0), WTC0(0xe033b7c0), + WTC0(0xdfe8e680), WTC0(0xdf9d1fc0), WTC0(0xdf5055c0), WTC0(0xdf0287c0), + WTC0(0xdeb3b340), WTC0(0xde63e7c0), WTC0(0xde134a00), WTC0(0xddc20000), + WTC0(0xdd703180), WTC0(0xdd1e1280), WTC0(0xdccbe080), WTC0(0xdc79d980), + WTC0(0xdc283600), WTC0(0xdbd71e00), WTC0(0xdb86b140), WTC0(0xdb3710c0), + WTC0(0xdae850c0), WTC0(0xda9a6bc0), WTC0(0xda4d5640), WTC0(0xda010640), + WTC0(0xd9b56640), WTC0(0xd96a5700), WTC0(0xd91fb700), WTC0(0xd8d56600), + WTC0(0xd88b4a40), WTC0(0xd8414f00), WTC0(0xd7f75f80), WTC0(0xd7ad6740), + WTC0(0xd76352c0), WTC0(0xd7191040), WTC0(0xd6ce8c80), WTC0(0xd683bd00), + WTC0(0xd638a5c0), WTC0(0xd5ed4f80), WTC0(0xd5a1c240), WTC0(0xd5562b80), + WTC0(0xd50ae500), WTC0(0xd4c04c80), WTC0(0xd476bb40), WTC0(0xd42e62c0), + WTC0(0xd3e75680), WTC0(0xd3a1ad00), WTC0(0xd35d6780), WTC0(0xd31a4300), + WTC0(0xd2d7dc00), WTC0(0xd295d080), WTC0(0xd253d8c0), WTC0(0xd211df40), + WTC0(0xd1cfdbc0), WTC0(0xd18dc480), WTC0(0xd14b9dc0), WTC0(0xd1097c80), + WTC0(0xd0c77700), WTC0(0xd085a500), WTC0(0xd0442f40), WTC0(0xd0034a80), + WTC0(0xcfc32c00), WTC0(0xcf840400), WTC0(0xcf45f400), WTC0(0xcf0913c0), + WTC0(0xcecd8000), WTC0(0xce932c80), WTC0(0xce59bf40), WTC0(0xce20cd40), + WTC0(0xcde7ec40), WTC0(0xcdaeedc0), WTC0(0xcd75ea00), WTC0(0xcd3cfec0), + WTC0(0xcd044b40), WTC0(0xcccbff00), WTC0(0xcc945480), WTC0(0xcc5d8780), + WTC0(0xcc27c3c0), WTC0(0xcbf2fc40), WTC0(0xcbbf0a00), WTC0(0xcb8bc7c0), + WTC0(0xcb591880), WTC0(0xcb26f0c0), WTC0(0xcaf54980), WTC0(0xcac41ac0), + WTC0(0xca936440), WTC0(0xca632d80), WTC0(0xca337f00), WTC0(0xca046180), + WTC0(0xc9d5dd40), WTC0(0xc9a7fa80), WTC0(0xc97ac200), WTC0(0xc94e3c00), + WTC0(0xc91d1840), WTC0(0xc8f15980), WTC0(0xc8c52340), WTC0(0xc8988100), + WTC0(0xc86b7f00), WTC0(0xc83e28c0), WTC0(0xc8108a80), WTC0(0xc7e2afc0), + WTC0(0xc7b4a480), WTC0(0xc7867480), WTC0(0xc7582b40), WTC0(0xc729cc80), + WTC0(0xc6fb5700), WTC0(0xc6ccca40), WTC0(0xc69e2180), WTC0(0xc66f49c0), + WTC0(0xc64029c0), WTC0(0xc610a740), WTC0(0xc5e0bfc0), WTC0(0xc5b09e80), + WTC0(0xc5807900), WTC0(0xc5508440), WTC0(0xc520e840), WTC0(0xc4f1bdc0), + WTC0(0xc4c31d00), WTC0(0xc4951780), WTC0(0xc4678a00), WTC0(0xc43a28c0), + WTC0(0xc40ca800), WTC0(0xc3deccc0), WTC0(0xc3b09940), WTC0(0xc3822c00), + WTC0(0xc353a0c0), WTC0(0xc3251740), WTC0(0xc2f6b500), WTC0(0xc2c8a140), + WTC0(0xc29b02c0), WTC0(0xc26df5c0), WTC0(0xc2418940), WTC0(0xc215cbc0), + WTC0(0xc1eaca00), WTC0(0xc1c08680), WTC0(0xc196fb00), WTC0(0xc16e22c0), + WTC0(0xc145f040), WTC0(0xc11e3a80), WTC0(0xc0f6cc00), WTC0(0xc0cf6ec0), + WTC0(0xc0a802c0), WTC0(0xc0809280), WTC0(0xc0593340), WTC0(0xc031f880), + WTC0(0xc00b04c0), WTC0(0xbfe48981), WTC0(0xbfbebb81), WTC0(0xbf99cb01), + WTC0(0xbf75cc81), WTC0(0xbf52c101), WTC0(0xbf30a901), WTC0(0xbf0f8301), + WTC0(0xbeef4601), WTC0(0xbecfe601), WTC0(0xbeb15701), WTC0(0xbe938c81), + WTC0(0xbe767e81), WTC0(0xbe5a2301), WTC0(0xbe3e7201), WTC0(0xbe236001), + WTC0(0xbe08e181), WTC0(0xbdeee981), WTC0(0xbdd56b81), WTC0(0xbdbc6381), + WTC0(0xbda3d081), WTC0(0xbd8bb281), WTC0(0xbd740b81), WTC0(0xbd5ce281), + WTC0(0xbd464281), WTC0(0xbd303581), WTC0(0xbd1ac801), WTC0(0xbd060c81), + WTC0(0xbcf21601), WTC0(0xbcdef701), WTC0(0xbcccbd01), WTC0(0xbcbb7001), + WTC0(0xbcab1781), WTC0(0xbc9bb901), WTC0(0xbc8d5101), WTC0(0xbc7fd301), + WTC0(0xbc733401), WTC0(0xbc676501), WTC0(0xbc5c4c81), WTC0(0xbc51cb01), + WTC0(0xbc47c281), WTC0(0xbc3e1981), WTC0(0xbc34c081), WTC0(0xbc2bab01), + WTC0(0xbc22cd81), WTC0(0xbc1a2401), WTC0(0xbc11b681), WTC0(0xbc098d81), + WTC0(0xbc01b381), WTC0(0xbbfa3c01), WTC0(0xbbf34281), WTC0(0xbbece281), + WTC0(0xbbe73201), WTC0(0xbbe23281), WTC0(0xbbdddb01), WTC0(0xbbda2501), + WTC0(0xbbd70201), WTC0(0xbbd45601), WTC0(0xbbd20301), WTC0(0xbbcfea81), + WTC0(0xbbce0601), WTC0(0xbbcc6b01), WTC0(0xbbcb3201), WTC0(0xbbca7481), + WTC0(0xbbca5d01), WTC0(0xbbcb2281), WTC0(0xbbccfc81), WTC0(0xbbd01301), + WTC0(0xbbd45881), WTC0(0xbbd9a781), WTC0(0xbbdfdb81), WTC0(0xbbe6c801), + WTC0(0xbbee2f81), WTC0(0xbbf5d181), WTC0(0xbbfd6c01), WTC0(0xbc04e381), + WTC0(0xbc0c4581), WTC0(0xbc13a481), WTC0(0xbc1b1081), WTC0(0xbc228f01), + WTC0(0xbc2a1a81), WTC0(0xbc31af01), WTC0(0xbc394901), WTC0(0xbc40e881), + WTC0(0xbc488e81), WTC0(0xbc503b81), WTC0(0xbc57f101), WTC0(0xbc5fae81), + WTC0(0xbc677501), WTC0(0xbc6f4401), WTC0(0xbc771c01), WTC0(0xbc7efc81), + WTC0(0xbc86e581), WTC0(0xbc8ed701), WTC0(0xbc96d101), WTC0(0xbc9ed481), + WTC0(0xbca6e101), WTC0(0xbcaef701), WTC0(0xbcb71701), WTC0(0xbcbf4001), + WTC0(0xbcc77181), WTC0(0xbccfac01), WTC0(0xbcd7ef01), WTC0(0xbce03b81), + WTC0(0xbce89281), WTC0(0xbcf0f381), WTC0(0xbcf95e81), WTC0(0xbd01d281), + WTC0(0xbd0a4f81), WTC0(0xbd12d581), WTC0(0xbd1b6501), WTC0(0xbd23ff01), + WTC0(0xbd2ca281), WTC0(0xbd355081), WTC0(0xbd3e0801), WTC0(0xbd46c801), + WTC0(0xbd4f9101), WTC0(0xbd586281), WTC0(0xbd613d81), WTC0(0xbd6a2201), + WTC0(0xbd731081), WTC0(0xbd7c0781), WTC0(0xbd850701), WTC0(0xbd8e0e01), + WTC0(0xbd971c81), WTC0(0xbda03381), WTC0(0xbda95301), WTC0(0xbdb27b01), + WTC0(0xbdbbab01), WTC0(0xbdc4e301), WTC0(0xbdce2181), WTC0(0xbdd76701), + WTC0(0xbde0b301), WTC0(0xbdea0681), WTC0(0xbdf36101), WTC0(0xbdfcc301), + WTC0(0xbe062b81), WTC0(0xbe0f9a01), WTC0(0xbe190d81), WTC0(0xbe228681), + WTC0(0xbe2c0501), WTC0(0xbe358901), WTC0(0xbe3f1381), WTC0(0xbe48a301), + WTC0(0xbe523781), WTC0(0xbe5bd001), WTC0(0xbe656c01), WTC0(0xbe6f0c01), + WTC0(0xbe78b001), WTC0(0xbe825801), WTC0(0xbe8c0501), WTC0(0xbe95b581), + WTC0(0xbe9f6901), WTC0(0xbea91f01), WTC0(0xbeb2d681), WTC0(0xbebc9181), + WTC0(0xbec64e81), WTC0(0xbed00f81), WTC0(0xbed9d281), WTC0(0xbee39801), + WTC0(0xbeed5f01), WTC0(0xbef72681), WTC0(0xbf00ef81), WTC0(0xbf0aba01), + WTC0(0xbf148681), WTC0(0xbf1e5501), WTC0(0xbf282501), WTC0(0xbf31f501), + WTC0(0xbf3bc601), WTC0(0xbf459681), WTC0(0xbf4f6801), WTC0(0xbf593a01), + WTC0(0xbf630d81), WTC0(0xbf6ce201), WTC0(0xbf76b701), WTC0(0xbf808b81), + WTC0(0xbf8a5f81), WTC0(0xbf943301), WTC0(0xbf9e0701), WTC0(0xbfa7dc01), + WTC0(0xbfb1b101), WTC0(0xbfbb8701), WTC0(0xbfc55c81), WTC0(0xbfcf3181), + WTC0(0xbfd90601), WTC0(0xbfe2d901), WTC0(0xbfecaa81), WTC0(0xbff67a01), + /* part 1 */ + WTC1(0x80130981), WTC1(0x80269f81), WTC1(0x803a3381), WTC1(0x804dc481), + WTC1(0x80615281), WTC1(0x8074dc01), WTC1(0x80886081), WTC1(0x809bdf01), + WTC1(0x80af5701), WTC1(0x80c2c781), WTC1(0x80d63101), WTC1(0x80e99401), + WTC1(0x80fcf181), WTC1(0x81104a01), WTC1(0x81239d81), WTC1(0x8136ea01), + WTC1(0x814a2f81), WTC1(0x815d6c01), WTC1(0x8170a181), WTC1(0x8183cf81), + WTC1(0x8196f781), WTC1(0x81aa1981), WTC1(0x81bd3401), WTC1(0x81d04681), + WTC1(0x81e34f81), WTC1(0x81f64f01), WTC1(0x82094581), WTC1(0x821c3401), + WTC1(0x822f1b01), WTC1(0x8241fa01), WTC1(0x8254cf01), WTC1(0x82679901), + WTC1(0x827a5801), WTC1(0x828d0b01), WTC1(0x829fb401), WTC1(0x82b25301), + WTC1(0x82c4e801), WTC1(0x82d77201), WTC1(0x82e9ef01), WTC1(0x82fc5f01), + WTC1(0x830ec081), WTC1(0x83211501), WTC1(0x83335c81), WTC1(0x83459881), + WTC1(0x8357c701), WTC1(0x8369e781), WTC1(0x837bf801), WTC1(0x838df801), + WTC1(0x839fe801), WTC1(0x83b1c881), WTC1(0x83c39a81), WTC1(0x83d55d01), + WTC1(0x83e70f01), WTC1(0x83f8b001), WTC1(0x840a3e81), WTC1(0x841bb981), + WTC1(0x842d2281), WTC1(0x843e7a81), WTC1(0x844fc081), WTC1(0x8460f581), + WTC1(0x84721701), WTC1(0x84832481), WTC1(0x84941d81), WTC1(0x84a50201), + WTC1(0x84b5d301), WTC1(0x84c69101), WTC1(0x84d73c01), WTC1(0x84e7d381), + WTC1(0x84f85581), WTC1(0x8508c181), WTC1(0x85191801), WTC1(0x85295881), + WTC1(0x85398481), WTC1(0x85499d01), WTC1(0x8559a081), WTC1(0x85698e81), + WTC1(0x85796601), WTC1(0x85892681), WTC1(0x8598d081), WTC1(0x85a86581), + WTC1(0x85b7e601), WTC1(0x85c75201), WTC1(0x85d6a981), WTC1(0x85e5eb81), + WTC1(0x85f51681), WTC1(0x86042c01), WTC1(0x86132c01), WTC1(0x86221801), + WTC1(0x8630f181), WTC1(0x863fb701), WTC1(0x864e6901), WTC1(0x865d0581), + WTC1(0x866b8d81), WTC1(0x867a0081), WTC1(0x86886001), WTC1(0x8696ad01), + WTC1(0x86a4e781), WTC1(0x86b30f01), WTC1(0x86c12401), WTC1(0x86cf2601), + WTC1(0x86dd1481), WTC1(0x86eaf081), WTC1(0x86f8ba81), WTC1(0x87067281), + WTC1(0x87141b01), WTC1(0x8721b481), WTC1(0x872f4201), WTC1(0x873cc201), + WTC1(0x874a2f01), WTC1(0x87578181), WTC1(0x8764b101), WTC1(0x8771c601), + WTC1(0x877ede01), WTC1(0x878c1881), WTC1(0x87998f01), WTC1(0x87a70e81), + WTC1(0x87b42481), WTC1(0x87c05e81), WTC1(0x87cb5101), WTC1(0x87d4ac81), + WTC1(0x87e73d81), WTC1(0x88124281), WTC1(0x88353501), WTC1(0x885f8481), + WTC1(0x888d3181), WTC1(0x88be1681), WTC1(0x88f13801), WTC1(0x8925f101), + WTC1(0x895bcd01), WTC1(0x89925a81), WTC1(0x89c92f81), WTC1(0x8a001f01), + WTC1(0x8a372881), WTC1(0x8a6e4a01), WTC1(0x8aa58681), WTC1(0x8adcee01), + WTC1(0x8b149701), WTC1(0x8b4c9701), WTC1(0x8b850281), WTC1(0x8bbde981), + WTC1(0x8bf75b01), WTC1(0x8c316681), WTC1(0x8c6c1b01), WTC1(0x8ca78781), + WTC1(0x8ce3ba81), WTC1(0x8d20c301), WTC1(0x8d5eaa01), WTC1(0x8d9d7781), + WTC1(0x8ddd3201), WTC1(0x8e1de001), WTC1(0x8e5f8881), WTC1(0x8ea23201), + WTC1(0x8ee5e301), WTC1(0x8f2aa101), WTC1(0x8f706f01), WTC1(0x8fb74f81), + WTC1(0x8fff4601), WTC1(0x90485401), WTC1(0x90927b81), WTC1(0x90ddc001), + WTC1(0x912a2201), WTC1(0x9177a301), WTC1(0x91c64301), WTC1(0x92160301), + WTC1(0x9266e281), WTC1(0x92b8e101), WTC1(0x930bff81), WTC1(0x93603d01), + WTC1(0x93b59901), WTC1(0x940c1281), WTC1(0x9463a881), WTC1(0x94bc5981), + WTC1(0x95162381), WTC1(0x95710601), WTC1(0x95ccff01), WTC1(0x962a0c81), + WTC1(0x96882e01), WTC1(0x96e76101), WTC1(0x9747a481), WTC1(0x97a8f681), + WTC1(0x980b5501), WTC1(0x986ebd81), WTC1(0x98d32d81), WTC1(0x9938a281), + WTC1(0x999f1981), WTC1(0x9a069001), WTC1(0x9a6f0381), WTC1(0x9ad87081), + WTC1(0x9b42d581), WTC1(0x9bae2f81), WTC1(0x9c1a7c81), WTC1(0x9c87ba81), + WTC1(0x9cf5e701), WTC1(0x9d650081), WTC1(0x9dd50481), WTC1(0x9e45f081), + WTC1(0x9eb7c101), WTC1(0x9f2a7281), WTC1(0x9f9e0301), WTC1(0xa0127081), + WTC1(0xa087b981), WTC1(0xa0fddd81), WTC1(0xa174da81), WTC1(0xa1ecae01), + WTC1(0xa2655581), WTC1(0xa2dece81), WTC1(0xa3591801), WTC1(0xa3d43001), + WTC1(0xa4501601), WTC1(0xa4ccc901), WTC1(0xa54a4701), WTC1(0xa5c89001), + WTC1(0xa647a301), WTC1(0xa6c77e01), WTC1(0xa7482101), WTC1(0xa7c98b01), + WTC1(0xa84bbb81), WTC1(0xa8ceb201), WTC1(0xa9526d81), WTC1(0xa9d6ef01), + WTC1(0xaa5c3601), WTC1(0xaae24301), WTC1(0xab691681), WTC1(0xabf0b181), + WTC1(0xac791401), WTC1(0xad023f01), WTC1(0xad8c3301), WTC1(0xae16f001), + WTC1(0xaea27681), WTC1(0xaf2ec901), WTC1(0xafbbe801), WTC1(0xb049d601), + WTC1(0xb0d89401), WTC1(0xb1682281), WTC1(0xb1f88181), WTC1(0xb289b181), + WTC1(0xb31bb301), WTC1(0xb3ae8601), WTC1(0xb4422b81), WTC1(0xb4d6a381), + WTC1(0x4a5a327f), WTC1(0x49c4adff), WTC1(0x492e637f), WTC1(0x48974f7f), + WTC1(0x47ff6d7f), WTC1(0x4766baff), WTC1(0x46cd35ff), WTC1(0x4632dd7f), + WTC1(0x4597b0ff), WTC1(0x44fbb1ff), WTC1(0x445eeaff), WTC1(0x43c165ff), + WTC1(0x4323227f), WTC1(0x4284277f), WTC1(0x41e48aff), WTC1(0x4144557f), + WTC1(0x40a3867f), WTC1(0x4001f5ff), WTC1(0x3f5f5d80), WTC1(0x3ebbad00), + WTC1(0x3e16ee40), WTC1(0x3d713d00), WTC1(0x3ccab700), WTC1(0x3c236500), + WTC1(0x3b7b5800), WTC1(0x3ad2ecc0), WTC1(0x3a2a6540), WTC1(0x3981b7c0), + WTC1(0x38d8ba00), WTC1(0x382f01c0), WTC1(0x37846240), WTC1(0x36d8eb00), + WTC1(0x362c9ec0), WTC1(0x357f7a00), WTC1(0x34d18340), WTC1(0x3422c900), + WTC1(0x33736c40), WTC1(0x32c39040), WTC1(0x32134280), WTC1(0x31629280), + WTC1(0x30b1a000), WTC1(0x30008380), WTC1(0x2f4f4240), WTC1(0x2e9df180), + WTC1(0x2decc780), WTC1(0x2d3bd640), WTC1(0x2c8b0cc0), WTC1(0x2bda3080), + WTC1(0x2b28ec80), WTC1(0x2a773500), WTC1(0x29c51b40), WTC1(0x291293c0), + WTC1(0x285f9280), WTC1(0x27ac35c0), WTC1(0x26f8ab40), WTC1(0x26454c00), + WTC1(0x25925600), WTC1(0x24dfd580), WTC1(0x242ddd40), WTC1(0x237c87c0), + WTC1(0x22cbe240), WTC1(0x221bef40), WTC1(0x216cb040), WTC1(0x20be2800), + WTC1(0x20105c80), WTC1(0x1f6352a0), WTC1(0x1eb71240), WTC1(0x1e0ba140), + WTC1(0x1d60fe40), WTC1(0x1cb723e0), WTC1(0x1c0e0300), WTC1(0x1b6596c0), + WTC1(0x1abde8a0), WTC1(0x1a16fbe0), WTC1(0x1970c680), WTC1(0x18cb4840), + WTC1(0x18268e20), WTC1(0x1782a0c0), WTC1(0x16df8960), WTC1(0x163d6300), + WTC1(0x159c52c0), WTC1(0x14fc87e0), WTC1(0x145e2c80), WTC1(0x13c15b60), + WTC1(0x13263240), WTC1(0x128cd9a0), WTC1(0x11f562a0), WTC1(0x115fc1c0), + WTC1(0x10cbf160), WTC1(0x1039f200), WTC1(0x0fa9a080), WTC1(0x0f1abd90), + WTC1(0x0e8d01d0), WTC1(0x0e003330), WTC1(0x0d743590), WTC1(0x0ce8ef40), + WTC1(0x0c5e1900), WTC1(0x0bd35d70), WTC1(0x0b488eb0), WTC1(0x0abd8410), + WTC1(0x0a320a00), WTC1(0x09a60e70), WTC1(0x0919ab00), WTC1(0x088d0de0), + WTC1(0x080065e0), WTC1(0x07739710), WTC1(0x06e65808), WTC1(0x06588348), + WTC1(0x05ca0ae0), WTC1(0x053aaaf8), WTC1(0x04a9faf0), WTC1(0x0417f698), + WTC1(0x03859ff4), WTC1(0x02f49be4), WTC1(0x0266b668), WTC1(0x01de554e), + WTC1(0x015f50ca), WTC1(0x00eb7e5d), WTC1(0x00904f24), WTC1(0x00212889), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), WTC1(0x00000000), + /* part 2 */ + WTC2(0xfffece02), WTC2(0xffe4c3df), WTC2(0xffcaaa55), WTC2(0xffb087d1), + WTC2(0xff9662bf), WTC2(0xff7c418b), WTC2(0xff622aa0), WTC2(0xff48246c), + WTC2(0xff2e355a), WTC2(0xff1463db), WTC2(0xfefab608), WTC2(0xfee12f0a), + WTC2(0xfec7cfd2), WTC2(0xfeae995a), WTC2(0xfe958cc4), WTC2(0xfe7cabce), + WTC2(0xfe63f882), WTC2(0xfe4b74e0), WTC2(0xfe3322f6), WTC2(0xfe1b04dc), + WTC2(0xfe031ccc), WTC2(0xfdeb6cf0), WTC2(0xfdd3ff7c), WTC2(0xfdbce834), + WTC2(0xfda63bb8), WTC2(0xfd900c68), WTC2(0xfd7a590c), WTC2(0xfd6511b4), + WTC2(0xfd5026c0), WTC2(0xfd3b8954), WTC2(0xfd272df0), WTC2(0xfd130adc), + WTC2(0xfcff15ac), WTC2(0xfceb4a68), WTC2(0xfcd7b110), WTC2(0xfcc454d0), + WTC2(0xfcb14064), WTC2(0xfc9e896c), WTC2(0xfc8c5264), WTC2(0xfc7abef0), + WTC2(0xfc69f078), WTC2(0xfc59f5e8), WTC2(0xfc4acfec), WTC2(0xfc3c8060), + WTC2(0xfc2f0264), WTC2(0xfc223b7c), WTC2(0xfc160714), WTC2(0xfc0a4150), + WTC2(0xfbfec920), WTC2(0xfbf38320), WTC2(0xfbe855d0), WTC2(0xfbdd2740), + WTC2(0xfbd1fc68), WTC2(0xfbc6fea0), WTC2(0xfbbc5a48), WTC2(0xfbb23b48), + WTC2(0xfba8ca78), WTC2(0xfba02e50), WTC2(0xfb988de0), WTC2(0xfb920b40), + WTC2(0xfb8cb870), WTC2(0xfb889f68), WTC2(0xfb85cbe8), WTC2(0xfb843dd0), + WTC2(0xfb83df78), WTC2(0xfb8495d0), WTC2(0xfb864660), WTC2(0xfb88d4a8), + WTC2(0xfb8c21e8), WTC2(0xfb900f28), WTC2(0xfb947dc0), WTC2(0xfb9950c0), + WTC2(0xfb9e6d08), WTC2(0xfba3b658), WTC2(0xfba91908), WTC2(0xfbae9e08), + WTC2(0xfbb45bd0), WTC2(0xfbba66f8), WTC2(0xfbc0dcf0), WTC2(0xfbc7ead8), + WTC2(0xfbcfc200), WTC2(0xfbd89330), WTC2(0xfbe294d0), WTC2(0xfbee03d0), + WTC2(0xfbfb1de8), WTC2(0xfc0a1da4), WTC2(0xfc1b22e0), WTC2(0xfc2e38f0), + WTC2(0xfc436d48), WTC2(0xfc5abf7c), WTC2(0xfc74024c), WTC2(0xfc8ef2e8), + WTC2(0xfcab51ac), WTC2(0xfcc8d024), WTC2(0xfce704f0), WTC2(0xfd0580cc), + WTC2(0xfd23d4d0), WTC2(0xfd41ce40), WTC2(0xfd5f81b0), WTC2(0xfd7d08f0), + WTC2(0xfd9a8560), WTC2(0xfdb85938), WTC2(0xfdd71798), WTC2(0xfdf753b8), + WTC2(0xfe1993ee), WTC2(0xfe3e30f8), WTC2(0xfe656cba), WTC2(0xfe8f8fdc), + WTC2(0xfebca8a4), WTC2(0xfeec590e), WTC2(0xff1e285c), WTC2(0xff51a0b7), + WTC2(0xff866330), WTC2(0xffbc2cbb), WTC2(0xfff2bbff), WTC2(0x0029d79d), + WTC2(0x00618a22), WTC2(0x009a1185), WTC2(0x00d3aa8c), WTC2(0x010e8ff6), + WTC2(0x014af29e), WTC2(0x0188fe56), WTC2(0x01c8e108), WTC2(0x020ab3c4), + WTC2(0x024e68a8), WTC2(0x0293e824), WTC2(0x02db1bc8), WTC2(0x0323f1a4), + WTC2(0x036e5d6c), WTC2(0x03ba5320), WTC2(0x0407c938), WTC2(0x0456cad0), + WTC2(0x04a77288), WTC2(0x04f9db88), WTC2(0x054e1888), WTC2(0x05a41ef0), + WTC2(0x05fbd6e0), WTC2(0x065528c0), WTC2(0x06b00838), WTC2(0x070c7ee0), + WTC2(0x076a9bb0), WTC2(0x07ca6d10), WTC2(0x082c08e0), WTC2(0x088f8da0), + WTC2(0x08f51ac0), WTC2(0x095ccc20), WTC2(0x09c69f70), WTC2(0x0a327b40), + WTC2(0x0aa046d0), WTC2(0x0b0febb0), WTC2(0x0b815dd0), WTC2(0x0bf49600), + WTC2(0x0c698c50), WTC2(0x0ce03ba0), WTC2(0x0d58a380), WTC2(0x0dd2c510), + WTC2(0x0e4ea110), WTC2(0x0ecc3dd0), WTC2(0x0f4ba800), WTC2(0x0fcced10), + WTC2(0x10501960), WTC2(0x10d532a0), WTC2(0x115c39c0), WTC2(0x11e52fa0), + WTC2(0x12701560), WTC2(0x12fcef20), WTC2(0x138bc200), WTC2(0x141c9300), + WTC2(0x14af64a0), WTC2(0x154434e0), WTC2(0x15db0020), WTC2(0x1673c360), + WTC2(0x170e7e80), WTC2(0x17ab35e0), WTC2(0x1849ee40), WTC2(0x18eaaba0), + WTC2(0x198d6f00), WTC2(0x1a3236a0), WTC2(0x1ad90080), WTC2(0x1b81cc60), + WTC2(0x1c2c9da0), WTC2(0x1cd97980), WTC2(0x1d8865c0), WTC2(0x1e396540), + WTC2(0x1eec7700), WTC2(0x1fa198c0), WTC2(0x2058c840), WTC2(0x21120640), + WTC2(0x21cd5700), WTC2(0x228abec0), WTC2(0x234a4180), WTC2(0x240bdf80), + WTC2(0x24cf95c0), WTC2(0x259561c0), WTC2(0x265d4200), WTC2(0x27273840), + WTC2(0x27f348c0), WTC2(0x28c17700), WTC2(0x2991c500), WTC2(0x2a643080), + WTC2(0x2b38b680), WTC2(0x2c0f53c0), WTC2(0x2ce80840), WTC2(0x2dc2d680), + WTC2(0x2e9fc100), WTC2(0x2f7ecac0), WTC2(0x305ff280), WTC2(0x314334c0), + WTC2(0x32288e00), WTC2(0x330ffb80), WTC2(0x33f97d80), WTC2(0x34e515c0), + WTC2(0x35d2c5c0), WTC2(0x36c28d00), WTC2(0x37b467c0), WTC2(0x38a85080), + WTC2(0x399e4240), WTC2(0x3a963a00), WTC2(0x3b903600), WTC2(0x3c8c3480), + WTC2(0x3d8a3380), WTC2(0x3e8a2dc0), WTC2(0x3f8c1b40), WTC2(0x408ff2ff), + WTC2(0x4195ae7f), WTC2(0x429d477f), WTC2(0x43a6b87f), WTC2(0x44b1fdff), + WTC2(0x45bf11ff), WTC2(0x46cdee7f), WTC2(0x47de8cff), WTC2(0x48f0e77f), + WTC2(0x4a050eff), WTC2(0x4b1b2dff), WTC2(0x4c3372ff), WTC2(0x4d4e0bff), + WTC2(0x4e6b257f), WTC2(0x4f8aedff), WTC2(0x50ad92ff), WTC2(0x51d341ff), + WTC2(0x002006a9), WTC2(0x000bfb36), WTC2(0xfffe45ac), WTC2(0xfff6d064), + WTC2(0xfff585bc), WTC2(0xfffa500d), WTC2(0x000519b4), WTC2(0x0015cd0c), + WTC2(0x002c5470), WTC2(0x00489a3b), WTC2(0x006a88c8), WTC2(0x00920a74), + WTC2(0x00bf0999), WTC2(0x00f17092), WTC2(0x012929bc), WTC2(0x01661f70), + WTC2(0x01a83c0c), WTC2(0x01ef69e8), WTC2(0x023b9364), WTC2(0x028ca2d4), + WTC2(0x02e2829c), WTC2(0x033d1d10), WTC2(0x039c5c90), WTC2(0x04002b78), + WTC2(0x04687418), WTC2(0x04d520e0), WTC2(0x05461c18), WTC2(0x05bb5020), + WTC2(0x0634a758), WTC2(0x06b20c20), WTC2(0x073368c8), WTC2(0x07b8a7b0), + WTC2(0x0841b340), WTC2(0x08ce75b0), WTC2(0x095ed980), WTC2(0x09f2c900), + WTC2(0x0a8a2e80), WTC2(0x0b24f470), WTC2(0x0bc30510), WTC2(0x0c644ad0), + WTC2(0x0d08b010), WTC2(0x0db01f10), WTC2(0x0e5a8250), WTC2(0x0f07c400), + WTC2(0x0fb7cea0), WTC2(0x106a8c80), WTC2(0x111fe800), WTC2(0x11d7cb60), + WTC2(0x12922120), WTC2(0x134ed3a0), WTC2(0x140dcd00), WTC2(0x14cef7e0), + WTC2(0x15923e60), WTC2(0x16578b00), WTC2(0x171ec820), WTC2(0x17e7e020), + WTC2(0x18b2bd20), WTC2(0x197f49c0), WTC2(0x1a4d7040), WTC2(0x1b1d1b00), + WTC2(0x1bee3460), WTC2(0x1cc0a6a0), WTC2(0x1d945c40), WTC2(0x1e693f80), + WTC2(0x1f3f3ac0), WTC2(0x20163880), WTC2(0x20ee22c0), WTC2(0x21c6e440), + WTC2(0x22a06740), WTC2(0x237a9600), WTC2(0x24555ac0), WTC2(0x2530a040), + WTC2(0x260c5080), WTC2(0x26e85600), WTC2(0x27c49b00), WTC2(0x28a10a00), + WTC2(0x297d8d80), WTC2(0x2a5a0f80), WTC2(0x2b367a80), WTC2(0x2c12b8c0), + WTC2(0x2ceeb500), WTC2(0x2dca5940), WTC2(0x2ea58fc0), WTC2(0x2f804340), + WTC2(0x305a5dc0), WTC2(0x3133ca00), WTC2(0x320c7200), WTC2(0x32e44000), + WTC2(0x33bb1ec0), WTC2(0x3490f880), WTC2(0x3565b7c0), WTC2(0x36394640), + WTC2(0x370b8f00), WTC2(0x37dc7c00), WTC2(0x38abf7c0), WTC2(0x3979ecc0), + WTC2(0x3a464500), WTC2(0x3b10eb00), WTC2(0x3bd9c940), WTC2(0x3ca0c9c0), + WTC2(0x3d65d740), WTC2(0x3e28dc00), WTC2(0x3ee9c240), WTC2(0x3fa87480), + WTC2(0x4064dcff), WTC2(0x411ee67f), WTC2(0x41d67a7f), WTC2(0x428b847f), + WTC2(0x433ded7f), WTC2(0x43eda0ff), WTC2(0x449a887f), WTC2(0x45448f7f), + WTC2(0x45eb9eff), WTC2(0x468fa1ff), WTC2(0x473082ff), WTC2(0x47ce2c7f), + WTC2(0x4868887f), WTC2(0x48ff80ff), WTC2(0x499300ff), WTC2(0x4a22f2ff), + WTC2(0x4aaf407f), WTC2(0x4b37d47f), WTC2(0x4bbc997f), WTC2(0x4c3d78ff), + WTC2(0x4cba5e7f), WTC2(0x4d33337f), WTC2(0x4da7e27f), WTC2(0x4e18567f), + WTC2(0x4e8478ff), WTC2(0x4eec347f), WTC2(0x4f4f737f), WTC2(0x4fae20ff), + WTC2(0x500825ff), WTC2(0x505d6dff), WTC2(0x50ade37f), WTC2(0x50f96f7f), + WTC2(0x513ffdff), WTC2(0x518177ff), WTC2(0x51bdc87f), WTC2(0x51f4d9ff), + WTC2(0x5226967f), WTC2(0x5252e87f), WTC2(0x5279b9ff), WTC2(0x529af5ff), + WTC2(0x52b6867f), WTC2(0x52cc55ff), WTC2(0x52dc4eff), WTC2(0x52e65aff), + WTC2(0x52ea657f), WTC2(0x52e857ff), WTC2(0x52e01d7f), WTC2(0x52d19fff), + WTC2(0x52bcc9ff), WTC2(0x52a1857f), WTC2(0x527fbd7f), WTC2(0x52575b7f), + WTC2(0x52284a7f), WTC2(0x51f274ff), WTC2(0x51b5c47f), WTC2(0x5172247f), + WTC2(0x51277dff), WTC2(0x50d5bc7f), WTC2(0x507cc9ff), WTC2(0x501c90ff), + WTC2(0x4fb4fb7f), WTC2(0x4f45f3ff), WTC2(0x4ecf64ff), WTC2(0x4e5138ff), + WTC2(0x4dcb597f), WTC2(0x4d3db1ff), WTC2(0x4ca82bff), WTC2(0x4c0ab27f), + WTC2(0x4b652f7f), WTC2(0x4ab78d7f), WTC2(0x4a01b67f), WTC2(0x4943957f), + WTC2(0x487d12ff), WTC2(0x47ae1f7f), WTC2(0x46d68f7f), WTC2(0x45f7187f), + WTC2(0x4513597f), WTC2(0x4430467f), WTC2(0x4352d2ff), WTC2(0x427e6bff), + WTC2(0x41b390ff), WTC2(0x40f2077f), WTC2(0x4039a87f), WTC2(0x3f8a3100), + WTC2(0x3ee33e00), WTC2(0x3e446ac0), WTC2(0x3dad5180), WTC2(0x3d1d7fc0), + WTC2(0x3c947b00), WTC2(0x3c11c7c0), WTC2(0x3b94ebc0), WTC2(0x3b1d6dc0), + WTC2(0x3aaad480), WTC2(0x3a3ca740), WTC2(0x39d26c40), WTC2(0x396ba8c0), + WTC2(0x3907e080), WTC2(0x38a69800), WTC2(0x38473d80), WTC2(0x37e923c0), + WTC2(0x378b9b80), WTC2(0x372e0380), WTC2(0x36d03a80), WTC2(0x36727f00), + WTC2(0x36150e40), WTC2(0x35b81540), WTC2(0x355b8000), WTC2(0x34ff1dc0), + WTC2(0x34a2bfc0), WTC2(0x34463e80), WTC2(0x33e982c0), WTC2(0x338c7880), + WTC2(0x332f0bc0), WTC2(0x32d11800), WTC2(0x327265c0), WTC2(0x3212bbc0), + WTC2(0x31b1e740), WTC2(0x314fef00), WTC2(0x30ed0540), WTC2(0x30895c80), + WTC2(0x30251880), WTC2(0x2fc02880), WTC2(0x2f5a6480), WTC2(0x2ef3a480), + WTC2(0x2e8bd640), WTC2(0x2e231100), WTC2(0x2db97680), WTC2(0x2d4f2700), + WTC2(0x2ce431c0), WTC2(0x2c789080), WTC2(0x2c0c3bc0), WTC2(0x2b9f2bc0), + WTC2(0x2b315940), WTC2(0x2ac2bc00), WTC2(0x2a534cc0), WTC2(0x29e303c0)}; + +const FIXP_WTB ELDAnalysis256[768] = { + WTC(0xfababde8), WTC(0xfa8e1e6a), WTC(0xfa6012a9), WTC(0xfa30c8dd), + WTC(0xfa006f4b), WTC(0xf9cf32c4), WTC(0xf99d1cc8), WTC(0xf96a148d), + WTC(0xf936184d), WTC(0xf9013d5b), WTC(0xf8cb7b67), WTC(0xf894ace0), + WTC(0xf85cd28e), WTC(0xf82413f8), WTC(0xf7ea90af), WTC(0xf7b05ee6), + WTC(0xf7759b0b), WTC(0xf73a671f), WTC(0xf6febea3), WTC(0xf6c27a0e), + WTC(0xf685ca33), WTC(0xf6493907), WTC(0xf60d437b), WTC(0xf5d2551f), + WTC(0xf598d273), WTC(0xf561199e), WTC(0xf52b8c6f), WTC(0xf4f8907d), + WTC(0xf4c87fdf), WTC(0xf49ba806), WTC(0xf4724286), WTC(0xf44c6127), + WTC(0xf4282435), WTC(0xf401ceae), WTC(0xf3d775a1), WTC(0xf3a91477), + WTC(0xf376c33f), WTC(0xf340a328), WTC(0xf306d4d6), WTC(0xf2c9775c), + WTC(0xf288a3ed), WTC(0xf2446e2a), WTC(0xf1fcfa45), WTC(0xf1b27b2d), + WTC(0xf164f3f4), WTC(0xf114365c), WTC(0xf0c00532), WTC(0xf06817a9), + WTC(0xf00c4ea4), WTC(0xefacbc7f), WTC(0xef4a205f), WTC(0xeee5dc33), + WTC(0xee808a0d), WTC(0xee19eeb2), WTC(0xedb12f6e), WTC(0xed44e8eb), + WTC(0xecd50a13), WTC(0xec62d8dd), WTC(0xebef68b2), WTC(0xeb7b805c), + WTC(0xeb069af4), WTC(0xea8eef1c), WTC(0xea131c86), WTC(0xe99234c6), + WTC(0xe90cd9c2), WTC(0xe884f65b), WTC(0xe7fcbd6d), WTC(0xe7767300), + WTC(0xe6f289d0), WTC(0xe66f958a), WTC(0xe5eae99f), WTC(0xe560c403), + WTC(0xe4cfaaa1), WTC(0xe43887dc), WTC(0xe39dedc4), WTC(0xe303f190), + WTC(0xe26d7f5d), WTC(0xe1dc34ff), WTC(0xe14f9ced), WTC(0xe0c53cd0), + WTC(0xe03ab085), WTC(0xdfadc948), WTC(0xdf1d640c), WTC(0xde896bb6), + WTC(0xddf256ad), WTC(0xdd591e3d), WTC(0xdcbf0aec), WTC(0xdc25ab0a), + WTC(0xdb8e334c), WTC(0xdaf97794), WTC(0xda67bed9), WTC(0xd9d8c524), + WTC(0xd94bfa62), WTC(0xd8c089b5), WTC(0xd835c151), WTC(0xd7ab1704), + WTC(0xd7200906), WTC(0xd69420dc), WTC(0xd6073c0d), WTC(0xd5799615), + WTC(0xd4ec7c87), WTC(0xd46241c9), WTC(0xd3dc5bde), WTC(0xd35b4a79), + WTC(0xd2de1032), WTC(0xd26246f5), WTC(0xd1e68ed2), WTC(0xd16aa0a4), + WTC(0xd0eea5d2), WTC(0xd073302b), WTC(0xcff93749), WTC(0xcf820f45), + WTC(0xcf0ebb30), WTC(0xce9fd702), WTC(0xce34596c), WTC(0xcdc9a803), + WTC(0xcd5ec5d6), WTC(0xccf468ec), WTC(0xcc8bb41e), WTC(0xcc2619cc), + WTC(0xcbc3e090), WTC(0xcb6422f5), WTC(0xcb064d2f), WTC(0xcaaa2a6d), + WTC(0xca4fbdc9), WTC(0xc9f73c43), WTC(0xc9a0dc9b), WTC(0xc94cdd02), + WTC(0xc8f578a4), WTC(0xc8a24d15), WTC(0xc84dc71f), WTC(0xc7f83516), + WTC(0xc7a1e4b9), WTC(0xc74b22b1), WTC(0xc6f41284), WTC(0xc69cabc1), + WTC(0xc644986d), WTC(0xc5eb4167), WTC(0xc5910312), WTC(0xc5372c7f), + WTC(0xc4deba2e), WTC(0xc4883eca), WTC(0xc43310f0), WTC(0xc3dd5c5a), + WTC(0xc3868802), WTC(0xc32f431d), WTC(0xc2d86c9e), WTC(0xc28300a6), + WTC(0xc22fae33), WTC(0xc1ded3f7), WTC(0xc1908d7d), WTC(0xc144b0ed), + WTC(0xc0fa7cee), WTC(0xc0b0a3b5), WTC(0xc066b8d3), WTC(0xc01d3b32), + WTC(0xbfd5161c), WTC(0xbf8f92af), WTC(0xbf4d5cea), WTC(0xbf0e7d5e), + WTC(0xbed2ce3a), WTC(0xbe9a0062), WTC(0xbe63cec2), WTC(0xbe2ffd2f), + WTC(0xbdfe4565), WTC(0xbdce5568), WTC(0xbda003df), WTC(0xbd735018), + WTC(0xbd485b2c), WTC(0xbd1f69bd), WTC(0xbcf8db7c), WTC(0xbcd52b0a), + WTC(0xbcb4ae4a), WTC(0xbc979382), WTC(0xbc7dcbab), WTC(0xbc6709dc), + WTC(0xbc52c1b1), WTC(0xbc402f2b), WTC(0xbc2ec37b), WTC(0xbc1e2cb3), + WTC(0xbc0e5d5f), WTC(0xbbff8f23), WTC(0xbbf238d2), WTC(0xbbe707d4), + WTC(0xbbde3c63), WTC(0xbbd7a658), WTC(0xbbd2c7f0), WTC(0xbbcee18b), + WTC(0xbbcbdebb), WTC(0xbbca5ab1), WTC(0xbbcb5622), WTC(0xbbd032e4), + WTC(0xbbd91d4d), WTC(0xbbe53757), WTC(0xbbf32f54), WTC(0xbc016781), + WTC(0xbc0f433a), WTC(0xbc1d2aa4), WTC(0xbc2b4912), WTC(0xbc3985df), + WTC(0xbc47d6b9), WTC(0xbc564099), WTC(0xbc64c78a), WTC(0xbc736d96), + WTC(0xbc823210), WTC(0xbc911484), WTC(0xbca015b8), WTC(0xbcaf37eb), + WTC(0xbcbe7bc3), WTC(0xbccdde4d), WTC(0xbcdd6037), WTC(0xbced049a), + WTC(0xbcfccc81), WTC(0xbd0cb482), WTC(0xbd1cbcaa), WTC(0xbd2ce7ea), + WTC(0xbd3d363b), WTC(0xbd4da445), WTC(0xbd5e312d), WTC(0xbd6edfd1), + WTC(0xbd7fae14), WTC(0xbd90991b), WTC(0xbda19fcf), WTC(0xbdb2c464), + WTC(0xbdc4053b), WTC(0xbdd55f4b), WTC(0xbde6d0a0), WTC(0xbdf85c51), + WTC(0xbe09ffa3), WTC(0xbe1bb724), WTC(0xbe2d8160), WTC(0xbe3f5f98), + WTC(0xbe515144), WTC(0xbe6351a9), WTC(0xbe755ebd), WTC(0xbe877b8e), + WTC(0xbe99a63d), WTC(0xbeabda45), WTC(0xbebe16b0), WTC(0xbed05d1c), + WTC(0xbee2ada9), WTC(0xbef502e2), WTC(0xbf075c40), WTC(0xbf19bc0b), + WTC(0xbf2c217f), WTC(0xbf3e887a), WTC(0xbf50f09d), WTC(0xbf635c77), + WTC(0xbf75cac0), WTC(0xbf883905), WTC(0xbf9aa62b), WTC(0xbfad14f1), + WTC(0xbfbf85c7), WTC(0xbfd1f592), WTC(0xbfe461fc), WTC(0xbff6c86a), + WTC(0x80126c8d), WTC(0x80372448), WTC(0x805bd2fd), WTC(0x80807315), + WTC(0x80a4fffa), WTC(0x80c9748d), WTC(0x80edd08b), WTC(0x81121a23), + WTC(0x81364fde), WTC(0x815a6b16), WTC(0x817e6b36), WTC(0x81a25433), + WTC(0x81c625c8), WTC(0x81e9d801), WTC(0x820d6a5c), WTC(0x8230e060), + WTC(0x825438c0), WTC(0x82776ac7), WTC(0x829a7555), WTC(0x82bd5ca3), + WTC(0x82e01e80), WTC(0x8302b200), WTC(0x83251590), WTC(0x83474d79), + WTC(0x8369566f), WTC(0x838b2957), WTC(0x83acc2d9), WTC(0x83ce27c1), + WTC(0x83ef54b9), WTC(0x841042d1), WTC(0x8430ef15), WTC(0x84515e84), + WTC(0x84718e32), WTC(0x84917804), WTC(0x84b11a25), WTC(0x84d0788d), + WTC(0x84ef9322), WTC(0x850e61ec), WTC(0x852ce400), WTC(0x854b1e0a), + WTC(0x85690f2c), WTC(0x8586b207), WTC(0x85a4057b), WTC(0x85c1107d), + WTC(0x85ddd335), WTC(0x85fa485e), WTC(0x86167172), WTC(0x8632549d), + WTC(0x864df388), WTC(0x8669497e), WTC(0x86845757), WTC(0x869f2218), + WTC(0x86b9ab5a), WTC(0x86d3f1bf), WTC(0x86edf68f), WTC(0x8707baf1), + WTC(0x872147e0), WTC(0x873aa6fc), WTC(0x8753c571), WTC(0x876c76e6), + WTC(0x87850ab7), WTC(0x879e373b), WTC(0x87b6ea37), WTC(0x87cc4188), + WTC(0x880d4300), WTC(0x8855e9ff), WTC(0x88acfca0), WTC(0x890d0f94), + WTC(0x8971e7d5), WTC(0x89d8a0c1), WTC(0x8a3fc425), WTC(0x8aa74105), + WTC(0x8b0f5b93), WTC(0x8b78a107), WTC(0x8be38bb3), WTC(0x8c508092), + WTC(0x8cbfe384), WTC(0x8d3214f1), WTC(0x8da75d21), WTC(0x8e1fe96c), + WTC(0x8e9be76a), WTC(0x8f1b806c), WTC(0x8f9ed314), WTC(0x9025f26a), + WTC(0x90b0ecea), WTC(0x913fd0eb), WTC(0x91d2a684), WTC(0x92696dea), + WTC(0x93042868), WTC(0x93a2d456), WTC(0x94456d20), WTC(0x94ebe9e5), + WTC(0x95964178), WTC(0x96446a05), WTC(0x96f65958), WTC(0x97ac059a), + WTC(0x98656089), WTC(0x99225a80), WTC(0x99e2e2e8), WTC(0x9aa6e666), + WTC(0x9b6e54b8), WTC(0x9c391d99), WTC(0x9d07338a), WTC(0x9dd8888d), + WTC(0x9ead0b5c), WTC(0x9f84a871), WTC(0xa05f4fb3), WTC(0xa13cf913), + WTC(0xa21d9891), WTC(0xa3011e27), WTC(0xa3e77eb4), WTC(0xa4d0b190), + WTC(0xa5bcb0d7), WTC(0xa6ab750c), WTC(0xa79cf884), WTC(0xa89135cb), + WTC(0xa9882a44), WTC(0xaa81d578), WTC(0xab7e39a6), WTC(0xac7d5a36), + WTC(0xad7f3ba5), WTC(0xae83dfed), WTC(0xaf8b4e16), WTC(0xb095911c), + WTC(0xb1a2afd1), WTC(0xb2b2ac9f), WTC(0xb3c58807), WTC(0xb4db4d5e), + WTC(0x4a268ead), WTC(0x490b5ba7), WTC(0x47ed8d30), WTC(0x46cd10c5), + WTC(0x45a9dcc1), WTC(0x4483f267), WTC(0x435b5aeb), WTC(0x42301d12), + WTC(0x41023a15), WTC(0x3fd19bf1), WTC(0x3e9e31e1), WTC(0x3d682986), + WTC(0x3c2fc001), WTC(0x3af52d8f), WTC(0x39b88b7d), WTC(0x38798642), + WTC(0x3737e6d3), WTC(0x35f3e98a), WTC(0x34add45c), WTC(0x33660083), + WTC(0x321ccf3a), WTC(0x30d2963e), WTC(0x2f87a28f), WTC(0x2e3c22cd), + WTC(0x2cf010e5), WTC(0x2ba2ffe5), WTC(0x2a54ba93), WTC(0x290596f5), + WTC(0x27b62806), WTC(0x266762b8), WTC(0x251a11b1), WTC(0x23ce94f9), + WTC(0x22852ddb), WTC(0x213df340), WTC(0x1ff90185), WTC(0x1eb67d94), + WTC(0x1d767485), WTC(0x1c38d477), WTC(0x1afda747), WTC(0x19c5248b), + WTC(0x188f8259), WTC(0x175d0d40), WTC(0x162e5320), WTC(0x150436cd), + WTC(0x13df8d3f), WTC(0x12c102f1), WTC(0x11a8dd65), WTC(0x1096d490), + WTC(0x0f8a1755), WTC(0x0e811dcd), WTC(0x0d7acb9a), WTC(0x0c767d00), + WTC(0x0b7334d9), WTC(0x0a6fef31), WTC(0x096c5a87), WTC(0x08691adb), + WTC(0x0765e395), WTC(0x06610309), WTC(0x0558a0d2), WTC(0x044a946c), + WTC(0x033acb52), WTC(0x0234706f), WTC(0x014939dc), WTC(0x00928577), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffe73593), WTC(0xffb63fcf), WTC(0xff853c1f), WTC(0xff5454d7), + WTC(0xff23b44b), WTC(0xfef38417), WTC(0xfec3dc9a), WTC(0xfe94c511), + WTC(0xfe664753), WTC(0xfe387086), WTC(0xfe0b4e63), WTC(0xfddef15c), + WTC(0xfdb3a3f6), WTC(0xfd89e611), WTC(0xfd61c750), WTC(0xfd3ae585), + WTC(0xfd14ec09), WTC(0xfcef9b06), WTC(0xfccaf509), WTC(0xfca74180), + WTC(0xfc8518a3), WTC(0xfc655c7a), WTC(0xfc488545), WTC(0xfc2e9998), + WTC(0xfc1726bb), WTC(0xfc01463f), WTC(0xfbec2c64), WTC(0xfbd735ce), + WTC(0xfbc29e8e), WTC(0xfbaf8042), WTC(0xfb9eeba0), WTC(0xfb91dc05), + WTC(0xfb88f420), WTC(0xfb8479eb), WTC(0xfb84398b), WTC(0xfb87884b), + WTC(0xfb8da8bf), WTC(0xfb95d020), WTC(0xfb9f3e49), WTC(0xfba9448a), + WTC(0xfbb3cf10), WTC(0xfbbf67e7), WTC(0xfbccf65d), WTC(0xfbddba58), + WTC(0xfbf31f46), WTC(0xfc0eb236), WTC(0xfc3164f0), WTC(0xfc5b8269), + WTC(0xfc8c5bcd), WTC(0xfcc248ee), WTC(0xfcfb056c), WTC(0xfd33cc26), + WTC(0xfd6b84ee), WTC(0xfda2d9e7), WTC(0xfddc03fb), WTC(0xfe1aaf57), + WTC(0xfe61a0af), WTC(0xfeb28df7), WTC(0xff0cd343), WTC(0xff6d8388), + WTC(0xffd24331), WTC(0x00396fe3), WTC(0x00a2fb3e), WTC(0x01107050), + WTC(0x01831900), WTC(0x01fc2377), WTC(0x027bd1fc), WTC(0x03019a2d), + WTC(0x038d0a88), WTC(0x041dd88f), WTC(0x04b43495), WTC(0x0550c1ef), + WTC(0x05f38bd6), WTC(0x069c0523), WTC(0x074a114e), WTC(0x07fe0ceb), + WTC(0x08b88e33), WTC(0x097a5965), WTC(0x0a438318), WTC(0x0b137046), + WTC(0x0be9b5ab), WTC(0x0cc61fa9), WTC(0x0da897b2), WTC(0x0e9123b3), + WTC(0x0f7ff200), WTC(0x10755696), WTC(0x11717f94), WTC(0x127474a0), + WTC(0x137e489d), WTC(0x148f1b02), WTC(0x15a6f15e), WTC(0x16c5b7c9), + WTC(0x17eb72b1), WTC(0x19183e51), WTC(0x1a4c2444), WTC(0x1b871b1c), + WTC(0x1cc92e92), WTC(0x1e127ffc), WTC(0x1f6319b9), WTC(0x20baef78), + WTC(0x221a0861), WTC(0x23807f94), WTC(0x24ee5a89), WTC(0x2663898d), + WTC(0x27e0101e), WTC(0x2964058d), WTC(0x2aef6bcf), WTC(0x2c8230fc), + WTC(0x2e1c545b), WTC(0x2fbde72b), WTC(0x3166e76f), WTC(0x33173f5d), + WTC(0x34cee8c3), WTC(0x368debe1), WTC(0x38543d4f), WTC(0x3a21bd94), + WTC(0x3bf6576f), WTC(0x3dd1ff07), WTC(0x3fb4948e), WTC(0x419de414), + WTC(0x438dc202), WTC(0x45840e7d), WTC(0x4780a435), WTC(0x4983609f), + WTC(0x4b8cc548), WTC(0x4d9df796), WTC(0x4fb81f46), WTC(0x51dc8690), + WTC(0x000d970d), WTC(0xfff7ea67), WTC(0xfff7fc3d), WTC(0x000d3de2), + WTC(0x003720ad), WTC(0x007515f1), WTC(0x00c68f04), WTC(0x012afd3b), + WTC(0x01a1d1ec), WTC(0x022a7e69), WTC(0x02c47408), WTC(0x036f2420), + WTC(0x042a0001), WTC(0x04f47905), WTC(0x05ce007e), WTC(0x06b607be), + WTC(0x07ac0028), WTC(0x08af5b01), WTC(0x09bf89a7), WTC(0x0adbfd6d), + WTC(0x0c042798), WTC(0x0d377997), WTC(0x0e7564b5), WTC(0x0fbd5a3a), + WTC(0x110ecb85), WTC(0x126929fb), WTC(0x13cbe6e6), WTC(0x15367376), + WTC(0x16a8413f), WTC(0x1820c15f), WTC(0x199f6568), WTC(0x1b239e6b), + WTC(0x1cacdde2), WTC(0x1e3a951a), WTC(0x1fcc356f), WTC(0x2161301f), + WTC(0x22f8f6b7), WTC(0x2492fa4a), WTC(0x262eac3f), WTC(0x27cb7e20), + WTC(0x2968e0c4), WTC(0x2b064625), WTC(0x2ca31f1a), WTC(0x2e3edd2a), + WTC(0x2fd8f19f), WTC(0x3170ce00), WTC(0x3305e32c), WTC(0x3497a2df), + WTC(0x36257e78), WTC(0x37aee70b), WTC(0x39334e05), WTC(0x3ab22498), + WTC(0x3c2adc2c), WTC(0x3d9ce645), WTC(0x3f07b3ef), WTC(0x406ab6ca), + WTC(0x41c56001), WTC(0x4317214a), WTC(0x445f6b34), WTC(0x459daf5d), + WTC(0x46d15f56), WTC(0x47f9ed71), WTC(0x4916d11f), WTC(0x4a275770), + WTC(0x4b2b2fff), WTC(0x4c219eae), WTC(0x4d0a20cb), WTC(0x4de4288e), + WTC(0x4eaf263d), WTC(0x4f6a8bb8), WTC(0x5015ca33), WTC(0x50b052dd), + WTC(0x51399757), WTC(0x51b108c6), WTC(0x5216190a), WTC(0x5268387c), + WTC(0x52a6d933), WTC(0x52d16c19), WTC(0x52e7628b), WTC(0x52e82ea3), + WTC(0x52d3407d), WTC(0x52a80a28), WTC(0x5265fd43), WTC(0x520c8a1d), + WTC(0x519b22c8), WTC(0x511138e0), WTC(0x506e3c82), WTC(0x4fb1a037), + WTC(0x4edad4e3), WTC(0x4de94c2d), WTC(0x4cdc76d8), WTC(0x4bb3c683), + WTC(0x4a6eacd2), WTC(0x490c9abe), WTC(0x478d04f1), WTC(0x45f00420), + WTC(0x4445673f), WTC(0x42ac0d2e), WTC(0x41338364), WTC(0x3fdb5b58), + WTC(0x3ea1c30f), WTC(0x3d842780), WTC(0x3c7fa763), WTC(0x3b911b96), + WTC(0x3ab560bf), WTC(0x39e95908), WTC(0x3929debb), WTC(0x3873bd4d), + WTC(0x37c31db2), WTC(0x3713a59c), WTC(0x3663deb2), WTC(0x35b52f23), + WTC(0x3507c61e), WTC(0x345a7f42), WTC(0x33ac7e0c), WTC(0x32fd366f), + WTC(0x324baa28), WTC(0x319674e9), WTC(0x30dd7e1a), WTC(0x3021f3e8), + WTC(0x2f63f903), WTC(0x2ea2a1aa), WTC(0x2dddd97b), WTC(0x2d166985), + WTC(0x2c4ca42f), WTC(0x2b805cca), WTC(0x2ab162aa), WTC(0x29df7b17), }; +const FIXP_WTB ELDAnalysis240[720] = { + WTC(0xfab9477b), WTC(0xfa899344), WTC(0xfa5845dd), WTC(0xfa259762), + WTC(0xf9f1c005), WTC(0xf9bcefe6), WTC(0xf9871e8b), WTC(0xf9503397), + WTC(0xf9183f47), WTC(0xf8df4eac), WTC(0xf8a53ba7), WTC(0xf869f0be), + WTC(0xf82d9759), WTC(0xf7f0593e), WTC(0xf7b2520a), WTC(0xf773a37c), + WTC(0xf73475ce), WTC(0xf6f4bedd), WTC(0xf6b455a8), WTC(0xf6739525), + WTC(0xf6332510), WTC(0xf5f3938b), WTC(0xf5b56073), WTC(0xf57900bd), + WTC(0xf53ee82d), WTC(0xf5079149), WTC(0xf4d36ffc), WTC(0xf4a2e526), + WTC(0xf4763d91), WTC(0xf44d9872), WTC(0xf426eaed), WTC(0xf3fdc161), + WTC(0xf3d001ff), WTC(0xf39dafcc), WTC(0xf366eb43), WTC(0xf32bdcdc), + WTC(0xf2ecab80), WTC(0xf2a97b34), WTC(0xf26265ae), WTC(0xf2178a6f), + WTC(0xf1c92458), WTC(0xf17752b9), WTC(0xf121e6ac), WTC(0xf0c89a63), + WTC(0xf06b15ef), WTC(0xf0092e86), WTC(0xefa2fd42), WTC(0xef397ebc), + WTC(0xeece51c6), WTC(0xee61e8b6), WTC(0xedf3d92e), WTC(0xed82c330), + WTC(0xed0d58bb), WTC(0xec94891b), WTC(0xec19d435), WTC(0xeb9e4e4e), + WTC(0xeb221000), WTC(0xeaa32422), WTC(0xea1fb440), WTC(0xe99695d2), + WTC(0xe90859ab), WTC(0xe8775114), WTC(0xe7e62b37), WTC(0xe7578147), + WTC(0xe6cb3ac1), WTC(0xe63f5696), WTC(0xe5afe916), WTC(0xe519090f), + WTC(0xe47aab0d), WTC(0xe3d6c2d0), WTC(0xe331dae7), WTC(0xe29031e1), + WTC(0xe1f40926), WTC(0xe15d87d2), WTC(0xe0c9d727), WTC(0xe0360ad5), + WTC(0xdf9f81af), WTC(0xdf04f9f9), WTC(0xde66697f), WTC(0xddc48ca1), + WTC(0xdd20a42a), WTC(0xdc7c6853), WTC(0xdbd9a476), WTC(0xdb398a8c), + WTC(0xda9cd7c2), WTC(0xda0365cf), WTC(0xd96cad85), WTC(0xd8d7b7a3), + WTC(0xd8439e8c), WTC(0xd7afb73d), WTC(0xd71b6347), WTC(0xd686149a), + WTC(0xd5efab2c), WTC(0xd558877e), WTC(0xd4c29dbc), WTC(0xd430a0aa), + WTC(0xd3a3d490), WTC(0xd31c588f), WTC(0xd297e075), WTC(0xd213ef33), + WTC(0xd18fd566), WTC(0xd10b8d3f), WTC(0xd087b250), WTC(0xd0054ef2), + WTC(0xcf85f94a), WTC(0xcf0af5f7), WTC(0xce94faf5), WTC(0xce229409), + WTC(0xcdb0b5f8), WTC(0xcd3ec554), WTC(0xcccdbf58), WTC(0xcc5f39d5), + WTC(0xcbf49ef5), WTC(0xcb8d5f73), WTC(0xcb28801c), WTC(0xcac5a265), + WTC(0xca64ad2e), WTC(0xca05d7fd), WTC(0xc9a96602), WTC(0xc94f9f79), + WTC(0xc8f2b954), WTC(0xc899e795), WTC(0xc83f94aa), WTC(0xc7e41f63), + WTC(0xc787e69f), WTC(0xc72b3fd0), WTC(0xc6ce3f0f), WTC(0xc670c175), + WTC(0xc61224cf), WTC(0xc5b21fec), WTC(0xc55202a4), WTC(0xc4f3353a), + WTC(0xc4968597), WTC(0xc43b93f2), WTC(0xc3e03d26), WTC(0xc383a011), + WTC(0xc3268aed), WTC(0xc2ca1039), WTC(0xc26f5bcc), WTC(0xc21726c9), + WTC(0xc1c1d5b2), WTC(0xc16f66ba), WTC(0xc11f76d9), WTC(0xc0d0a9f6), + WTC(0xc081cddb), WTC(0xc0333180), WTC(0xbfe5bb54), WTC(0xbf9aee90), + WTC(0xbf53d587), WTC(0xbf108855), WTC(0xbed0de05), WTC(0xbe9477d7), + WTC(0xbe5b030f), WTC(0xbe243642), WTC(0xbdefb72f), WTC(0xbdbd29df), + WTC(0xbd8c71ab), WTC(0xbd5d99cb), WTC(0xbd30e375), WTC(0xbd06afcc), + WTC(0xbcdf8c7f), WTC(0xbcbbf704), WTC(0xbc9c307e), WTC(0xbc803b86), + WTC(0xbc67c0c7), WTC(0xbc521d3d), WTC(0xbc3e6561), WTC(0xbc2bf2cb), + WTC(0xbc1a6872), WTC(0xbc09ce15), WTC(0xbbfa764f), WTC(0xbbed1356), + WTC(0xbbe257fa), WTC(0xbbda4099), WTC(0xbbd46a31), WTC(0xbbcffa76), + WTC(0xbbcc766d), WTC(0xbbca782f), WTC(0xbbcb16c7), WTC(0xbbcff77c), + WTC(0xbbd978e6), WTC(0xbbe68e5f), WTC(0xbbf593ed), WTC(0xbc04a834), + WTC(0xbc136941), WTC(0xbc2252c3), WTC(0xbc31723d), WTC(0xbc40ab92), + WTC(0xbc4ffe2d), WTC(0xbc5f7072), WTC(0xbc6f0520), WTC(0xbc7ebd23), + WTC(0xbc8e9746), WTC(0xbc9e942f), WTC(0xbcaeb633), WTC(0xbcbefe8b), + WTC(0xbccf69bb), WTC(0xbcdff92e), WTC(0xbcf0b04f), WTC(0xbd018ebd), + WTC(0xbd129192), WTC(0xbd23b9b8), WTC(0xbd350afb), WTC(0xbd46820e), + WTC(0xbd581bfc), WTC(0xbd69db11), WTC(0xbd7bbf57), WTC(0xbd8dc584), + WTC(0xbd9feaad), WTC(0xbdb231a4), WTC(0xbdc498ea), WTC(0xbdd71cd1), + WTC(0xbde9bb57), WTC(0xbdfc77d9), WTC(0xbe0f4e93), WTC(0xbe223ae5), + WTC(0xbe353cf5), WTC(0xbe485689), WTC(0xbe5b8329), WTC(0xbe6ebe88), + WTC(0xbe820afd), WTC(0xbe956811), WTC(0xbea8d109), WTC(0xbebc4352), + WTC(0xbecfc0fb), WTC(0xbee34a07), WTC(0xbef6d884), WTC(0xbf0a6bb1), + WTC(0xbf1e0685), WTC(0xbf31a685), WTC(0xbf45483c), WTC(0xbf58eb6b), + WTC(0xbf6c9376), WTC(0xbf803c90), WTC(0xbf93e4b9), WTC(0xbfa78d05), + WTC(0xbfbb3830), WTC(0xbfcee339), WTC(0xbfe28aa9), WTC(0xbff62b89), + WTC(0x8013a5f4), WTC(0x803acfd6), WTC(0x8061eec7), WTC(0x8088fc73), + WTC(0x80aff270), WTC(0x80d6cbe5), WTC(0x80fd8c2a), WTC(0x812437a8), + WTC(0x814ac94f), WTC(0x81713adc), WTC(0x81979098), WTC(0x81bdccb7), + WTC(0x81e3e738), WTC(0x8209dd04), WTC(0x822fb23a), WTC(0x825565bb), + WTC(0x827aed94), WTC(0x82a04909), WTC(0x82c57c85), WTC(0x82ea831c), + WTC(0x830f539d), WTC(0x8333eeba), WTC(0x8358585a), WTC(0x837c882e), + WTC(0x83a07742), WTC(0x83c428a5), WTC(0x83e79c4c), WTC(0x840aca65), + WTC(0x842dad81), WTC(0x84504ac0), WTC(0x84729fb1), WTC(0x8494a4f1), + WTC(0x84b65932), WTC(0x84d7c0f8), WTC(0x84f8d936), WTC(0x85199a59), + WTC(0x853a05a1), WTC(0x855a2023), WTC(0x8579e46e), WTC(0x85994d55), + WTC(0x85b86190), WTC(0x85d723e6), WTC(0x85f58fa9), WTC(0x8613a3ce), + WTC(0x863167b5), WTC(0x864eddfe), WTC(0x866c0138), WTC(0x8688d2e4), + WTC(0x86a55901), WTC(0x86c19497), WTC(0x86dd8390), WTC(0x86f9288f), + WTC(0x871487e0), WTC(0x872fadd0), WTC(0x874a9a1e), WTC(0x876519d0), + WTC(0x877f471e), WTC(0x8799fb36), WTC(0x87b48b97), WTC(0x87cba021), + WTC(0x880f67ae), WTC(0x885e0f91), WTC(0x88bc84cd), WTC(0x89244640), + WTC(0x8990a45d), WTC(0x89fe6766), WTC(0x8a6c9065), WTC(0x8adb31e6), + WTC(0x8b4ad5b3), WTC(0x8bbc2068), WTC(0x8c2f93ff), WTC(0x8ca5a922), + WTC(0x8d1ed72d), WTC(0x8d9b7ddb), WTC(0x8e1bd6cc), WTC(0x8ea01924), + WTC(0x8f287716), WTC(0x8fb5143e), WTC(0x9046074e), WTC(0x90db612b), + WTC(0x91753263), WTC(0x92138094), WTC(0x92b64cf3), WTC(0x935d96c9), + WTC(0x94095a56), WTC(0x94b98fd4), WTC(0x956e2a87), WTC(0x96271ff6), + WTC(0x96e46309), WTC(0x97a5e80d), WTC(0x986b9e55), WTC(0x993572af), + WTC(0x9a0350ce), WTC(0x9ad52154), WTC(0x9baad10f), WTC(0x9c844cdd), + WTC(0x9d618437), WTC(0x9e4265b2), WTC(0x9f26d9ad), WTC(0xa00ec9b0), + WTC(0xa0fa2916), WTC(0xa1e8ec20), WTC(0xa2daffa4), WTC(0xa3d05468), + WTC(0xa4c8e007), WTC(0xa5c49ae4), WTC(0xa6c37c24), WTC(0xa7c57d03), + WTC(0xa8ca9750), WTC(0xa9d2c7f2), WTC(0xaade0f6f), WTC(0xabec7177), + WTC(0xacfdf2b1), WTC(0xae129740), WTC(0xaf2a6321), WTC(0xb04563a6), + WTC(0xb163a2e6), WTC(0xb28524c4), WTC(0xb3a9eaf7), WTC(0xb4d1ff1b), + WTC(0x4a1d2880), WTC(0x48eee56e), WTC(0x47bda882), WTC(0x46895c79), + WTC(0x4551f8a1), WTC(0x4417817b), WTC(0x42da023d), WTC(0x419980ca), + WTC(0x4055f463), WTC(0x3f0f3b51), WTC(0x3dc56e18), WTC(0x3c78d943), + WTC(0x3b29bf3d), WTC(0x39d84ea0), WTC(0x3884337d), WTC(0x372d2371), + WTC(0x35d364ea), WTC(0x34774cef), WTC(0x33194d3a), WTC(0x31b9d586), + WTC(0x30594fcf), WTC(0x2ef80b63), WTC(0x2d9630d5), WTC(0x2c337c00), + WTC(0x2acf6a9e), WTC(0x296a3205), WTC(0x28046825), WTC(0x269f1752), + WTC(0x253b5314), WTC(0x23d9993f), WTC(0x227a3c77), WTC(0x211d59a0), + WTC(0x1fc314fd), WTC(0x1e6b9834), WTC(0x1d16eb58), WTC(0x1bc4f82e), + WTC(0x1a75e481), WTC(0x1929f389), WTC(0x17e16ee3), WTC(0x169cd758), + WTC(0x155d1ae5), WTC(0x14235182), WTC(0x12f051de), WTC(0x11c4993b), + WTC(0x109fdf4c), WTC(0x0f81351c), WTC(0x0e66c5e6), WTC(0x0d4f4b16), + WTC(0x0c39f013), WTC(0x0b25765d), WTC(0x0a10c51e), WTC(0x08fbee35), + WTC(0x07e7986f), WTC(0x06d25fe7), WTC(0x05ba1b52), WTC(0x049c33b7), + WTC(0x0379ceb9), WTC(0x025ee7c7), WTC(0x015edc1c), WTC(0x00978deb), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffe59474), WTC(0xffb158f8), WTC(0xff7d1275), WTC(0xff48f44c), + WTC(0xff1531e3), WTC(0xfee1faa9), WTC(0xfeaf626e), WTC(0xfe7d7227), + WTC(0xfe4c383f), WTC(0xfe1bc4ff), WTC(0xfdec297f), WTC(0xfdbd9f6c), + WTC(0xfd90bbf0), WTC(0xfd65ba73), WTC(0xfd3c2d32), WTC(0xfd13ab35), + WTC(0xfcebe811), WTC(0xfcc4eeae), WTC(0xfc9f1d64), WTC(0xfc7b48b0), + WTC(0xfc5a7282), WTC(0xfc3cef9b), WTC(0xfc229f4c), WTC(0xfc0a9e29), + WTC(0xfbf3dccb), WTC(0xfbdd80c3), WTC(0xfbc7556c), WTC(0xfbb289cf), + WTC(0xfba06f99), WTC(0xfb923aca), WTC(0xfb88bb57), WTC(0xfb84457f), + WTC(0xfb848c2e), WTC(0xfb88bd28), WTC(0xfb8feda1), WTC(0xfb9928eb), + WTC(0xfba38b9e), WTC(0xfbae711c), WTC(0xfbba3538), WTC(0xfbc7af9d), + WTC(0xfbd8485e), WTC(0xfbeda238), WTC(0xfc099de4), WTC(0xfc2d981f), + WTC(0xfc59fd0d), WTC(0xfc8e1583), WTC(0xfcc7e0d7), WTC(0xfd048d03), + WTC(0xfd40dfaf), WTC(0xfd7c1d35), WTC(0xfdb767cc), WTC(0xfdf64a9f), + WTC(0xfe3d0242), WTC(0xfe8e3316), WTC(0xfeead2b9), WTC(0xff4fff8c), + WTC(0xffba7b11), WTC(0x00281cae), WTC(0x009847d1), WTC(0x010cb653), + WTC(0x01870639), WTC(0x02089db5), WTC(0x0291b571), WTC(0x0321a4c1), + WTC(0x03b7eda0), WTC(0x04544c7f), WTC(0x04f74134), WTC(0x05a16810), + WTC(0x06525829), WTC(0x070994d4), WTC(0x07c767ba), WTC(0x088c69b8), + WTC(0x09598634), WTC(0x0a2f14ca), WTC(0x0b0c677b), WTC(0x0bf0f576), + WTC(0x0cdc7f73), WTC(0x0dceed54), WTC(0x0ec84a00), WTC(0x0fc8db86), + WTC(0x10d10278), WTC(0x11e0e05e), WTC(0x12f880cc), WTC(0x1418049b), + WTC(0x153f86b3), WTC(0x166ef5a3), WTC(0x17a64878), WTC(0x18e59dde), + WTC(0x1a2d088b), WTC(0x1b7c7e41), WTC(0x1cd40ab7), WTC(0x1e33d542), + WTC(0x1f9be7a5), WTC(0x210c344f), WTC(0x2284cb85), WTC(0x2405ca48), + WTC(0x258f2b7f), WTC(0x2720e063), WTC(0x28bafd49), WTC(0x2a5d950c), + WTC(0x2c0896e4), WTC(0x2dbbf7d4), WTC(0x2f77ca28), WTC(0x313c1273), + WTC(0x3308b7e4), WTC(0x34ddb0ec), WTC(0x36bb06b7), WTC(0x38a0a935), + WTC(0x3a8e7270), WTC(0x3c844ca9), WTC(0x3e82267e), WTC(0x4087ccfa), + WTC(0x42950352), WTC(0x44a99ce7), WTC(0x46c57093), WTC(0x48e84dbe), + WTC(0x4b127506), WTC(0x4d452d29), WTC(0x4f81e066), WTC(0x51ca11c4), + WTC(0x000c82e8), WTC(0xfff6f40c), WTC(0xfffa1260), WTC(0x001530bf), + WTC(0x0047a202), WTC(0x0090b903), WTC(0x00efc89f), WTC(0x016423af), + WTC(0x01ed1d0e), WTC(0x028a0796), WTC(0x033a3620), WTC(0x03fcfb89), + WTC(0x04d1aaaa), WTC(0x05b7965c), WTC(0x06ae1179), WTC(0x07b46ee8), + WTC(0x08ca0173), WTC(0x09ee1c00), WTC(0x0b201162), WTC(0x0c5f346e), + WTC(0x0daad808), WTC(0x0f024f17), WTC(0x1064ec4b), WTC(0x11d202c4), + WTC(0x1348e514), WTC(0x14c8e62f), WTC(0x1651590a), WTC(0x17e19051), + WTC(0x1978df27), WTC(0x1b169812), WTC(0x1cba0e15), WTC(0x1e629407), + WTC(0x200f7cd4), WTC(0x21c01b29), WTC(0x2373c228), WTC(0x2529c453), + WTC(0x26e174b9), WTC(0x289a262f), WTC(0x2a532bba), WTC(0x2c0bd7b2), + WTC(0x2dc37d92), WTC(0x2f796fce), WTC(0x312d017a), WTC(0x32dd8513), + WTC(0x348a4dde), WTC(0x3632aeb3), WTC(0x37d5fa29), WTC(0x39738334), + WTC(0x3b0a9c99), WTC(0x3c9a9926), WTC(0x3e22cc21), WTC(0x3fa287dc), + WTC(0x41191f89), WTC(0x4285e5fc), WTC(0x43e82e02), WTC(0x453f4a40), + WTC(0x468a8dd9), WTC(0x47c94c23), WTC(0x48fadc7c), WTC(0x4a1e75f9), + WTC(0x4b339ecf), WTC(0x4c3981b1), WTC(0x4d2f7cd3), WTC(0x4e14e381), + WTC(0x4ee90804), WTC(0x4fab3d6a), WTC(0x505ad6bd), WTC(0x50f726a3), + WTC(0x517f7fea), WTC(0x51f335fd), WTC(0x52519b0f), WTC(0x529a01f2), + WTC(0x52cbbe31), WTC(0x52e621d9), WTC(0x52e880aa), WTC(0x52d22c7a), + WTC(0x52a278a5), WTC(0x5258b880), WTC(0x51f43e1d), WTC(0x51745c38), + WTC(0x50d8669e), WTC(0x501faf0e), WTC(0x4f49897e), WTC(0x4e554804), + WTC(0x4d423d9e), WTC(0x4c0fbd8b), WTC(0x4abd1a4d), WTC(0x4949a698), + WTC(0x47b4b7f9), WTC(0x45fe2b6d), WTC(0x44375019), WTC(0x4284e96e), + WTC(0x40f7efa2), WTC(0x3f8f8b33), WTC(0x3e494311), WTC(0x3d21e35b), + WTC(0x3c15c621), WTC(0x3b2115f3), WTC(0x3a4008aa), WTC(0x396ed2a6), + WTC(0x38a99a1d), WTC(0x37ec1177), WTC(0x3730f154), WTC(0x36756c15), + WTC(0x35bafb0d), WTC(0x35020093), WTC(0x34492381), WTC(0x338f6226), + WTC(0x32d40a34), WTC(0x3215bd73), WTC(0x315302ce), WTC(0x308c7c41), + WTC(0x2fc3532f), WTC(0x2ef6de8f), WTC(0x2e265a7f), WTC(0x2d527bfd), + WTC(0x2c7bf035), WTC(0x2ba2975b), WTC(0x2ac63552), WTC(0x29e686ca), +}; +const FIXP_WTB ELDAnalysis128[384] = { + WTC(0xfaa49e98), WTC(0xfa48929f), WTC(0xf9e7eb39), WTC(0xf983b829), + WTC(0xf91bc5cb), WTC(0xf8b0376f), WTC(0xf8408d62), WTC(0xf7cd8c1e), + WTC(0xf7580da3), WTC(0xf6e0b0dc), WTC(0xf667753c), WTC(0xf5efa4cf), + WTC(0xf57cb6de), WTC(0xf511b62b), WTC(0xf4b1a860), WTC(0xf45ee8f8), + WTC(0xf415710d), WTC(0xf3c0c4f3), WTC(0xf35c2af9), WTC(0xf2e89620), + WTC(0xf266f3cb), WTC(0xf1d819bf), WTC(0xf13cff2f), WTC(0xf09489d2), + WTC(0xefdcfa80), WTC(0xef182059), WTC(0xee4d6c60), WTC(0xed7b8da7), + WTC(0xec9c27b1), WTC(0xebb57d0d), WTC(0xeacb3918), WTC(0xe9d35591), + WTC(0xe8c9176e), WTC(0xe7b93e42), WTC(0xe6b10e47), WTC(0xe5a6b875), + WTC(0xe484c345), WTC(0xe3509f1b), WTC(0xe224254c), WTC(0xe10a4e18), + WTC(0xdff4a668), WTC(0xded3d881), WTC(0xdda5ed98), WTC(0xdc722d13), + WTC(0xdb437360), WTC(0xda1fefed), WTC(0xd90623b2), WTC(0xd7f070f5), + WTC(0xd6da361b), WTC(0xd5c0786f), WTC(0xd4a6e188), WTC(0xd39b37b4), + WTC(0xd2a01ff2), WTC(0xd1a8a05c), WTC(0xd0b0cf47), WTC(0xcfbd3527), + WTC(0xced6b8d7), WTC(0xcdff0a66), WTC(0xcd2978a4), WTC(0xcc587183), + WTC(0xcb93bfdb), WTC(0xcad80773), WTC(0xca233c2b), WTC(0xc9768b5e), + WTC(0xc8cc130c), WTC(0xc8231acd), WTC(0xc7768de4), WTC(0xc6c86bdf), + WTC(0xc6181aa1), WTC(0xc563f6ce), WTC(0xc4b33a2a), WTC(0xc4085fcf), + WTC(0xc35ae72e), WTC(0xc2ad7adf), WTC(0xc206ed94), WTC(0xc16a5744), + WTC(0xc0d59625), WTC(0xc041e21b), WTC(0xbfb1ee05), WTC(0xbf2d82ea), + WTC(0xbeb60fe9), WTC(0xbe499da8), WTC(0xbde61891), WTC(0xbd8975b6), + WTC(0xbd339d36), WTC(0xbce6a08b), WTC(0xbca5b2f9), WTC(0xbc721002), + WTC(0xbc494d41), WTC(0xbc266160), WTC(0xbc06d14f), WTC(0xbbec52c7), + WTC(0xbbdaaf79), WTC(0xbbd0be99), WTC(0xbbcae139), WTC(0xbbcd359c), + WTC(0xbbded5d3), WTC(0xbbfa58cf), WTC(0xbc162f9d), WTC(0xbc326534), + WTC(0xbc4f081c), WTC(0xbc6c1678), WTC(0xbc899f93), WTC(0xbca7a263), + WTC(0xbcc62954), WTC(0xbce52ddc), WTC(0xbd04bc7f), WTC(0xbd24cd8f), + WTC(0xbd456998), WTC(0xbd668428), WTC(0xbd88207c), WTC(0xbdaa2e4b), + WTC(0xbdccaf3e), WTC(0xbdef932c), WTC(0xbe12d936), WTC(0xbe366dd6), + WTC(0xbe5a4fd9), WTC(0xbe7e6b49), WTC(0xbea2bf3f), WTC(0xbec738b5), + WTC(0xbeebd791), WTC(0xbf108b49), WTC(0xbf3554aa), WTC(0xbf5a25cf), + WTC(0xbf7f020b), WTC(0xbfa3dd25), WTC(0xbfc8be1e), WTC(0xbfed95f6), + WTC(0x8024c933), WTC(0x806e24fb), WTC(0x80b73d96), WTC(0x80fff78c), + WTC(0x8148612f), WTC(0x8190626e), WTC(0x81d8030a), WTC(0x821f28e1), + WTC(0x8265d6be), WTC(0x82abed56), WTC(0x82f16e40), WTC(0x833636d2), + WTC(0x837a470a), WTC(0x83bd7be6), WTC(0x83ffd415), WTC(0x84412e66), + WTC(0x84818c4f), WTC(0x84c0d18c), WTC(0x84ff0429), WTC(0x853c09a5), + WTC(0x8577eacf), WTC(0x85b29402), WTC(0x85ec17bf), WTC(0x86246b50), + WTC(0x865ba7d7), WTC(0x8691c4c0), WTC(0x86c6d72a), WTC(0x86fae06c), + WTC(0x872dfcd1), WTC(0x87602c6a), WTC(0x87918a27), WTC(0x87c22ef8), + WTC(0x882f7c20), WTC(0x88dc38ab), WTC(0x89a52f47), WTC(0x8a737635), + WTC(0x8b43d08d), WTC(0x8c19be9f), WTC(0x8cf89ce7), WTC(0x8de337e9), + WTC(0x8edb3e02), WTC(0x8fe1e815), WTC(0x90f7e107), WTC(0x921d8b95), + WTC(0x9353008c), WTC(0x94982fd7), WTC(0x95ecdc6d), WTC(0x9750b87f), + WTC(0x98c36ad6), WTC(0x9a447674), WTC(0x9bd34e9c), WTC(0x9d6f76fa), + WTC(0x9f18780d), WTC(0xa0cdc487), WTC(0xa28eff8e), WTC(0xa45bbe4b), + WTC(0xa633baaf), WTC(0xa816bff0), WTC(0xaa04a90d), WTC(0xabfd7205), + WTC(0xae01356b), WTC(0xb0101477), WTC(0xb22a5244), WTC(0xb4500b02), + WTC(0x499946f3), WTC(0x475da5af), WTC(0x45173dce), WTC(0x42c610ad), + WTC(0x406a44b0), WTC(0x3e037ce8), WTC(0x3b92b806), WTC(0x39195cd0), + WTC(0x36962f17), WTC(0x340a1b28), WTC(0x3177cde6), WTC(0x2ee1f20d), + WTC(0x2c49b0d6), WTC(0x29ad3d74), WTC(0x270e9ec1), WTC(0x2474132f), + WTC(0x21e14a01), WTC(0x1f57704e), WTC(0x1cd758ce), WTC(0x1a610d48), + WTC(0x17f5db88), WTC(0x1598a188), WTC(0x134f7a40), WTC(0x111f1ca0), + WTC(0x0f053b83), WTC(0x0cf871db), WTC(0x0af19e60), WTC(0x08eaa56d), + WTC(0x06e3c473), WTC(0x04d25cc9), WTC(0x02b59b4d), WTC(0x00e5bc4c), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffcebf14), WTC(0xff6cc249), WTC(0xff0b8bda), WTC(0xfeac3e5f), + WTC(0xfe4f4638), WTC(0xfdf5052f), WTC(0xfd9e8cf4), WTC(0xfd4e34ea), + WTC(0xfd023142), WTC(0xfcb8f6f7), WTC(0xfc74e090), WTC(0xfc3b33e8), + WTC(0xfc0c1254), WTC(0xfbe1b2eb), WTC(0xfbb8ce73), WTC(0xfb97e511), + WTC(0xfb86273d), WTC(0xfb857a3e), WTC(0xfb918813), WTC(0xfba43692), + WTC(0xfbb96f24), WTC(0xfbd4dcc3), WTC(0xfc000cd5), WTC(0xfc458653), + WTC(0xfca6cd98), WTC(0xfd178c8e), WTC(0xfd872979), WTC(0xfdfa721e), + WTC(0xfe88c77c), WTC(0xff3c8b5c), WTC(0x00059ebc), WTC(0x00d91db0), + WTC(0x01bec555), WTC(0x02bdfb80), WTC(0x03d4c846), WTC(0x0501ad53), + WTC(0x064719b2), WTC(0x07a34a2b), WTC(0x0918814b), WTC(0x0aaaaa6b), + WTC(0x0c5728b9), WTC(0x0e1c1a0f), WTC(0x0ff9ccd1), WTC(0x11f21ffb), + WTC(0x1405d073), WTC(0x1635776b), WTC(0x1880f4e5), WTC(0x1ae8bdcb), + WTC(0x1d6cede3), WTC(0x200e1d93), WTC(0x22cc56fd), WTC(0x25a80858), + WTC(0x28a11bdd), WTC(0x2bb7e363), WTC(0x2eec2f0f), WTC(0x323e298d), + WTC(0x35ad7f0b), WTC(0x393a1989), WTC(0x3ce34a65), WTC(0x40a8683d), + WTC(0x44881c94), WTC(0x48813cb3), WTC(0x4c94523d), WTC(0x50c8eff0), + WTC(0x00000000), WTC(0x00000000), WTC(0x0053a1ea), WTC(0x00f67066), + WTC(0x01e3f61b), WTC(0x0317bdaf), WTC(0x048d51ca), WTC(0x06403d11), + WTC(0x082c0a34), WTC(0x0a4c43d2), WTC(0x0c9c748e), WTC(0x0f182718), + WTC(0x11bae616), WTC(0x14803c1b), WTC(0x1763b3e6), WTC(0x1a60d832), + WTC(0x1d73336b), WTC(0x20965068), WTC(0x23c5b9d6), WTC(0x26fcfa1a), + WTC(0x2a379c30), WTC(0x2d712a75), WTC(0x30a52fba), WTC(0x33cf36a9), + WTC(0x36eaca15), WTC(0x39f3743b), WTC(0x3ce4bfc2), WTC(0x3fba37b8), + WTC(0x426f6671), WTC(0x44ffd6e8), WTC(0x47671326), WTC(0x49a0b2d0), + WTC(0x4ba81be1), WTC(0x4d78fd1e), WTC(0x4f0ed503), WTC(0x50652e28), + WTC(0x51779351), WTC(0x52418fbe), WTC(0x52bead75), WTC(0x52ea76cc), + WTC(0x52c07793), WTC(0x523c3918), WTC(0x5159470e), WTC(0x50132b36), + WTC(0x4e657128), WTC(0x4c4ba31d), WTC(0x49c14b60), WTC(0x46c1e9e4), + WTC(0x4374e179), WTC(0x408377b1), WTC(0x3e0fa0aa), WTC(0x3c05d584), + WTC(0x3a4d9888), WTC(0x38cdd8fa), WTC(0x376b75c4), WTC(0x360c51a7), + WTC(0x34b12fdc), WTC(0x33550d9f), WTC(0x31f1955c), WTC(0x307ffcb2), + WTC(0x2f03c44d), WTC(0x2d7a6b86), WTC(0x2be6d3d4), WTC(0x2a48d219), +}; + +const FIXP_WTB ELDAnalysis120[360] = { + WTC(0xfaa1a40a), WTC(0xfa3f173d), WTC(0xf9d7760c), WTC(0xf96bcc12), + WTC(0xf8fbe82c), WTC(0xf887bb26), WTC(0xf80f131a), WTC(0xf7930d03), + WTC(0xf714aeaf), WTC(0xf693f5a1), WTC(0xf613385b), WTC(0xf596ef0e), + WTC(0xf522dcc4), WTC(0xf4bab1f6), WTC(0xf461700c), WTC(0xf412e1fe), + WTC(0xf3b769b1), WTC(0xf349eaca), WTC(0xf2cb9164), WTC(0xf23d6d7b), + WTC(0xf1a0ab28), WTC(0xf0f5c20f), WTC(0xf03aadd9), WTC(0xef6e8c66), + WTC(0xee984910), WTC(0xedbbcbf8), WTC(0xecd1435b), WTC(0xebdc1b77), + WTC(0xeae31338), WTC(0xe9dbea9a), WTC(0xe8c005ea), WTC(0xe79e7068), + WTC(0xe6856dce), WTC(0xe5657c79), WTC(0xe42928e9), WTC(0xe2e0756e), + WTC(0xe1a83cf5), WTC(0xe0801fab), WTC(0xdf52bfeb), WTC(0xde15d1b1), + WTC(0xdcce71ba), WTC(0xdb8931bf), WTC(0xda4fbbe8), WTC(0xd9220a98), + WTC(0xd7f9af0c), WTC(0xd6d0e1df), WTC(0xd5a41f15), WTC(0xd4790330), + WTC(0xd35f84b8), WTC(0xd255e881), WTC(0xd14daf00), WTC(0xd04638e2), + WTC(0xcf47dff7), WTC(0xce5b8850), WTC(0xcd77b1d6), WTC(0xcc960ec0), + WTC(0xcbc0a6a4), WTC(0xcaf6d4f7), WTC(0xca34fa7d), WTC(0xc97c26c0), + WTC(0xc8c6868a), WTC(0xc811f873), WTC(0xc7599db8), WTC(0xc69f9780), + WTC(0xc5e24043), WTC(0xc5226384), WTC(0xc468f547), WTC(0xc3b20be9), + WTC(0xc2f826f0), WTC(0xc242ea02), WTC(0xc19844ae), WTC(0xc0f80714), + WTC(0xc05a6da1), WTC(0xbfbfe6d3), WTC(0xbf31b5b4), WTC(0xbeb24843), + WTC(0xbe3f4cb4), WTC(0xbdd63599), WTC(0xbd74c6b2), WTC(0xbd1b7128), + WTC(0xbccd4b41), WTC(0xbc8dc08e), WTC(0xbc5ca2bd), WTC(0xbc3509f1), + WTC(0xbc11f904), WTC(0xbbf37848), WTC(0xbbddfb6b), WTC(0xbbd214ea), + WTC(0xbbcb3a11), WTC(0xbbcce581), WTC(0xbbdfa6ba), WTC(0xbbfd2fa5), + WTC(0xbc1ad516), WTC(0xbc390c16), WTC(0xbc57b323), WTC(0xbc76dd1f), + WTC(0xbc969172), WTC(0xbcb6d611), WTC(0xbcd7ac8e), WTC(0xbcf91af9), + WTC(0xbd1b20bd), WTC(0xbd3dc1f5), WTC(0xbd60f678), WTC(0xbd84bec7), + WTC(0xbda909c0), WTC(0xbdcdd76e), WTC(0xbdf3161c), WTC(0xbe18c1e5), + WTC(0xbe3ec6c5), WTC(0xbe651f19), WTC(0xbe8bb78b), WTC(0xbeb288e1), + WTC(0xbed9848b), WTC(0xbf00a16f), WTC(0xbf27d681), WTC(0xbf4f1958), + WTC(0xbf76680e), WTC(0xbf9db85c), WTC(0xbfc50e09), WTC(0xbfec5bdf), + WTC(0x80273bdb), WTC(0x807577de), WTC(0x80c3630d), WTC(0x8110e4cb), + WTC(0x815e05da), WTC(0x81aab20f), WTC(0x81f6e68e), WTC(0x824290d0), + WTC(0x828da04c), WTC(0x82d8061f), WTC(0x8321a740), WTC(0x836a77f9), + WTC(0x83b2574f), WTC(0x83f93cc1), WTC(0x843f04a6), WTC(0x8483acd1), + WTC(0x84c71639), WTC(0x850944da), WTC(0x854a1d3a), WTC(0x8589a437), + WTC(0x85c7ccf9), WTC(0x8604a42f), WTC(0x86402cfb), WTC(0x867a740d), + WTC(0x86b37ff2), WTC(0x86eb5f6f), WTC(0x87222109), WTC(0x8757eb5f), + WTC(0x878c8341), WTC(0x87c0be51), WTC(0x88345fca), WTC(0x88ef97fb), + WTC(0x89c778c5), WTC(0x8aa3cc20), WTC(0x8b833d56), WTC(0x8c6a42a9), + WTC(0x8d5cb787), WTC(0x8e5d7787), WTC(0x8f6e3c5b), WTC(0x90902640), + WTC(0x91c3ca28), WTC(0x9309622d), WTC(0x9460e7d0), WTC(0x95ca1ad2), + WTC(0x97449dff), WTC(0x98d00612), WTC(0x9a6bbc19), WTC(0x9c17164d), + WTC(0x9dd180fc), WTC(0x9f9a6304), WTC(0xa1711f56), WTC(0xa355425e), + WTC(0xa5465846), WTC(0xa744190f), WTC(0xa94e4ca9), WTC(0xab64dcf0), + WTC(0xad87e068), WTC(0xafb77bfa), WTC(0xb1f3fb2b), WTC(0xb43d885c), + WTC(0x49866451), WTC(0x4723e56b), WTC(0x44b51e8d), WTC(0x423a2180), + WTC(0x3fb2fe0f), WTC(0x3d1f78f2), WTC(0x3a8153b7), WTC(0x37d906ff), + WTC(0x35259e7e), WTC(0x3269ba18), WTC(0x2fa8c1ea), WTC(0x2ce4fbab), + WTC(0x2a1cebd5), WTC(0x27519ac1), WTC(0x248a2de9), WTC(0x21cb7a79), + WTC(0x1f16fc13), WTC(0x1c6d9a50), WTC(0x19cf83c1), WTC(0x173e9943), + WTC(0x14bf6a71), WTC(0x12598f74), WTC(0x100fe27f), WTC(0x0ddab46a), + WTC(0x0bafab9d), WTC(0x09864fc7), WTC(0x075d3ac8), WTC(0x052c0fc2), + WTC(0x02ea842b), WTC(0x00f21d19), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), WTC(0x00000000), + WTC(0xffcb7b4d), WTC(0xff62fb20), WTC(0xfefb82e2), WTC(0xfe965482), + WTC(0xfe33e4bf), WTC(0xfdd4b9b5), WTC(0xfd7b04ec), WTC(0xfd27cfe4), + WTC(0xfcd84cfd), WTC(0xfc8ce1d4), WTC(0xfc4b45e1), WTC(0xfc1666da), + WTC(0xfbe8af26), WTC(0xfbbcad9e), WTC(0xfb98c6ad), WTC(0xfb85dd87), + WTC(0xfb86355b), WTC(0xfb94589b), WTC(0xfba8ed8a), WTC(0xfbc0a735), + WTC(0xfbe23f8d), WTC(0xfc1a92c4), WTC(0xfc73315f), WTC(0xfce611a1), + WTC(0xfd5e94d9), WTC(0xfdd61cab), WTC(0xfe6427fd), WTC(0xff1c92da), + WTC(0xfff10542), WTC(0x00d1d58a), WTC(0x01c6daab), WTC(0x02d8dbc3), + WTC(0x040557a6), WTC(0x054b6f91), WTC(0x06ad2b2b), WTC(0x0828f4c5), + WTC(0x09c348d1), WTC(0x0b7dcb56), WTC(0x0d54d98e), WTC(0x0f47a599), + WTC(0x1157fa1b), WTC(0x138743ae), WTC(0x15d6423f), WTC(0x1844f0ae), + WTC(0x1ad3c273), WTC(0x1d82e65c), WTC(0x205306e1), WTC(0x23443d5c), + WTC(0x2656fae8), WTC(0x298b3a5a), WTC(0x2ce13a7d), WTC(0x3058e0e3), + WTC(0x33f22950), WTC(0x37acd0b2), WTC(0x3b885e6b), WTC(0x3f840412), + WTC(0x439e65ee), WTC(0x47d6014e), WTC(0x4c2aa857), WTC(0x50a46876), + WTC(0xfffe9b02), WTC(0x0004ac61), WTC(0x0069639d), WTC(0x0127578b), + WTC(0x02391efe), WTC(0x039950cc), WTC(0x054283bf), WTC(0x072f4eba), + WTC(0x095a488c), WTC(0x0bbe0802), WTC(0x0e5523f9), WTC(0x111a332e), + WTC(0x1407cca2), WTC(0x171886f5), WTC(0x1a46f927), WTC(0x1d8db9e1), + WTC(0x20e7600d), WTC(0x244e82a3), WTC(0x27bdb846), WTC(0x2b2f97a8), + WTC(0x2e9eb7ea), WTC(0x3205afd1), WTC(0x355f161c), WTC(0x38a581d7), + WTC(0x3bd3894a), WTC(0x3ee3c398), WTC(0x41d0c7ae), WTC(0x44952cb8), + WTC(0x472b8856), WTC(0x498e7eee), WTC(0x4bb88245), WTC(0x4da44d9f), + WTC(0x4f4c6b7d), WTC(0x50ab7298), WTC(0x51bbfa11), WTC(0x527898fb), + WTC(0x52dbe5f2), WTC(0x52e07778), WTC(0x5280e51f), WTC(0x51b7c4f1), + WTC(0x507fadc7), WTC(0x4ed336dd), WTC(0x4cacf749), WTC(0x4a078534), + WTC(0x46dd6dcc), WTC(0x43599e22), WTC(0x403f48da), WTC(0x3db1ed89), + WTC(0x3b98bd24), WTC(0x39d5b003), WTC(0x384a3292), WTC(0x36d328ff), + WTC(0x355e63a6), WTC(0x33ec69d8), WTC(0x32755ebd), WTC(0x30f01fce), + WTC(0x2f5d9646), WTC(0x2dbcc615), WTC(0x2c0fa145), WTC(0x2a56ce53), +}; diff --git a/libAACenc/src/aacEnc_rom.h b/libAACenc/src/aacEnc_rom.h index 862417f..fd50cab 100644 --- a/libAACenc/src/aacEnc_rom.h +++ b/libAACenc/src/aacEnc_rom.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,39 +90,42 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/****************************************************************************** + Author(s): M. Lohwasser, M. Gayer - Initial authors: M. Lohwasser, M. Gayer - Contents/description: + Description: + +*******************************************************************************/ -******************************************************************************/ /*! \file - \brief Memory layout + \brief Memory layout \author Markus Lohwasser */ -#ifndef AAC_ENC_ROM_H -#define AAC_ENC_ROM_H +#ifndef AACENC_ROM_H +#define AACENC_ROM_H #include "common_fix.h" #include "psy_const.h" #include "psy_configuration.h" #include "FDK_tools_rom.h" +#include "FDK_lpc.h" /* Huffman Tables */ -extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]; -extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]; -extern const ULONG FDKaacEnc_huff_ltab5_6[9][9]; -extern const ULONG FDKaacEnc_huff_ltab7_8[8][8]; -extern const ULONG FDKaacEnc_huff_ltab9_10[13][13]; -extern const UCHAR FDKaacEnc_huff_ltab11[17][17]; -extern const UCHAR FDKaacEnc_huff_ltabscf[121]; +extern const ULONG FDKaacEnc_huff_ltab1_2[3][3][3][3]; +extern const ULONG FDKaacEnc_huff_ltab3_4[3][3][3][3]; +extern const ULONG FDKaacEnc_huff_ltab5_6[9][9]; +extern const ULONG FDKaacEnc_huff_ltab7_8[8][8]; +extern const ULONG FDKaacEnc_huff_ltab9_10[13][13]; +extern const UCHAR FDKaacEnc_huff_ltab11[17][17]; +extern const UCHAR FDKaacEnc_huff_ltabscf[121]; extern const USHORT FDKaacEnc_huff_ctab1[3][3][3][3]; extern const USHORT FDKaacEnc_huff_ctab2[3][3][3][3]; extern const USHORT FDKaacEnc_huff_ctab3[3][3][3][3]; @@ -123,13 +137,13 @@ extern const USHORT FDKaacEnc_huff_ctab8[8][8]; extern const USHORT FDKaacEnc_huff_ctab9[13][13]; extern const USHORT FDKaacEnc_huff_ctab10[13][13]; extern const USHORT FDKaacEnc_huff_ctab11[21][17]; -extern const ULONG FDKaacEnc_huff_ctabscf[121]; +extern const ULONG FDKaacEnc_huff_ctabscf[121]; /* quantizer */ #define MANT_DIGITS 9 -#define MANT_SIZE (1<<MANT_DIGITS) +#define MANT_SIZE (1 << MANT_DIGITS) #if defined(ARCH_PREFER_MULT_32x16) #define FIXP_QTD FIXP_SGL @@ -147,50 +161,47 @@ extern const FIXP_DBL FDKaacEnc_mTab_4_3Elc[512]; extern const FIXP_DBL FDKaacEnc_specExpMantTableCombElc[4][14]; extern const UCHAR FDKaacEnc_specExpTableComb[4][14]; - /* table to count used number of bits */ -extern const SHORT FDKaacEnc_sideInfoTabLong[MAX_SFB_LONG + 1]; -extern const SHORT FDKaacEnc_sideInfoTabShort[MAX_SFB_SHORT + 1]; - +extern const SHORT FDKaacEnc_sideInfoTabLong[]; +extern const SHORT FDKaacEnc_sideInfoTabShort[]; /* Psy Configuration constants */ -extern const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_8000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_8000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_11025_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_11025_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_12000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_12000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_16000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_16000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_22050_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_22050_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_24000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_24000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_32000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_32000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_44100_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_44100_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_48000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_48000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_64000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_64000_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_88200_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_88200_short_128; -extern const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024; +extern const SFB_PARAM_LONG p_FDKaacEnc_96000_long_1024; extern const SFB_PARAM_SHORT p_FDKaacEnc_96000_short_128; - /* TNS filter coefficients */ -extern const FIXP_DBL FDKaacEnc_tnsEncCoeff3[8]; -extern const FIXP_DBL FDKaacEnc_tnsCoeff3Borders[8]; -extern const FIXP_DBL FDKaacEnc_tnsEncCoeff4[16]; -extern const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]; +extern const FIXP_LPC FDKaacEnc_tnsEncCoeff3[8]; +extern const FIXP_LPC FDKaacEnc_tnsCoeff3Borders[8]; +extern const FIXP_LPC FDKaacEnc_tnsEncCoeff4[16]; +extern const FIXP_LPC FDKaacEnc_tnsCoeff4Borders[16]; #define WTC0 WTC #define WTC1 WTC @@ -198,6 +209,9 @@ extern const FIXP_DBL FDKaacEnc_tnsCoeff4Borders[16]; extern const FIXP_WTB ELDAnalysis512[1536]; extern const FIXP_WTB ELDAnalysis480[1440]; +extern const FIXP_WTB ELDAnalysis256[768]; +extern const FIXP_WTB ELDAnalysis240[720]; +extern const FIXP_WTB ELDAnalysis128[384]; +extern const FIXP_WTB ELDAnalysis120[360]; - -#endif /* #ifndef AAC_ENC_ROM_H */ +#endif /* #ifndef AACENC_ROM_H */ diff --git a/libAACenc/src/aacenc.cpp b/libAACenc/src/aacenc.cpp index 5e8c08d..8b8a1ad 100644 --- a/libAACenc/src/aacenc.cpp +++ b/libAACenc/src/aacenc.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/*************************** Fast MPEG AAC Audio Encoder ********************** + Author(s): M. Schug / A. Groeschel - Initial author: M. Schug / A. Groeschel - contents/description: fast aac coder functions + Description: fast aac coder functions -******************************************************************************/ +*******************************************************************************/ #include "aacenc.h" @@ -102,74 +114,53 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" +#define BITRES_MAX_LD 4000 +#define BITRES_MIN_LD 500 +#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */ +#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */ + +INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength, + const INT samplingRate) { + int shift = 0; + while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength && + (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) { + shift++; + } - - -#define MIN_BUFSIZE_PER_EFF_CHAN 6144 - -INT FDKaacEnc_CalcBitsPerFrame( - const INT bitRate, - const INT frameLength, - const INT samplingRate - ) -{ - int shift = 0; - while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength - && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) - { - shift++; - } - - return (bitRate*(frameLength>>shift)) / (samplingRate>>shift); + return (bitRate * (frameLength >> shift)) / (samplingRate >> shift); } -INT FDKaacEnc_CalcBitrate( - const INT bitsPerFrame, - const INT frameLength, - const INT samplingRate - ) -{ - int shift = 0; - while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength - && (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) - { - shift++; - } - - return (bitsPerFrame * (samplingRate>>shift)) / ( frameLength>>shift) ; +INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength, + const INT samplingRate) { + int shift = 0; + while ((frameLength & ~((1 << (shift + 1)) - 1)) == frameLength && + (samplingRate & ~((1 << (shift + 1)) - 1)) == samplingRate) { + shift++; + } + return (bitsPerFrame * (samplingRate >> shift)) / (frameLength >> shift); } -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate); - -INT FDKaacEnc_LimitBitrate( - HANDLE_TRANSPORTENC hTpEnc, - INT coreSamplingRate, - INT frameLength, - INT nChannels, - INT nChannelsEff, - INT bitRate, - INT averageBits, - INT *pAverageBitsPerFrame, - INT bitrateMode, - INT nSubFrames - ) -{ - INT transportBits, prevBitRate, averageBitsPerFrame, shift = 0, iter=0; - - while ( (frameLength & ~((1<<(shift+1))-1)) == frameLength - && (coreSamplingRate & ~((1<<(shift+1))-1)) == coreSamplingRate ) - { - shift ++; +static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary( + INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame, + INT sampleRate); + +INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot, + INT coreSamplingRate, INT frameLength, INT nChannels, + INT nChannelsEff, INT bitRate, INT averageBits, + INT *pAverageBitsPerFrame, + AACENC_BITRATE_MODE bitrateMode, INT nSubFrames) { + INT transportBits, prevBitRate, averageBitsPerFrame, minBitrate = 0, iter = 0; + INT minBitsPerFrame = 40 * nChannels; + if (isLowDelay(aot)) { + minBitrate = 8000 * nChannelsEff; } do { prevBitRate = bitRate; - averageBitsPerFrame = (bitRate*(frameLength>>shift)) / (coreSamplingRate>>shift) / nSubFrames; + averageBitsPerFrame = + FDKaacEnc_CalcBitsPerFrame(bitRate, frameLength, coreSamplingRate) / + nSubFrames; if (pAverageBitsPerFrame != NULL) { *pAverageBitsPerFrame = averageBitsPerFrame; @@ -182,32 +173,34 @@ INT FDKaacEnc_LimitBitrate( transportBits = 208; } - bitRate = FDKmax(bitRate, ((((40 * nChannels) + transportBits) * (coreSamplingRate)) / frameLength) ); + bitRate = fMax(bitRate, + fMax(minBitrate, + FDKaacEnc_CalcBitrate((minBitsPerFrame + transportBits), + frameLength, coreSamplingRate))); FDK_ASSERT(bitRate >= 0); - bitRate = FDKmin(bitRate, ((nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN)*(coreSamplingRate>>shift)) / (frameLength>>shift)) ; + bitRate = fMin(bitRate, FDKaacEnc_CalcBitrate( + (nChannelsEff * MIN_BUFSIZE_PER_EFF_CHAN), + frameLength, coreSamplingRate)); FDK_ASSERT(bitRate >= 0); - } while (prevBitRate != bitRate && iter++ < 3) ; + } while (prevBitRate != bitRate && iter++ < 3); return bitRate; } - -typedef struct -{ +typedef struct { AACENC_BITRATE_MODE bitrateMode; int chanBitrate[2]; /* mono/stereo settings */ } CONFIG_TAB_ENTRY_VBR; static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = { - {AACENC_BR_MODE_CBR, { 0, 0}} , - {AACENC_BR_MODE_VBR_1, { 32000, 20000}} , - {AACENC_BR_MODE_VBR_2, { 40000, 32000}} , - {AACENC_BR_MODE_VBR_3, { 56000, 48000}} , - {AACENC_BR_MODE_VBR_4, { 72000, 64000}} , - {AACENC_BR_MODE_VBR_5, {112000, 96000}} -}; + {AACENC_BR_MODE_CBR, {0, 0}}, + {AACENC_BR_MODE_VBR_1, {32000, 20000}}, + {AACENC_BR_MODE_VBR_2, {40000, 32000}}, + {AACENC_BR_MODE_VBR_3, {56000, 48000}}, + {AACENC_BR_MODE_VBR_4, {72000, 64000}}, + {AACENC_BR_MODE_VBR_5, {112000, 96000}}}; /*----------------------------------------------------------------------------- @@ -218,30 +211,30 @@ static const CONFIG_TAB_ENTRY_VBR configTabVBR[] = { returns: vbr bitrate ------------------------------------------------------------------------------*/ -INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) -{ +INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode, + CHANNEL_MODE channelMode) { INT bitrate = 0; INT monoStereoMode = 0; /* default mono */ - if (FDKaacEnc_GetMonoStereoMode(channelMode)==EL_MODE_STEREO) { - monoStereoMode = 1; + if (FDKaacEnc_GetMonoStereoMode(channelMode) == EL_MODE_STEREO) { + monoStereoMode = 1; } - switch((AACENC_BITRATE_MODE)bitrateMode){ - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode]; - break; - case AACENC_BR_MODE_INVALID: - case AACENC_BR_MODE_CBR: - case AACENC_BR_MODE_SFR: - case AACENC_BR_MODE_FF: - default: - bitrate = 0; - break; + switch (bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + bitrate = configTabVBR[bitrateMode].chanBitrate[monoStereoMode]; + break; + case AACENC_BR_MODE_INVALID: + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_SFR: + case AACENC_BR_MODE_FF: + default: + bitrate = 0; + break; } /* convert channel bitrate to overall bitrate*/ @@ -257,38 +250,39 @@ INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode) * * \return Corrected bitreservoir level used in transport library. */ -static INT FDKaacEnc_EncBitresToTpBitres( - const HANDLE_AAC_ENC hAacEnc - ) -{ - INT transporBitreservoir = 0; +static INT FDKaacEnc_EncBitresToTpBitres(const HANDLE_AAC_ENC hAacEnc) { + INT transportBitreservoir = 0; switch (hAacEnc->bitrateMode) { case AACENC_BR_MODE_CBR: - transporBitreservoir = hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */ + transportBitreservoir = + hAacEnc->qcKernel->bitResTot; /* encoder bitreservoir level */ break; case AACENC_BR_MODE_VBR_1: case AACENC_BR_MODE_VBR_2: case AACENC_BR_MODE_VBR_3: case AACENC_BR_MODE_VBR_4: case AACENC_BR_MODE_VBR_5: - transporBitreservoir = FDK_INT_MAX; /* signal variable bitrate */ + transportBitreservoir = FDK_INT_MAX; /* signal variable bitrate */ break; - case AACENC_BR_MODE_FF: case AACENC_BR_MODE_SFR: - transporBitreservoir = 0; /* super framing and fixed framing */ - break; /* without bitreservoir signaling */ + transportBitreservoir = 0; /* super framing and fixed framing */ + break; /* without bitreservoir signaling */ default: case AACENC_BR_MODE_INVALID: - transporBitreservoir = 0; /* invalid configuration*/ - FDK_ASSERT(0); + transportBitreservoir = 0; /* invalid configuration*/ } - if (hAacEnc->config->audioMuxVersion==2) { - transporBitreservoir = MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff; + if (hAacEnc->config->audioMuxVersion == 2) { + transportBitreservoir = + MIN_BUFSIZE_PER_EFF_CHAN * hAacEnc->channelMapping.nChannelsEff; } - return transporBitreservoir; + return transportBitreservoir; +} + +INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder) { + return FDKaacEnc_EncBitresToTpBitres(hAacEncoder); } /*----------------------------------------------------------------------------- @@ -298,40 +292,39 @@ static INT FDKaacEnc_EncBitresToTpBitres( returns: --- ------------------------------------------------------------------------------*/ -void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) -{ - /* make thepre initialization of the structs flexible */ - FDKmemclear(config, sizeof(AACENC_CONFIG)); - - /* default ancillary */ - config->anc_Rate = 0; /* no ancillary data */ - config->ancDataBitRate = 0; /* no additional consumed bitrate */ - - /* default configurations */ - config->bitRate = -1; /* bitrate must be set*/ - config->averageBits = -1; /* instead of bitrate/s we can configure bits/superframe */ - config->bitrateMode = 0; - config->bandWidth = 0; /* get bandwidth from table */ - config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */ - config->usePns = 1; /* depending on channelBitrate this might be set to 0 later */ - config->useIS = 1; /* Intensity Stereo Configuration */ - config->framelength = -1; /* Framesize not configured */ - config->syntaxFlags = 0; /* default syntax with no specialities */ - config->epConfig = -1; /* no ER syntax -> no additional error protection */ - config->nSubFrames = 1; /* default, no sub frames */ - config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */ - config->channelMode = MODE_UNKNOWN; - config->minBitsPerFrame = -1; /* minum number of bits in each AU */ - config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ - config->bitreservoir = -1; /* default, uninitialized value */ - config->audioMuxVersion = -1; /* audio mux version not configured */ - - /* init tabs in fixpoint_math */ - InitLdInt(); - InitInvSqrtTab(); +void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) { + /* make the preinitialization of the structs flexible */ + FDKmemclear(config, sizeof(AACENC_CONFIG)); + + /* default ancillary */ + config->anc_Rate = 0; /* no ancillary data */ + config->ancDataBitRate = 0; /* no additional consumed bitrate */ + + /* default configurations */ + config->bitRate = -1; /* bitrate must be set*/ + config->averageBits = + -1; /* instead of bitrate/s we can configure bits/superframe */ + config->bitrateMode = + AACENC_BR_MODE_CBR; /* set bitrate mode to constant bitrate */ + config->bandWidth = 0; /* get bandwidth from table */ + config->useTns = TNS_ENABLE_MASK; /* tns enabled completly */ + config->usePns = + 1; /* depending on channelBitrate this might be set to 0 later */ + config->useIS = 1; /* Intensity Stereo Configuration */ + config->useMS = 1; /* MS Stereo tool */ + config->framelength = -1; /* Framesize not configured */ + config->syntaxFlags = 0; /* default syntax with no specialities */ + config->epConfig = -1; /* no ER syntax -> no additional error protection */ + config->nSubFrames = 1; /* default, no sub frames */ + config->channelOrder = CH_ORDER_MPEG; /* Use MPEG channel ordering. */ + config->channelMode = MODE_UNKNOWN; + config->minBitsPerFrame = -1; /* minum number of bits in each AU */ + config->maxBitsPerFrame = -1; /* minum number of bits in each AU */ + config->audioMuxVersion = -1; /* audio mux version not configured */ + config->downscaleFactor = + 1; /* downscale factor for ELD reduced delay mode, 1 is normal ELD */ } - /*--------------------------------------------------------------------------- functionname: FDKaacEnc_Open @@ -339,16 +332,13 @@ void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config) returns: error code ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, - const INT nElements, - const INT nChannels, - const INT nSubFrames) -{ +AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, const INT nElements, + const INT nChannels, const INT nSubFrames) { AAC_ENCODER_ERROR ErrorStatus; - AAC_ENC *hAacEnc = NULL; - UCHAR *dynamicRAM = NULL; + AAC_ENC *hAacEnc = NULL; + UCHAR *dynamicRAM = NULL; - if (phAacEnc==NULL) { + if (phAacEnc == NULL) { return AAC_ENC_INVALID_HANDLE; } @@ -360,82 +350,65 @@ AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, } FDKmemclear(hAacEnc, sizeof(AAC_ENC)); - hAacEnc->dynamic_RAM = GetAACdynamic_RAM(); - dynamicRAM = (UCHAR*)hAacEnc->dynamic_RAM; + if (NULL == (hAacEnc->dynamic_RAM = GetAACdynamic_RAM())) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } + dynamicRAM = (UCHAR *)hAacEnc->dynamic_RAM; /* allocate the Psy aud Psy Out structure */ - ErrorStatus = FDKaacEnc_PsyNew(&hAacEnc->psyKernel, - nElements, - nChannels - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = + FDKaacEnc_PsyNew(&hAacEnc->psyKernel, nElements, nChannels, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; + + ErrorStatus = FDKaacEnc_PsyOutNew(hAacEnc->psyOut, nElements, nChannels, + nSubFrames, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; /* allocate the Q&C Out structure */ - ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, - nElements, - nChannels, - nSubFrames - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCOutNew(hAacEnc->qcOut, nElements, nChannels, + nSubFrames, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; /* allocate the Q&C kernel */ - ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, - nElements - ,dynamicRAM - ); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCNew(&hAacEnc->qcKernel, nElements, dynamicRAM); + if (ErrorStatus != AAC_ENC_OK) goto bail; hAacEnc->maxChannels = nChannels; hAacEnc->maxElements = nElements; - hAacEnc->maxFrames = nSubFrames; + hAacEnc->maxFrames = nSubFrames; bail: *phAacEnc = hAacEnc; return ErrorStatus; } - -AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, - AACENC_CONFIG *config, /* pre-initialized config struct */ - HANDLE_TRANSPORTENC hTpEnc, - ULONG initFlags) -{ +AAC_ENCODER_ERROR FDKaacEnc_Initialize( + HANDLE_AAC_ENC hAacEnc, + AACENC_CONFIG *config, /* pre-initialized config struct */ + HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags) { AAC_ENCODER_ERROR ErrorStatus; - INT psyBitrate, tnsMask; //INT profile = 1; - CHANNEL_MAPPING *cm = NULL; + INT psyBitrate, tnsMask; // INT profile = 1; + CHANNEL_MAPPING *cm = NULL; - INT qmbfac, qbw; + INT mbfac_e, qbw; FIXP_DBL mbfac, bw_ratio; QC_INIT qcInit; INT averageBitsPerFrame = 0; + int bitresMin = 0; /* the bitreservoir is always big for AAC-LC */ + const CHANNEL_MODE prevChannelMode = hAacEnc->encoderMode; - if (config==NULL) - return AAC_ENC_INVALID_HANDLE; + if (config == NULL) return AAC_ENC_INVALID_HANDLE; /******************* sanity checks *******************/ /* check config structure */ - if (config->nChannels < 1 || config->nChannels > (8)) { + if (config->nChannels < 1 || config->nChannels > (8)) { return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } /* check sample rate */ - switch (config->sampleRate) - { + switch (config->sampleRate) { case 8000: case 11025: case 12000: @@ -454,52 +427,44 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, } /* bitrate has to be set */ - if (config->bitRate==-1) { - return AAC_ENC_UNSUPPORTED_BITRATE; + if (config->bitRate == -1) { + return AAC_ENC_UNSUPPORTED_BITRATE; } /* check bit rate */ if (FDKaacEnc_LimitBitrate( - hTpEnc, - config->sampleRate, - config->framelength, - config->nChannels, - FDKaacEnc_GetChannelModeConfiguration(config->channelMode)->nChannelsEff, - config->bitRate, - config->averageBits, - &averageBitsPerFrame, - config->bitrateMode, - config->nSubFrames - ) != config->bitRate - && !((config->bitrateMode>=1) && (config->bitrateMode<=5)) - ) - { + hTpEnc, config->audioObjectType, config->sampleRate, + config->framelength, config->nChannels, + FDKaacEnc_GetChannelModeConfiguration(config->channelMode) + ->nChannelsEff, + config->bitRate, config->averageBits, &averageBitsPerFrame, + config->bitrateMode, config->nSubFrames) != config->bitRate && + !(AACENC_BR_MODE_IS_VBR(config->bitrateMode))) { return AAC_ENC_UNSUPPORTED_BITRATE; } if (config->syntaxFlags & AC_ER_VCB11) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; + return AAC_ENC_UNSUPPORTED_ER_FORMAT; } if (config->syntaxFlags & AC_ER_HCR) { - return AAC_ENC_UNSUPPORTED_ER_FORMAT; + return AAC_ENC_UNSUPPORTED_ER_FORMAT; } /* check frame length */ - switch (config->framelength) - { + switch (config->framelength) { case 1024: - if ( config->audioObjectType == AOT_ER_AAC_LD - || config->audioObjectType == AOT_ER_AAC_ELD ) - { + if (isLowDelay(config->audioObjectType)) { return AAC_ENC_INVALID_FRAME_LENGTH; } break; + case 128: + case 256: case 512: + case 120: + case 240: case 480: - if ( config->audioObjectType != AOT_ER_AAC_LD - && config->audioObjectType != AOT_ER_AAC_ELD ) - { + if (!isLowDelay(config->audioObjectType)) { return AAC_ENC_INVALID_FRAME_LENGTH; } break; @@ -508,189 +473,241 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEnc, } if (config->anc_Rate != 0) { - - ErrorStatus = FDKaacEnc_InitCheckAncillary(config->bitRate, - config->framelength, - config->anc_Rate, - &hAacEnc->ancillaryBitsPerFrame, - config->sampleRate); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - /* update estimated consumed bitrate */ - config->ancDataBitRate += ( (hAacEnc->ancillaryBitsPerFrame * config->sampleRate) / config->framelength ); - + ErrorStatus = FDKaacEnc_InitCheckAncillary( + config->bitRate, config->framelength, config->anc_Rate, + &hAacEnc->ancillaryBitsPerFrame, config->sampleRate); + if (ErrorStatus != AAC_ENC_OK) goto bail; + + /* update estimated consumed bitrate */ + config->ancDataBitRate += + FDKaacEnc_CalcBitrate(hAacEnc->ancillaryBitsPerFrame, + config->framelength, config->sampleRate); } /* maximal allowed DSE bytes in frame */ - { - /* fixpoint calculation*/ - INT q_res, encBitrate, sc; - FIXP_DBL tmp = fDivNorm(config->framelength, config->sampleRate, &q_res); - encBitrate = (config->bitRate/*-config->ancDataBitRate*/)- (INT)(config->nChannels*8000); - sc = CountLeadingBits(encBitrate); - config->maxAncBytesPerAU = FDKmin( (256), FDKmax(0,(INT)(fMultDiv2(tmp, (FIXP_DBL)(encBitrate<<sc))>>(-q_res+sc-1+3))) ); - } + config->maxAncBytesPerAU = + fMin((256), fMax(0, FDKaacEnc_CalcBitsPerFrame( + (config->bitRate - (config->nChannels * 8000)), + config->framelength, config->sampleRate) >> + 3)); /* bind config to hAacEnc->config */ hAacEnc->config = config; /* set hAacEnc->bitrateMode */ - hAacEnc->bitrateMode = (AACENC_BITRATE_MODE)config->bitrateMode; + hAacEnc->bitrateMode = config->bitrateMode; hAacEnc->encoderMode = config->channelMode; - ErrorStatus = FDKaacEnc_InitChannelMapping(hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_InitChannelMapping( + hAacEnc->encoderMode, config->channelOrder, &hAacEnc->channelMapping); + if (ErrorStatus != AAC_ENC_OK) goto bail; cm = &hAacEnc->channelMapping; - ErrorStatus = FDKaacEnc_DetermineBandWidth(&hAacEnc->config->bandWidth, - config->bandWidth, - config->bitRate - config->ancDataBitRate, - hAacEnc->bitrateMode, - config->sampleRate, - config->framelength, - cm, - hAacEnc->encoderMode); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_DetermineBandWidth( + config->bandWidth, config->bitRate - config->ancDataBitRate, + hAacEnc->bitrateMode, config->sampleRate, config->framelength, cm, + hAacEnc->encoderMode, &hAacEnc->config->bandWidth); + if (ErrorStatus != AAC_ENC_OK) goto bail; hAacEnc->bandwidth90dB = (INT)hAacEnc->config->bandWidth; tnsMask = config->useTns ? TNS_ENABLE_MASK : 0x0; psyBitrate = config->bitRate - config->ancDataBitRate; - ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, - hAacEnc->psyOut, - hAacEnc->maxFrames, - hAacEnc->maxChannels, - config->audioObjectType, - cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + if ((hAacEnc->encoderMode != prevChannelMode) || (initFlags != 0)) { + /* Reinitialize psych states in case of channel configuration change ore if + * full reset requested. */ + ErrorStatus = FDKaacEnc_psyInit(hAacEnc->psyKernel, hAacEnc->psyOut, + hAacEnc->maxFrames, hAacEnc->maxChannels, + config->audioObjectType, cm); + if (ErrorStatus != AAC_ENC_OK) goto bail; + } - ErrorStatus = FDKaacEnc_psyMainInit(hAacEnc->psyKernel, - config->audioObjectType, - cm, - config->sampleRate, - config->framelength, - psyBitrate, - tnsMask, - hAacEnc->bandwidth90dB, - config->usePns, - config->useIS, - config->syntaxFlags, - initFlags); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_psyMainInit( + hAacEnc->psyKernel, config->audioObjectType, cm, config->sampleRate, + config->framelength, psyBitrate, tnsMask, hAacEnc->bandwidth90dB, + config->usePns, config->useIS, config->useMS, config->syntaxFlags, + initFlags); + if (ErrorStatus != AAC_ENC_OK) goto bail; ErrorStatus = FDKaacEnc_QCOutInit(hAacEnc->qcOut, hAacEnc->maxFrames, cm); - if (ErrorStatus != AAC_ENC_OK) - goto bail; - - - - qcInit.channelMapping = &hAacEnc->channelMapping; - qcInit.sceCpe = 0; + if (ErrorStatus != AAC_ENC_OK) goto bail; + + qcInit.channelMapping = &hAacEnc->channelMapping; + qcInit.sceCpe = 0; + + if (AACENC_BR_MODE_IS_VBR(config->bitrateMode)) { + qcInit.averageBits = (averageBitsPerFrame + 7) & ~7; + qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff; + qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff; + qcInit.maxBits = (config->maxBitsPerFrame != -1) + ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) + : qcInit.maxBits; + qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame + 7) & ~7); + qcInit.minBits = + (config->minBitsPerFrame != -1) ? config->minBitsPerFrame : 0; + qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame & ~7); + } else { + INT bitreservoir = -1; /* default bitrservoir size*/ + if (isLowDelay(config->audioObjectType)) { + INT brPerChannel = config->bitRate / config->nChannels; + brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel)); + + /* bitreservoir = + * (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; + */ + FIXP_DBL slope = fDivNorm( + (brPerChannel - BITRATE_MIN_LD), + BITRATE_MAX_LD - BITRATE_MIN_LD); /* calc slope for interpolation */ + bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD - BITRES_MIN_LD)) + + BITRES_MIN_LD; /* interpolate */ + bitreservoir = bitreservoir & ~7; /* align to bytes */ + bitresMin = BITRES_MIN_LD; + } - if ((config->bitrateMode>=1) && (config->bitrateMode<=5)) { - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - qcInit.bitRes = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.maxBits = MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff; - qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; - qcInit.maxBits = fixMax(qcInit.maxBits, (averageBitsPerFrame+7)&~7); - qcInit.minBits = (config->minBitsPerFrame!=-1) ? config->minBitsPerFrame : 0; - qcInit.minBits = fixMin(qcInit.minBits, averageBitsPerFrame&~7); - } - else - { - int maxBitres; - qcInit.averageBits = (averageBitsPerFrame+7)&~7; - maxBitres = (MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff) - qcInit.averageBits; - qcInit.bitRes = (config->bitreservoir!=-1) ? FDKmin(config->bitreservoir, maxBitres) : maxBitres; - - qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes); - qcInit.maxBits = (config->maxBitsPerFrame!=-1) ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) : qcInit.maxBits; - qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN*cm->nChannelsEff, fixMax(qcInit.maxBits, (averageBitsPerFrame+7+8)&~7)); - - qcInit.minBits = fixMax(0, ((averageBitsPerFrame-1)&~7)-qcInit.bitRes-transportEnc_GetStaticBits(hTpEnc, ((averageBitsPerFrame+7)&~7)+qcInit.bitRes)); - qcInit.minBits = (config->minBitsPerFrame!=-1) ? fixMax(qcInit.minBits, config->minBitsPerFrame) : qcInit.minBits; - qcInit.minBits = fixMin(qcInit.minBits, (averageBitsPerFrame - transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits))&~7); + int maxBitres; + qcInit.averageBits = (averageBitsPerFrame + 7) & ~7; + maxBitres = + (MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff) - qcInit.averageBits; + qcInit.bitRes = + (bitreservoir != -1) ? fMin(bitreservoir, maxBitres) : maxBitres; + + qcInit.maxBits = fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff, + ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes); + qcInit.maxBits = (config->maxBitsPerFrame != -1) + ? fixMin(qcInit.maxBits, config->maxBitsPerFrame) + : qcInit.maxBits; + qcInit.maxBits = + fixMin(MIN_BUFSIZE_PER_EFF_CHAN * cm->nChannelsEff, + fixMax(qcInit.maxBits, (averageBitsPerFrame + 7 + 8) & ~7)); + + qcInit.minBits = fixMax( + 0, ((averageBitsPerFrame - 1) & ~7) - qcInit.bitRes - + transportEnc_GetStaticBits( + hTpEnc, ((averageBitsPerFrame + 7) & ~7) + qcInit.bitRes)); + qcInit.minBits = (config->minBitsPerFrame != -1) + ? fixMax(qcInit.minBits, config->minBitsPerFrame) + : qcInit.minBits; + qcInit.minBits = fixMin( + qcInit.minBits, (averageBitsPerFrame - + transportEnc_GetStaticBits(hTpEnc, qcInit.maxBits)) & + ~7); } - qcInit.sampleRate = config->sampleRate; - qcInit.advancedBitsToPe = isLowDelay(config->audioObjectType) ? 1 : 0 ; - qcInit.nSubFrames = config->nSubFrames; + qcInit.sampleRate = config->sampleRate; + qcInit.isLowDelay = isLowDelay(config->audioObjectType) ? 1 : 0; + qcInit.nSubFrames = config->nSubFrames; qcInit.padding.paddingRest = config->sampleRate; - /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ - bw_ratio = fDivNorm((FIXP_DBL)(10*config->framelength*hAacEnc->bandwidth90dB), (FIXP_DBL)(config->sampleRate), &qbw); - qcInit.meanPe = FDKmax((INT)scaleValue(bw_ratio, qbw+1-(DFRACT_BITS-1)), 1); - - /* Calc maxBitFac */ - mbfac = fDivNorm((MIN_BUFSIZE_PER_EFF_CHAN-744)*cm->nChannelsEff, qcInit.averageBits/qcInit.nSubFrames, &qmbfac); - qmbfac = DFRACT_BITS-1-qmbfac; - qcInit.maxBitFac = (qmbfac > 24) ? (mbfac >> (qmbfac - 24)):(mbfac << (24 - qmbfac)); - - switch(config->bitrateMode){ - case AACENC_BR_MODE_CBR: - qcInit.bitrateMode = QCDATA_BR_MODE_CBR; - break; - case AACENC_BR_MODE_VBR_1: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1; - break; - case AACENC_BR_MODE_VBR_2: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2; - break; - case AACENC_BR_MODE_VBR_3: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3; - break; - case AACENC_BR_MODE_VBR_4: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4; - break; - case AACENC_BR_MODE_VBR_5: - qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5; - break; - case AACENC_BR_MODE_SFR: - qcInit.bitrateMode = QCDATA_BR_MODE_SFR; - break; - case AACENC_BR_MODE_FF: - qcInit.bitrateMode = QCDATA_BR_MODE_FF; - break; - default: - ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE; - goto bail; + if (qcInit.bitRes >= bitresMin * config->nChannels) { + qcInit.bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */ + } else if (qcInit.bitRes > 0) { + qcInit.bitResMode = AACENC_BR_MODE_REDUCED; /* reduced bitreservoir */ + } else { + qcInit.bitResMode = AACENC_BR_MODE_DISABLED; /* disabled bitreservoir */ } - qcInit.invQuant = (config->useRequant)?2:0; + /* Configure bitrate distribution strategy. */ + switch (config->channelMode) { + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + qcInit.bitDistributionMode = 0; /* over all elements bitrate estimation */ + break; + case MODE_1: + case MODE_2: + default: /* all non mpeg defined channel modes */ + qcInit.bitDistributionMode = 1; /* element-wise bit bitrate estimation */ + } /* config->channelMode */ + + /* Calc meanPe: qcInit.meanPe = 10.0f * FRAME_LEN_LONG * + * hAacEnc->bandwidth90dB/(config->sampleRate/2.0f); */ + bw_ratio = + fDivNorm((FIXP_DBL)(10 * config->framelength * hAacEnc->bandwidth90dB), + (FIXP_DBL)(config->sampleRate), &qbw); + qcInit.meanPe = + fMax((INT)scaleValue(bw_ratio, qbw + 1 - (DFRACT_BITS - 1)), 1); + + /* Calc maxBitFac, scale it to 24 bit accuracy */ + mbfac = fDivNorm(qcInit.maxBits, qcInit.averageBits / qcInit.nSubFrames, + &mbfac_e); + qcInit.maxBitFac = scaleValue(mbfac, -(DFRACT_BITS - 1 - 24 - mbfac_e)); + + switch (config->bitrateMode) { + case AACENC_BR_MODE_CBR: + qcInit.bitrateMode = QCDATA_BR_MODE_CBR; + break; + case AACENC_BR_MODE_VBR_1: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_1; + break; + case AACENC_BR_MODE_VBR_2: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_2; + break; + case AACENC_BR_MODE_VBR_3: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_3; + break; + case AACENC_BR_MODE_VBR_4: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_4; + break; + case AACENC_BR_MODE_VBR_5: + qcInit.bitrateMode = QCDATA_BR_MODE_VBR_5; + break; + case AACENC_BR_MODE_SFR: + qcInit.bitrateMode = QCDATA_BR_MODE_SFR; + break; + case AACENC_BR_MODE_FF: + qcInit.bitrateMode = QCDATA_BR_MODE_FF; + break; + default: + ErrorStatus = AAC_ENC_UNSUPPORTED_BITRATE_MODE; + goto bail; + } - /* maxIterations should be set to the maximum number of requantization iterations that are - * allowed before the crash recovery functionality is activated. This setting should be adjusted - * to the processing power available, i.e. to the processing power headroom in one frame that is - * still left after normal encoding without requantization. Please note that if activated this - * functionality is used most likely only in cases where the encoder is operating beyond - * recommended settings, i.e. the audio quality is suboptimal anyway. Activating the crash - * recovery does not further reduce audio quality significantly in these cases. */ - if ( (config->audioObjectType == AOT_ER_AAC_LD) || (config->audioObjectType == AOT_ER_AAC_ELD) ) { + qcInit.invQuant = (config->useRequant) ? 2 : 0; + + /* maxIterations should be set to the maximum number of requantization + * iterations that are allowed before the crash recovery functionality is + * activated. This setting should be adjusted to the processing power + * available, i.e. to the processing power headroom in one frame that is still + * left after normal encoding without requantization. Please note that if + * activated this functionality is used most likely only in cases where the + * encoder is operating beyond recommended settings, i.e. the audio quality is + * suboptimal anyway. Activating the crash recovery does not further reduce + * audio quality significantly in these cases. */ + if (isLowDelay(config->audioObjectType)) { qcInit.maxIterations = 2; - } - else - { + } else { qcInit.maxIterations = 5; } qcInit.bitrate = config->bitRate - config->ancDataBitRate; - qcInit.staticBits = transportEnc_GetStaticBits(hTpEnc, qcInit.averageBits/qcInit.nSubFrames); + qcInit.staticBits = transportEnc_GetStaticBits( + hTpEnc, qcInit.averageBits / qcInit.nSubFrames); - ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit); - if (ErrorStatus != AAC_ENC_OK) - goto bail; + ErrorStatus = FDKaacEnc_QCInit(hAacEnc->qcKernel, &qcInit, initFlags); + if (ErrorStatus != AAC_ENC_OK) goto bail; - hAacEnc->aot = hAacEnc->config->audioObjectType; + /* Map virtual aot's to intern aot used in bitstream writer. */ + switch (hAacEnc->config->audioObjectType) { + case AOT_MP2_AAC_LC: + hAacEnc->aot = AOT_AAC_LC; + break; + case AOT_MP2_SBR: + hAacEnc->aot = AOT_SBR; + break; + default: + hAacEnc->aot = hAacEnc->config->audioObjectType; + } /* common things */ @@ -701,7 +718,6 @@ bail: return ErrorStatus; } - /*--------------------------------------------------------------------------- functionname: FDKaacEnc_EncodeFrame @@ -709,277 +725,235 @@ bail: returns: error code ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, /* encoder handle */ - HANDLE_TRANSPORTENC hTpEnc, - INT_PCM* RESTRICT inputBuffer, - INT* nOutBytes, - AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS] - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - int el, n, c=0; - UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS]; - - CHANNEL_MAPPING *cm = &hAacEnc->channelMapping; - - - - PSY_OUT *psyOut = hAacEnc->psyOut[c]; - QC_OUT *qcOut = hAacEnc->qcOut[c]; - - FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR)); - - qcOut->elementExtBits = 0; /* sum up all extended bit of each element */ - qcOut->staticBits = 0; /* sum up side info bits of each element */ - qcOut->totalNoRedPe = 0; /* sum up PE */ - - /* advance psychoacoustics */ - for (el=0; el<cm->nElements; el++) { - ELEMENT_INFO elInfo = cm->elInfo[el]; - - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - int ch; - - /* update pointer!*/ - for(ch=0;ch<elInfo.nChannelsInEl;ch++) { - PSY_OUT_CHANNEL *psyOutChan = psyOut->psyOutElement[el]->psyOutChannel[ch]; - QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch]; - - psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum; - psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy; - psyOutChan->sfbEnergy = qcOutChan->sfbEnergy; - psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData; - psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData; - psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData; - - } - - FDKaacEnc_psyMain(elInfo.nChannelsInEl, - hAacEnc->psyKernel->psyElement[el], - hAacEnc->psyKernel->psyDynamic, - hAacEnc->psyKernel->psyConf, - psyOut->psyOutElement[el], - inputBuffer, - cm->elInfo[el].ChannelIndex, - cm->nChannels - - ); - - /* FormFactor, Pe and staticBitDemand calculation */ - ErrorStatus = FDKaacEnc_QCMainPrepare(&elInfo, - hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el], - psyOut->psyOutElement[el], - qcOut->qcElement[el], - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - - qcOut->qcElement[el]->extBitsUsed = 0; - qcOut->qcElement[el]->nExtensions = 0; - /* reset extension payload */ - FDKmemclear(&qcOut->qcElement[el]->extension, (1)*sizeof(QC_OUT_EXTENSION)); - - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == el) - && (extPayload[n].dataSize > 0) - && (extPayload[n].pData != NULL) ) - { - int idx = qcOut->qcElement[el]->nExtensions++; - - qcOut->qcElement[el]->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->qcElement[el]->extension[idx].nPayloadBits = extPayload[n].dataSize; - qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->qcElement[el]->extBitsUsed += - FDKaacEnc_writeExtensionData( NULL, - &qcOut->qcElement[el]->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - extPayloadUsed[n] = 1; - } - } - - /* sum up extension and static bits for all channel elements */ - qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed; - qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed; - - /* sum up pe */ - qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe; +AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( + HANDLE_AAC_ENC hAacEnc, /* encoder handle */ + HANDLE_TRANSPORTENC hTpEnc, INT_PCM *RESTRICT inputBuffer, + const UINT inputBufferBufSize, INT *nOutBytes, + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]) { + AAC_ENCODER_ERROR ErrorStatus; + int el, n, c = 0; + UCHAR extPayloadUsed[MAX_TOTAL_EXT_PAYLOADS]; + + CHANNEL_MAPPING *cm = &hAacEnc->channelMapping; + + PSY_OUT *psyOut = hAacEnc->psyOut[c]; + QC_OUT *qcOut = hAacEnc->qcOut[c]; + + FDKmemclear(extPayloadUsed, MAX_TOTAL_EXT_PAYLOADS * sizeof(UCHAR)); + + qcOut->elementExtBits = 0; /* sum up all extended bit of each element */ + qcOut->staticBits = 0; /* sum up side info bits of each element */ + qcOut->totalNoRedPe = 0; /* sum up PE */ + + /* advance psychoacoustics */ + for (el = 0; el < cm->nElements; el++) { + ELEMENT_INFO elInfo = cm->elInfo[el]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + int ch; + + /* update pointer!*/ + for (ch = 0; ch < elInfo.nChannelsInEl; ch++) { + PSY_OUT_CHANNEL *psyOutChan = + psyOut->psyOutElement[el]->psyOutChannel[ch]; + QC_OUT_CHANNEL *qcOutChan = qcOut->qcElement[el]->qcOutChannel[ch]; + + psyOutChan->mdctSpectrum = qcOutChan->mdctSpectrum; + psyOutChan->sfbSpreadEnergy = qcOutChan->sfbSpreadEnergy; + psyOutChan->sfbEnergy = qcOutChan->sfbEnergy; + psyOutChan->sfbEnergyLdData = qcOutChan->sfbEnergyLdData; + psyOutChan->sfbMinSnrLdData = qcOutChan->sfbMinSnrLdData; + psyOutChan->sfbThresholdLdData = qcOutChan->sfbThresholdLdData; + } + + ErrorStatus = FDKaacEnc_psyMain( + elInfo.nChannelsInEl, hAacEnc->psyKernel->psyElement[el], + hAacEnc->psyKernel->psyDynamic, hAacEnc->psyKernel->psyConf, + psyOut->psyOutElement[el], inputBuffer, inputBufferBufSize, + cm->elInfo[el].ChannelIndex, cm->nChannels); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* FormFactor, Pe and staticBitDemand calculation */ + ErrorStatus = FDKaacEnc_QCMainPrepare( + &elInfo, hAacEnc->qcKernel->hAdjThr->adjThrStateElem[el], + psyOut->psyOutElement[el], qcOut->qcElement[el], hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /*-------------------------------------------- */ + + qcOut->qcElement[el]->extBitsUsed = 0; + qcOut->qcElement[el]->nExtensions = 0; + /* reset extension payload */ + FDKmemclear(&qcOut->qcElement[el]->extension, + (1) * sizeof(QC_OUT_EXTENSION)); + + for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) { + if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == el) && + (extPayload[n].dataSize > 0) && (extPayload[n].pData != NULL)) { + int idx = qcOut->qcElement[el]->nExtensions++; + + qcOut->qcElement[el]->extension[idx].type = + extPayload[n].dataType; /* Perform a sanity check on the type? */ + qcOut->qcElement[el]->extension[idx].nPayloadBits = + extPayload[n].dataSize; + qcOut->qcElement[el]->extension[idx].pPayload = extPayload[n].pData; + /* Now ask the bitstream encoder how many bits we need to encode the + * data with the current bitstream syntax: */ + qcOut->qcElement[el]->extBitsUsed += FDKaacEnc_writeExtensionData( + NULL, &qcOut->qcElement[el]->extension[idx], 0, 0, + hAacEnc->config->syntaxFlags, hAacEnc->aot, + hAacEnc->config->epConfig); + extPayloadUsed[n] = 1; } + } + + /* sum up extension and static bits for all channel elements */ + qcOut->elementExtBits += qcOut->qcElement[el]->extBitsUsed; + qcOut->staticBits += qcOut->qcElement[el]->staticBitsUsed; + + /* sum up pe */ + qcOut->totalNoRedPe += qcOut->qcElement[el]->peData.pe; } + } - qcOut->nExtensions = 0; - qcOut->globalExtBits = 0; - - /* reset extension payload */ - FDKmemclear(&qcOut->extension, (2+2)*sizeof(QC_OUT_EXTENSION)); - - /* Add extension payload not assigned to an channel element - (Ancillary data is the only supported type up to now) */ - for ( n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++ ) { - if ( !extPayloadUsed[n] - && (extPayload[n].associatedChElement == -1) - && (extPayload[n].pData != NULL) ) - { - UINT payloadBits = 0; - - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - if (hAacEnc->ancillaryBitsPerFrame) { - /* granted frame dse bitrate */ - payloadBits = hAacEnc->ancillaryBitsPerFrame; - } - else { - /* write anc data if bitrate constraint fulfilled */ - if ((extPayload[n].dataSize>>3) <= hAacEnc->config->maxAncBytesPerAU) { - payloadBits = extPayload[n].dataSize; - } - } - payloadBits = fixMin( extPayload[n].dataSize, payloadBits ); - } else { - payloadBits = extPayload[n].dataSize; - } - - if (payloadBits > 0) - { - int idx = qcOut->nExtensions++; - - qcOut->extension[idx].type = extPayload[n].dataType; /* Perform a sanity check on the type? */ - qcOut->extension[idx].nPayloadBits = payloadBits; - qcOut->extension[idx].pPayload = extPayload[n].pData; - /* Now ask the bitstream encoder how many bits we need to encode the data with the current bitstream syntax: */ - qcOut->globalExtBits += FDKaacEnc_writeExtensionData( NULL, - &qcOut->extension[idx], - 0, 0, - hAacEnc->config->syntaxFlags, - hAacEnc->aot, - hAacEnc->config->epConfig ); - if (extPayload[n].dataType == EXT_DATA_ELEMENT) { - /* substract the processed bits */ - extPayload[n].dataSize -= payloadBits; - } - extPayloadUsed[n] = 1; - } + qcOut->nExtensions = 0; + qcOut->globalExtBits = 0; + + /* reset extension payload */ + FDKmemclear(&qcOut->extension, (2 + 2) * sizeof(QC_OUT_EXTENSION)); + + /* Add extension payload not assigned to an channel element + (Ancillary data is the only supported type up to now) */ + for (n = 0; n < MAX_TOTAL_EXT_PAYLOADS; n++) { + if (!extPayloadUsed[n] && (extPayload[n].associatedChElement == -1) && + (extPayload[n].pData != NULL)) { + UINT payloadBits = 0; + + if (extPayload[n].dataType == EXT_DATA_ELEMENT) { + if (hAacEnc->ancillaryBitsPerFrame) { + /* granted frame dse bitrate */ + payloadBits = hAacEnc->ancillaryBitsPerFrame; + } else { + /* write anc data if bitrate constraint fulfilled */ + if ((extPayload[n].dataSize >> 3) <= + hAacEnc->config->maxAncBytesPerAU) { + payloadBits = extPayload[n].dataSize; + } } - } + payloadBits = fixMin(extPayload[n].dataSize, payloadBits); + } else { + payloadBits = extPayload[n].dataSize; + } - if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE|AC_ER))) { - qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */ + if (payloadBits > 0) { + int idx = qcOut->nExtensions++; + + qcOut->extension[idx].type = + extPayload[n].dataType; /* Perform a sanity check on the type? */ + qcOut->extension[idx].nPayloadBits = payloadBits; + qcOut->extension[idx].pPayload = extPayload[n].pData; + /* Now ask the bitstream encoder how many bits we need to encode the + * data with the current bitstream syntax: */ + qcOut->globalExtBits += FDKaacEnc_writeExtensionData( + NULL, &qcOut->extension[idx], 0, 0, hAacEnc->config->syntaxFlags, + hAacEnc->aot, hAacEnc->config->epConfig); + if (extPayload[n].dataType == EXT_DATA_ELEMENT) { + /* substract the processed bits */ + extPayload[n].dataSize -= payloadBits; + } + extPayloadUsed[n] = 1; + } } + } + + if (!(hAacEnc->config->syntaxFlags & (AC_SCALABLE | AC_ER))) { + qcOut->globalExtBits += EL_ID_BITS; /* add bits for ID_END */ + } + + /* build bitstream all nSubFrames */ + { + INT totalBits = 0; /* Total AU bits */ + ; + INT avgTotalBits = 0; - /* build bitstream all nSubFrames */ + /*-------------------------------------------- */ + /* Get average total bits */ + /*-------------------------------------------- */ { - INT totalBits = 0; /* Total AU bits */; - INT avgTotalBits = 0; - - /*-------------------------------------------- */ - /* Get average total bits */ - /*-------------------------------------------- */ - { - /* frame wise bitrate adaption */ - FDKaacEnc_AdjustBitrate(hAacEnc->qcKernel, - cm, - &avgTotalBits, - hAacEnc->config->bitRate, - hAacEnc->config->sampleRate, - hAacEnc->config->framelength); - - /* adjust super frame bitrate */ - avgTotalBits *= hAacEnc->config->nSubFrames; - } + /* frame wise bitrate adaption */ + FDKaacEnc_AdjustBitrate( + hAacEnc->qcKernel, cm, &avgTotalBits, hAacEnc->config->bitRate, + hAacEnc->config->sampleRate, hAacEnc->config->framelength); + + /* adjust super frame bitrate */ + avgTotalBits *= hAacEnc->config->nSubFrames; + } - /* Make first estimate of transport header overhead. - Take maximum possible frame size into account to prevent bitreservoir underrun. */ - hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - /*-------------------------------------------- */ - - ErrorStatus = FDKaacEnc_QCMain(hAacEnc->qcKernel, - hAacEnc->psyOut, - hAacEnc->qcOut, - avgTotalBits, - cm - ,hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_updateFillBits(cm, - hAacEnc->qcKernel, - hAacEnc->qcKernel->elementBits, - hAacEnc->qcOut); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /*-------------------------------------------- */ - ErrorStatus = FDKaacEnc_FinalizeBitConsumption(cm, - hAacEnc->qcKernel, - qcOut, - qcOut->qcElement, - hTpEnc, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - /*-------------------------------------------- */ - totalBits += qcOut->totalBits; - - - /*-------------------------------------------- */ - FDKaacEnc_updateBitres(cm, - hAacEnc->qcKernel, - hAacEnc->qcOut); - - /*-------------------------------------------- */ - - /* for ( all sub frames ) ... */ - /* write bitstream header */ - transportEnc_WriteAccessUnit( - hTpEnc, - totalBits, - FDKaacEnc_EncBitresToTpBitres(hAacEnc), - cm->nChannelsEff); - - /* write bitstream */ - ErrorStatus = FDKaacEnc_WriteBitstream( - hTpEnc, - cm, - qcOut, - psyOut, - hAacEnc->qcKernel, - hAacEnc->aot, - hAacEnc->config->syntaxFlags, - hAacEnc->config->epConfig); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /* transportEnc_EndAccessUnit() is being called inside FDKaacEnc_WriteBitstream() */ - transportEnc_GetFrame(hTpEnc, nOutBytes); - - } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */ + /* Make first estimate of transport header overhead. + Take maximum possible frame size into account to prevent bitreservoir + underrun. */ + hAacEnc->qcKernel->globHdrBits = transportEnc_GetStaticBits( + hTpEnc, avgTotalBits + hAacEnc->qcKernel->bitResTot); + /*-------------------------------------------- */ + /*-------------------------------------------- */ + /*-------------------------------------------- */ + + ErrorStatus = FDKaacEnc_QCMain( + hAacEnc->qcKernel, hAacEnc->psyOut, hAacEnc->qcOut, avgTotalBits, cm, + hAacEnc->aot, hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + /*-------------------------------------------- */ + + /*-------------------------------------------- */ + ErrorStatus = FDKaacEnc_updateFillBits( + cm, hAacEnc->qcKernel, hAacEnc->qcKernel->elementBits, hAacEnc->qcOut); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; /*-------------------------------------------- */ - return AAC_ENC_OK; + ErrorStatus = FDKaacEnc_FinalizeBitConsumption( + cm, hAacEnc->qcKernel, qcOut, qcOut->qcElement, hTpEnc, hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + /*-------------------------------------------- */ + totalBits += qcOut->totalBits; + + /*-------------------------------------------- */ + FDKaacEnc_updateBitres(cm, hAacEnc->qcKernel, hAacEnc->qcOut); + + /*-------------------------------------------- */ + + /* for ( all sub frames ) ... */ + /* write bitstream header */ + if (TRANSPORTENC_OK != + transportEnc_WriteAccessUnit(hTpEnc, totalBits, + FDKaacEnc_EncBitresToTpBitres(hAacEnc), + cm->nChannelsEff)) { + return AAC_ENC_UNKNOWN; + } + + /* write bitstream */ + ErrorStatus = FDKaacEnc_WriteBitstream( + hTpEnc, cm, qcOut, psyOut, hAacEnc->qcKernel, hAacEnc->aot, + hAacEnc->config->syntaxFlags, hAacEnc->config->epConfig); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* transportEnc_EndAccessUnit() is being called inside + * FDKaacEnc_WriteBitstream() */ + if (TRANSPORTENC_OK != transportEnc_GetFrame(hTpEnc, nOutBytes)) { + return AAC_ENC_UNKNOWN; + } + + } /* -end- if (curFrame==hAacEnc->qcKernel->nSubFrames) */ + + /*-------------------------------------------- */ + return AAC_ENC_OK; } /*--------------------------------------------------------------------------- @@ -990,29 +964,27 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, ---------------------------------------------------------------------------*/ -void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc) /* encoder handle */ +void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc) /* encoder handle */ { - if (*phAacEnc == NULL) { - return; - } - AAC_ENC *hAacEnc = (AAC_ENC*)*phAacEnc; + if (*phAacEnc == NULL) { + return; + } + AAC_ENC *hAacEnc = (AAC_ENC *)*phAacEnc; - if (hAacEnc->dynamic_RAM != NULL) - FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM); + if (hAacEnc->dynamic_RAM != NULL) FreeAACdynamic_RAM(&hAacEnc->dynamic_RAM); - FDKaacEnc_PsyClose(&hAacEnc->psyKernel,hAacEnc->psyOut); + FDKaacEnc_PsyClose(&hAacEnc->psyKernel, hAacEnc->psyOut); - FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut); + FDKaacEnc_QCClose(&hAacEnc->qcKernel, hAacEnc->qcOut); - FreeRam_aacEnc_AacEncoder(phAacEnc); + FreeRam_aacEnc_AacEncoder(phAacEnc); } - /* The following functions are in this source file only for convenience and */ /* need not be visible outside of a possible encoder library. */ /* basic defines for ancillary data */ -#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */ +#define MAX_ANCRATE 19200 /* ancillary rate >= 19200 isn't valid */ /*--------------------------------------------------------------------------- @@ -1021,42 +993,33 @@ void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc) /* encoder handle */ return: if success or NULL if error ---------------------------------------------------------------------------*/ -static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary(INT bitRate, - INT framelength, - INT ancillaryRate, - INT *ancillaryBitsPerFrame, - INT sampleRate) -{ - INT diffToByteAlign; - +static AAC_ENCODER_ERROR FDKaacEnc_InitCheckAncillary( + INT bitRate, INT framelength, INT ancillaryRate, INT *ancillaryBitsPerFrame, + INT sampleRate) { /* don't use negative ancillary rates */ - if ( ancillaryRate < -1 ) - return AAC_ENC_UNSUPPORTED_ANC_BITRATE; + if (ancillaryRate < -1) return AAC_ENC_UNSUPPORTED_ANC_BITRATE; /* check if ancillary rate is ok */ - if ( (ancillaryRate != (-1)) && (ancillaryRate != 0) ) { + if ((ancillaryRate != (-1)) && (ancillaryRate != 0)) { /* ancRate <= 15% of bitrate && ancRate < 19200 */ - if ( ( ancillaryRate >= MAX_ANCRATE ) || - ( (ancillaryRate * 20) > (bitRate * 3) ) ) { + if ((ancillaryRate >= MAX_ANCRATE) || + ((ancillaryRate * 20) > (bitRate * 3))) { return AAC_ENC_UNSUPPORTED_ANC_BITRATE; } - } - else if (ancillaryRate == -1) { + } else if (ancillaryRate == -1) { /* if no special ancRate is requested but a ancillary file is stated, then generate a ancillary rate matching to the bitrate */ if (bitRate >= (MAX_ANCRATE * 10)) { /* ancillary rate is 19199 */ ancillaryRate = (MAX_ANCRATE - 1); - } - else { /* 10% of bitrate */ + } else { /* 10% of bitrate */ ancillaryRate = bitRate / 10; } } /* make ancillaryBitsPerFrame byte align */ - *ancillaryBitsPerFrame = (ancillaryRate * framelength ) / sampleRate; - diffToByteAlign = *ancillaryBitsPerFrame % 8; - *ancillaryBitsPerFrame = *ancillaryBitsPerFrame - diffToByteAlign; + *ancillaryBitsPerFrame = + FDKaacEnc_CalcBitsPerFrame(ancillaryRate, framelength, sampleRate) & ~0x7; return AAC_ENC_OK; } diff --git a/libAACenc/src/aacenc.h b/libAACenc/src/aacenc.h index 79524b5..0e0d8c1 100644 --- a/libAACenc/src/aacenc.h +++ b/libAACenc/src/aacenc.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): M. Schug / A. Groeschel - Initial author: M. Schug / A. Groeschel - contents/description: fast aac coder interface library functions + Description: fast aac coder interface library functions -******************************************************************************/ +*******************************************************************************/ -#ifndef _aacenc_h_ -#define _aacenc_h_ +#ifndef AACENC_H +#define AACENC_H #include "common_fix.h" #include "FDK_audio.h" @@ -98,10 +110,7 @@ amm-info@iis.fraunhofer.de #include "sbr_encoder.h" -#define BITRES_MAX_LD 4000 -#define BITRES_MIN_LD 500 -#define BITRATE_MAX_LD 70000 /* Max assumed bitrate for bitres calculation */ -#define BITRATE_MIN_LD 12000 /* Min assumed bitrate for bitres calculation */ +#define MIN_BUFSIZE_PER_EFF_CHAN 6144 #ifdef __cplusplus extern "C" { @@ -111,192 +120,218 @@ extern "C" { * AAC-LC error codes. */ typedef enum { - AAC_ENC_OK = 0x0000, /*!< All fine. */ + AAC_ENC_OK = 0x0000, /*!< All fine. */ - AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from another module. */ + AAC_ENC_UNKNOWN = 0x0002, /*!< Error condition is of unknown reason, or from + another module. */ /* initialization errors */ - aac_enc_init_error_start = 0x2000, - AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call was invalid (probably NULL). */ - AAC_ENC_INVALID_FRAME_LENGTH = 0x2080, /*!< Invalid frame length. */ - AAC_ENC_INVALID_N_CHANNELS = 0x20e0, /*!< Invalid amount of audio input channels. */ - AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */ - - AAC_ENC_UNSUPPORTED_AOT = 0x3000, /*!< The Audio Object Type (AOT) is not supported. */ - AAC_ENC_UNSUPPORTED_BITRATE = 0x3020, /*!< The chosen bitrate is not supported. */ - AAC_ENC_UNSUPPORTED_BITRATE_MODE = 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */ - AAC_ENC_UNSUPPORTED_ANC_BITRATE = 0x3040, /*!< Unsupported ancillay bitrate. */ - AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060, - AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE = 0x3080, /*!< The bitstream format is not supported. */ - AAC_ENC_UNSUPPORTED_ER_FORMAT = 0x30a0, /*!< The error resilience tool format is not supported. */ - AAC_ENC_UNSUPPORTED_EPCONFIG = 0x30c0, /*!< The error protection format is not supported. */ - AAC_ENC_UNSUPPORTED_CHANNELCONFIG = 0x30e0, /*!< The channel configuration (either number or arrangement) is not supported. */ - AAC_ENC_UNSUPPORTED_SAMPLINGRATE = 0x3100, /*!< Sample rate of audio input is not supported. */ - AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */ - AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */ + aac_enc_init_error_start = 0x2000, + AAC_ENC_INVALID_HANDLE = 0x2020, /*!< The handle passed to the function call + was invalid (probably NULL). */ + AAC_ENC_INVALID_FRAME_LENGTH = + 0x2080, /*!< Invalid frame length (must be 1024 or 960). */ + AAC_ENC_INVALID_N_CHANNELS = + 0x20e0, /*!< Invalid amount of audio input channels. */ + AAC_ENC_INVALID_SFB_TABLE = 0x2140, /*!< Internal encoder error. */ + + AAC_ENC_UNSUPPORTED_AOT = + 0x3000, /*!< The Audio Object Type (AOT) is not supported. */ + AAC_ENC_UNSUPPORTED_FILTERBANK = + 0x3010, /*!< Filterbank type is not supported. */ + AAC_ENC_UNSUPPORTED_BITRATE = + 0x3020, /*!< The chosen bitrate is not supported. */ + AAC_ENC_UNSUPPORTED_BITRATE_MODE = + 0x3028, /*!< Unsupported bit rate mode (CBR or VBR). */ + AAC_ENC_UNSUPPORTED_ANC_BITRATE = + 0x3040, /*!< Unsupported ancillay bitrate. */ + AAC_ENC_UNSUPPORTED_ANC_MODE = 0x3060, + AAC_ENC_UNSUPPORTED_TRANSPORT_TYPE = + 0x3080, /*!< The bitstream format is not supported. */ + AAC_ENC_UNSUPPORTED_ER_FORMAT = + 0x30a0, /*!< The error resilience tool format is not supported. */ + AAC_ENC_UNSUPPORTED_EPCONFIG = + 0x30c0, /*!< The error protection format is not supported. */ + AAC_ENC_UNSUPPORTED_CHANNELCONFIG = + 0x30e0, /*!< The channel configuration (either number or arrangement) is + not supported. */ + AAC_ENC_UNSUPPORTED_SAMPLINGRATE = + 0x3100, /*!< Sample rate of audio input is not supported. */ + AAC_ENC_NO_MEMORY = 0x3120, /*!< Could not allocate memory. */ + AAC_ENC_PE_INIT_TABLE_NOT_FOUND = 0x3140, /*!< Internal encoder error. */ aac_enc_init_error_end, /* encode errors */ - aac_enc_error_start = 0x4000, - AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */ - AAC_ENC_WRITTEN_BITS_ERROR = 0x4040, /*!< Unexpected number of written bits, differs to - calculated number of bits. */ - AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */ - AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */ - AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */ - AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */ - AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100, - AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */ - - AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */ - AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */ - AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */ + aac_enc_error_start = 0x4000, + AAC_ENC_QUANT_ERROR = 0x4020, /*!< Too many bits used in quantization. */ + AAC_ENC_WRITTEN_BITS_ERROR = + 0x4040, /*!< Unexpected number of written bits, differs to + calculated number of bits. */ + AAC_ENC_PNS_TABLE_ERROR = 0x4060, /*!< PNS level out of range. */ + AAC_ENC_GLOBAL_GAIN_TOO_HIGH = 0x4080, /*!< Internal quantizer error. */ + AAC_ENC_BITRES_TOO_LOW = 0x40a0, /*!< Too few bits in bit reservoir. */ + AAC_ENC_BITRES_TOO_HIGH = 0x40a1, /*!< Too many bits in bit reservoir. */ + AAC_ENC_INVALID_CHANNEL_BITRATE = 0x4100, + AAC_ENC_INVALID_ELEMENTINFO_TYPE = 0x4120, /*!< Internal encoder error. */ + + AAC_ENC_WRITE_SCAL_ERROR = 0x41e0, /*!< Error writing scalefacData. */ + AAC_ENC_WRITE_SEC_ERROR = 0x4200, /*!< Error writing sectionData. */ + AAC_ENC_WRITE_SPEC_ERROR = 0x4220, /*!< Error writing spectralData. */ aac_enc_error_end } AAC_ENCODER_ERROR; /*-------------------------- defines --------------------------------------*/ -#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */ - -#define MAX_TOTAL_EXT_PAYLOADS (((8) * (1)) + (2+2)) +#define ANC_DATA_BUFFERSIZE 1024 /* ancBuffer size */ +#define MAX_TOTAL_EXT_PAYLOADS ((((8)) * (1)) + (2 + 2)) typedef enum { - AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */ - AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */ - AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, about 32 kbps/channel. */ - AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, about 40 kbps/channel. */ - AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, about 48-56 kbps/channel. */ - AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, about 64 kbps/channel. */ - AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, about 80-96 kbps/channel. */ - AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */ - AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */ + AACENC_BR_MODE_INVALID = -1, /*!< Invalid bitrate mode. */ + AACENC_BR_MODE_CBR = 0, /*!< Constant bitrate mode. */ + AACENC_BR_MODE_VBR_1 = 1, /*!< Variable bitrate mode, very low bitrate. */ + AACENC_BR_MODE_VBR_2 = 2, /*!< Variable bitrate mode, low bitrate. */ + AACENC_BR_MODE_VBR_3 = 3, /*!< Variable bitrate mode, medium bitrate. */ + AACENC_BR_MODE_VBR_4 = 4, /*!< Variable bitrate mode, high bitrate. */ + AACENC_BR_MODE_VBR_5 = 5, /*!< Variable bitrate mode, very high bitrate. */ + AACENC_BR_MODE_FF = 6, /*!< Fixed frame mode. */ + AACENC_BR_MODE_SFR = 7 /*!< Superframe mode. */ } AACENC_BITRATE_MODE; +#define AACENC_BR_MODE_IS_VBR(brMode) ((brMode >= 1) && (brMode <= 5)) + typedef enum { - CH_ORDER_MPEG = 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */ - CH_ORDER_WAV /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, SL, SR) */ + CH_ORDER_MPEG = + 0, /*!< MPEG channel ordering (e. g. 5.1: C, L, R, SL, SR, LFE) */ + CH_ORDER_WAV /*!< WAV fileformat channel ordering (e. g. 5.1: L, R, C, LFE, + SL, SR) */ } CHANNEL_ORDER; /*-------------------- structure definitions ------------------------------*/ struct AACENC_CONFIG { - INT sampleRate; /* encoder sample rate */ - INT bitRate; /* encoder bit rate in bits/sec */ - INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be consiedered while configuration */ + INT sampleRate; /* encoder sample rate */ + INT bitRate; /* encoder bit rate in bits/sec */ + INT ancDataBitRate; /* additional bits consumed by anc data or sbr have to be + consiedered while configuration */ + + INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !) + */ + AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */ - INT nSubFrames; /* number of frames in super frame (not ADTS/LATM subframes !) */ - AUDIO_OBJECT_TYPE audioObjectType; /* Audio Object Type */ + INT averageBits; /* encoder bit rate in bits/superframe */ + AACENC_BITRATE_MODE bitrateMode; /* encoder bitrate mode (CBR/VBR) */ + INT nChannels; /* number of channels to process */ + CHANNEL_ORDER channelOrder; /* input Channel ordering scheme. */ + INT bandWidth; /* targeted audio bandwidth in Hz */ + CHANNEL_MODE channelMode; /* encoder channel mode configuration */ + INT framelength; /* used frame size */ - INT averageBits; /* encoder bit rate in bits/superframe */ - INT bitrateMode; /* encoder bitrate mode (CBR/VBR) */ - INT nChannels; /* number of channels to process */ - CHANNEL_ORDER channelOrder; /* Input Channel ordering scheme. */ - INT bandWidth; /* targeted audio bandwidth in Hz */ - CHANNEL_MODE channelMode; /* encoder channel mode configuration */ - INT framelength; /* used frame size */ + UINT syntaxFlags; /* bitstreams syntax configuration */ + SCHAR epConfig; /* error protection configuration */ - UINT syntaxFlags; /* bitstreams syntax configuration */ - SCHAR epConfig; /* error protection configuration */ + INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate + */ + UINT maxAncBytesPerAU; + INT minBitsPerFrame; /* minimum number of bits in AU */ + INT maxBitsPerFrame; /* maximum number of bits in AU */ - INT anc_Rate; /* ancillary rate, 0 (disabled), -1 (default) else desired rate */ - UINT maxAncBytesPerAU; - INT minBitsPerFrame; /* minimum number of bits in AU */ - INT maxBitsPerFrame; /* maximum number of bits in AU */ - INT bitreservoir; /* size of bitreservoir */ + INT audioMuxVersion; /* audio mux version in loas/latm transport format */ - INT audioMuxVersion; /* audio mux version in loas/latm transport format */ + UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ - UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ + UCHAR useTns; /* flag: use temporal noise shaping */ + UCHAR usePns; /* flag: use perceptual noise substitution */ + UCHAR useIS; /* flag: use intensity coding */ + UCHAR useMS; /* flag: use ms stereo tool */ - UCHAR useTns; /* flag: use temporal noise shaping */ - UCHAR usePns; /* flag: use perceptual noise substitution */ - UCHAR useIS; /* flag: use intensity coding */ + UCHAR useRequant; /* flag: use afterburner */ - UCHAR useRequant; /* flag: use afterburner */ + UINT downscaleFactor; }; typedef struct { - UCHAR *pData; /* pointer to extension payload data */ - UINT dataSize; /* extension payload data size in bits */ - EXT_PAYLOAD_TYPE dataType; /* extension payload data type */ - INT associatedChElement; /* number of the channel element the data is assigned to */ + UCHAR *pData; /* pointer to extension payload data */ + UINT dataSize; /* extension payload data size in bits */ + EXT_PAYLOAD_TYPE dataType; /* extension payload data type */ + INT associatedChElement; /* number of the channel element the data is assigned + to */ } AACENC_EXT_PAYLOAD; typedef struct AAC_ENC *HANDLE_AAC_ENC; /** - * \brief Calculate framesize in bits for given bit rate, frame length and sampling rate. + * \brief Calculate framesize in bits for given bit rate, frame length and + * sampling rate. * * \param bitRate Ttarget bitrate in bits per second. * \param frameLength Number of audio samples in one frame. * \param samplingRate Sampling rate in Hz. * * \return Framesize in bits per frame. -*/ -INT FDKaacEnc_CalcBitsPerFrame( - const INT bitRate, - const INT frameLength, - const INT samplingRate - ); + */ +INT FDKaacEnc_CalcBitsPerFrame(const INT bitRate, const INT frameLength, + const INT samplingRate); /** - * \brief Calculate bitrate in bits per second for given framesize, frame length and sampling rate. + * \brief Calculate bitrate in bits per second for given framesize, frame length + * and sampling rate. * - * \param bitsPerFrame Framesize in bits per frame. + * \param bitsPerFrame Framesize in bits per frame * \param frameLength Number of audio samples in one frame. * \param samplingRate Sampling rate in Hz. * * \return Bitrate in bits per second. -*/ -INT FDKaacEnc_CalcBitrate( - const INT bitsPerFrame, - const INT frameLength, - const INT samplingRate - ); + */ +INT FDKaacEnc_CalcBitrate(const INT bitsPerFrame, const INT frameLength, + const INT samplingRate); /** * \brief Limit given bit rate to a valid value * \param hTpEnc transport encoder handle + * \param aot audio object type * \param coreSamplingRate the sample rate to be used for the AAC encoder * \param frameLength the frameLength to be used for the AAC encoder * \param nChannels number of total channels * \param nChannelsEff number of effective channels - * \param bitRate the initial bit rate value for which the closest valid bit rate value is searched for - * \param averageBits average bits per frame for fixed framing. Set to -1 if not available. + * \param bitRate the initial bit rate value for which the closest valid bit + * rate value is searched for + * \param averageBits average bits per frame for fixed framing. Set to -1 if not + * available. * \param optional pointer where the current bits per frame are stored into. * \param bitrateMode the current bit rate mode - * \param nSubFrames number of sub frames for super framing (not transport frames). + * \param nSubFrames number of sub frames for super framing (not transport + * frames). * \return a valid bit rate value as close as possible or identical to bitRate */ -INT FDKaacEnc_LimitBitrate( - HANDLE_TRANSPORTENC hTpEnc, - INT coreSamplingRate, - INT frameLength, - INT nChannels, - INT nChannelsEff, - INT bitRate, - INT averageBits, - INT *pAverageBitsPerFrame, - INT bitrateMode, - INT nSubFrames - ); - - /*----------------------------------------------------------------------------- - - functionname: FDKaacEnc_GetVBRBitrate - description: Get VBR bitrate from vbr quality - input params: int vbrQuality (VBR0, VBR1, VBR2) - channelMode - returns: vbr bitrate +INT FDKaacEnc_LimitBitrate(HANDLE_TRANSPORTENC hTpEnc, AUDIO_OBJECT_TYPE aot, + INT coreSamplingRate, INT frameLength, INT nChannels, + INT nChannelsEff, INT bitRate, INT averageBits, + INT *pAverageBitsPerFrame, + AACENC_BITRATE_MODE bitrateMode, INT nSubFrames); - ------------------------------------------------------------------------------*/ - INT FDKaacEnc_GetVBRBitrate(INT bitrateMode, CHANNEL_MODE channelMode); +/** + * \brief Get current state of the bit reservoir + * \param hAacEncoder encoder handle + * \return bit reservoir state in bits + */ +INT FDKaacEnc_GetBitReservoirState(const HANDLE_AAC_ENC hAacEncoder); + +/*----------------------------------------------------------------------------- + + functionname: FDKaacEnc_GetVBRBitrate + description: Get VBR bitrate from vbr quality + input params: int vbrQuality (VBR0, VBR1, VBR2) + channelMode + returns: vbr bitrate +------------------------------------------------------------------------------*/ +INT FDKaacEnc_GetVBRBitrate(AACENC_BITRATE_MODE bitrateMode, + CHANNEL_MODE channelMode); /*----------------------------------------------------------------------------- @@ -305,26 +340,27 @@ INT FDKaacEnc_LimitBitrate( returns: --- ------------------------------------------------------------------------------*/ -void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config); +void FDKaacEnc_AacInitDefaultConfig(AACENC_CONFIG *config); /*--------------------------------------------------------------------------- - functionname:FDKaacEnc_Open + functionname:FDKaacEnc_Open description: allocate and initialize a new encoder instance returns: 0 if success ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_Open(HANDLE_AAC_ENC *phAacEnc, /* pointer to an encoder handle, initialized on return */ - const INT nElements, /* number of maximal elements in instance to support */ - const INT nChannels, /* number of maximal channels in instance to support */ - const INT nSubFrames); /* support superframing in instance */ - - -AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEncoder, /* pointer to an encoder handle, initialized on return */ - AACENC_CONFIG *config, /* pre-initialized config struct */ - HANDLE_TRANSPORTENC hTpEnc, - ULONG initFlags); - +AAC_ENCODER_ERROR FDKaacEnc_Open( + HANDLE_AAC_ENC + *phAacEnc, /* pointer to an encoder handle, initialized on return */ + const INT nElements, /* number of maximal elements in instance to support */ + const INT nChannels, /* number of maximal channels in instance to support */ + const INT nSubFrames); /* support superframing in instance */ + +AAC_ENCODER_ERROR FDKaacEnc_Initialize( + HANDLE_AAC_ENC + hAacEncoder, /* pointer to an encoder handle, initialized on return */ + AACENC_CONFIG *config, /* pre-initialized config struct */ + HANDLE_TRANSPORTENC hTpEnc, ULONG initFlags); /*--------------------------------------------------------------------------- @@ -334,12 +370,11 @@ AAC_ENCODER_ERROR FDKaacEnc_Initialize(HANDLE_AAC_ENC hAacEncoder, /* poin ---------------------------------------------------------------------------*/ -AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, /* encoder handle */ - HANDLE_TRANSPORTENC hTpEnc, - INT_PCM* inputBuffer, - INT* numOutBytes, - AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS] - ); +AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( + HANDLE_AAC_ENC hAacEnc, /* encoder handle */ + HANDLE_TRANSPORTENC hTpEnc, INT_PCM *inputBuffer, + const UINT inputBufferBufSize, INT *numOutBytes, + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]); /*--------------------------------------------------------------------------- @@ -349,11 +384,10 @@ AAC_ENCODER_ERROR FDKaacEnc_EncodeFrame( HANDLE_AAC_ENC hAacEnc, / ---------------------------------------------------------------------------*/ -void FDKaacEnc_Close( HANDLE_AAC_ENC* phAacEnc); /* encoder handle */ +void FDKaacEnc_Close(HANDLE_AAC_ENC *phAacEnc); /* encoder handle */ #ifdef __cplusplus } #endif -#endif /* _aacenc_h_ */ - +#endif /* AACENC_H */ diff --git a/libAACenc/src/aacenc_lib.cpp b/libAACenc/src/aacenc_lib.cpp index 64445b9..11db3da 100644 --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/**************************** MPEG-4 HE-AAC Encoder ************************* +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: FDK HE-AAC Encoder interface library functions + Author(s): M. Lohwasser -****************************************************************************/ + Description: FDK HE-AAC Encoder interface library functions + +*******************************************************************************/ #include "aacenc_lib.h" #include "FDK_audio.h" @@ -96,9 +108,9 @@ amm-info@iis.fraunhofer.de #include "FDK_core.h" /* FDK_tools versioning info */ /* Encoder library info */ -#define AACENCODER_LIB_VL0 3 -#define AACENCODER_LIB_VL1 4 -#define AACENCODER_LIB_VL2 22 +#define AACENCODER_LIB_VL0 4 +#define AACENCODER_LIB_VL1 0 +#define AACENCODER_LIB_VL2 0 #define AACENCODER_LIB_TITLE "AAC Encoder" #ifdef __ANDROID__ #define AACENCODER_LIB_BUILD_DATE "" @@ -108,9 +120,10 @@ amm-info@iis.fraunhofer.de #define AACENCODER_LIB_BUILD_TIME __TIME__ #endif +#include "pcm_utils.h" #include "sbr_encoder.h" -#include "../src/sbr_ram.h" +#include "../src/sbrenc_ram.h" #include "channel_map.h" #include "psy_const.h" @@ -119,260 +132,297 @@ amm-info@iis.fraunhofer.de #include "tpenc_lib.h" #include "metadata_main.h" - -#define SBL(fl) (fl/8) /*!< Short block length (hardcoded to 8 short blocks per long block) */ -#define BSLA(fl) (4*SBL(fl)+SBL(fl)/2) /*!< AAC block switching look-ahead */ -#define DELAY_AAC(fl) (fl+BSLA(fl)) /*!< MDCT + blockswitching */ -#define DELAY_AACELD(fl) ((fl)/2) /*!< ELD FB delay (no framing delay included) */ - -#define INPUTBUFFER_SIZE (1537+100+2048) - -#define DEFAULT_HEADER_PERIOD_REPETITION_RATE 10 /*!< Default header repetition rate used in transport library and for SBR header. */ +#include "mps_main.h" +#include "sacenc_lib.h" + +#define SBL(fl) \ + (fl / \ + 8) /*!< Short block length (hardcoded to 8 short blocks per long block) */ +#define BSLA(fl) \ + (4 * SBL(fl) + SBL(fl) / 2) /*!< AAC block switching look-ahead */ +#define DELAY_AAC(fl) (fl + BSLA(fl)) /*!< MDCT + blockswitching */ +#define DELAY_AACLD(fl) (fl) /*!< MDCT delay (no framing delay included) */ +#define DELAY_AACELD(fl) \ + ((fl) / 2) /*!< ELD FB delay (no framing delay included) */ + +#define MAX_DS_DELAY (100) /*!< Maximum downsampler delay in SBR. */ +#define INPUTBUFFER_SIZE \ + (2 * (1024) + MAX_DS_DELAY + 1537) /*!< Audio input samples + downsampler \ + delay + sbr/aac delay compensation */ + +#define DEFAULT_HEADER_PERIOD_REPETITION_RATE \ + 10 /*!< Default header repetition rate used in transport library and for SBR \ + header. */ //////////////////////////////////////////////////////////////////////////////////// /** * Flags to characterize encoder modules to be supported in present instance. */ enum { - ENC_MODE_FLAG_AAC = 0x0001, - ENC_MODE_FLAG_SBR = 0x0002, - ENC_MODE_FLAG_PS = 0x0004, - ENC_MODE_FLAG_SAC = 0x0008, - ENC_MODE_FLAG_META = 0x0010 + ENC_MODE_FLAG_AAC = 0x0001, + ENC_MODE_FLAG_SBR = 0x0002, + ENC_MODE_FLAG_PS = 0x0004, + ENC_MODE_FLAG_SAC = 0x0008, + ENC_MODE_FLAG_META = 0x0010 }; //////////////////////////////////////////////////////////////////////////////////// typedef struct { - AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */ - UINT userSamplerate; /*!< Sampling frequency. */ - UINT nChannels; /*!< will be set via channelMode. */ - CHANNEL_MODE userChannelMode; - UINT userBitrate; - UINT userBitrateMode; - UINT userBandwidth; - UINT userAfterburner; - UINT userFramelength; - UINT userAncDataRate; - UINT userPeakBitrate; - - UCHAR userTns; /*!< Use TNS coding. */ - UCHAR userPns; /*!< Use PNS coding. */ - UCHAR userIntensity; /*!< Use Intensity coding. */ - - TRANSPORT_TYPE userTpType; /*!< Transport type */ - UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */ - UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for LOAS/LATM or ADTS (default 1). */ - UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */ - UCHAR userTpProtection; - UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate. Moreover this parameters is - used to configure repetition rate of PCE in raw_data_block. */ - - UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */ - UINT userPceAdditions; /*!< Configure additional bits in PCE. */ - - UCHAR userMetaDataMode; /*!< Meta data library configuration. */ - - UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */ - UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */ + AUDIO_OBJECT_TYPE userAOT; /*!< Audio Object Type. */ + UINT userSamplerate; /*!< Sampling frequency. */ + UINT nChannels; /*!< will be set via channelMode. */ + CHANNEL_MODE userChannelMode; + UINT userBitrate; + UINT userBitrateMode; + UINT userBandwidth; + UINT userAfterburner; + UINT userFramelength; + UINT userAncDataRate; + UINT userPeakBitrate; + + UCHAR userTns; /*!< Use TNS coding. */ + UCHAR userPns; /*!< Use PNS coding. */ + UCHAR userIntensity; /*!< Use Intensity coding. */ + + TRANSPORT_TYPE userTpType; /*!< Transport type */ + UCHAR userTpSignaling; /*!< Extension AOT signaling mode. */ + UCHAR userTpNsubFrames; /*!< Number of sub frames in a transport frame for + LOAS/LATM or ADTS (default 1). */ + UCHAR userTpAmxv; /*!< AudioMuxVersion to be used for LATM (default 0). */ + UCHAR userTpProtection; + UCHAR userTpHeaderPeriod; /*!< Parameter used to configure LATM/LOAS SMC rate. + Moreover this parameters is used to configure + repetition rate of PCE in raw_data_block. */ + + UCHAR userErTools; /*!< Use VCB11, HCR and/or RVLC ER tool. */ + UINT userPceAdditions; /*!< Configure additional bits in PCE. */ + + UCHAR userMetaDataMode; /*!< Meta data library configuration. */ + + UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */ + UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */ + + UINT userDownscaleFactor; } USER_PARAM; +/** + * SBR extenxion payload struct provides buffers to be filled in SBR encoder + * library. + */ +typedef struct { + UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */ + UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */ +} SBRENC_EXT_PAYLOAD; + //////////////////////////////////////////////////////////////////////////////////// /**************************************************************************** Structure Definitions ****************************************************************************/ -typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG; +typedef struct AACENC_CONFIG *HANDLE_AACENC_CONFIG; +struct AACENCODER { + USER_PARAM extParam; + CODER_CONFIG coderConfig; -struct AACENCODER -{ - USER_PARAM extParam; - CODER_CONFIG coderConfig; - - /* AAC */ - AACENC_CONFIG aacConfig; - HANDLE_AAC_ENC hAacEnc; - - /* SBR */ - HANDLE_SBR_ENCODER hEnvEnc; + /* AAC */ + AACENC_CONFIG aacConfig; + HANDLE_AAC_ENC hAacEnc; - /* Meta Data */ - HANDLE_FDK_METADATA_ENCODER hMetadataEnc; - INT metaDataAllowed; /* Signal whether chosen configuration allows metadata. Necessary for delay - compensation. Metadata mode is a separate parameter. */ + /* SBR */ + HANDLE_SBR_ENCODER hEnvEnc; /* SBR encoder */ + SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */ - /* Transport */ - HANDLE_TRANSPORTENC hTpEnc; + /* Meta Data */ + HANDLE_FDK_METADATA_ENCODER hMetadataEnc; + INT metaDataAllowed; /* Signal whether chosen configuration allows metadata. + Necessary for delay compensation. Metadata mode is a + separate parameter. */ - /* Output */ - UCHAR *outBuffer; /* Internal bitstream buffer */ - INT outBufferInBytes; /* Size of internal bitstream buffer*/ + HANDLE_MPS_ENCODER hMpsEnc; - /* Input */ - INT_PCM *inputBuffer; /* Internal input buffer. Input source for AAC encoder */ - INT inputBufferOffset; /* Where to write new input samples. */ + /* Transport */ + HANDLE_TRANSPORTENC hTpEnc; - INT nSamplesToRead; /* number of input samples neeeded for encoding one frame */ - INT nSamplesRead; /* number of input samples already in input buffer */ - INT nZerosAppended; /* appended zeros at end of file*/ - INT nDelay; /* encoder delay */ + INT_PCM + *inputBuffer; /* Internal input buffer. Input source for AAC encoder */ + UCHAR *outBuffer; /* Internal bitstream buffer */ - AACENC_EXT_PAYLOAD extPayload [MAX_TOTAL_EXT_PAYLOADS]; - /* Extension payload */ - UCHAR extPayloadData [(1)][(8)][MAX_PAYLOAD_SIZE]; - UINT extPayloadSize [(1)][(8)]; /* payload sizes in bits */ + INT inputBufferSize; /* Size of internal input buffer */ + INT inputBufferSizePerChannel; /* Size of internal input buffer per channel */ + INT outBufferInBytes; /* Size of internal bitstream buffer*/ - ULONG InitFlags; /* internal status to treggier re-initialization */ + INT inputBufferOffset; /* Where to write new input samples. */ + INT nSamplesToRead; /* number of input samples neeeded for encoding one frame + */ + INT nSamplesRead; /* number of input samples already in input buffer */ + INT nZerosAppended; /* appended zeros at end of file*/ + INT nDelay; /* codec delay */ + INT nDelayCore; /* codec delay, w/o the SBR decoder delay */ - /* Memory allocation info. */ - INT nMaxAacElements; - INT nMaxAacChannels; - INT nMaxSbrElements; - INT nMaxSbrChannels; - UINT nMaxSubFrames; + AACENC_EXT_PAYLOAD extPayload[MAX_TOTAL_EXT_PAYLOADS]; - UINT encoder_modis; + ULONG InitFlags; /* internal status to treggier re-initialization */ - /* Capability flags */ - UINT CAPF_tpEnc; + /* Memory allocation info. */ + INT nMaxAacElements; + INT nMaxAacChannels; + INT nMaxSbrElements; + INT nMaxSbrChannels; -} ; + UINT encoder_modis; -typedef struct -{ - ULONG samplingRate; /*!< Encoder output sampling rate. */ - ULONG bitrateRange; /*!< Lower bitrate range for config entry. */ + /* Capability flags */ + UINT CAPF_tpEnc; +}; - UCHAR lowDelaySbr; /*!< 0: ELD sbr off, - 1: ELD sbr on */ +typedef struct { + /* input */ + ULONG nChannels; /*!< Number of audio channels. */ + ULONG samplingRate; /*!< Encoder output sampling rate. */ + ULONG bitrateRange; /*!< Lower bitrate range for config entry. */ - UCHAR downsampledSbr; /*!< 0: ELD with dualrate sbr, - 1: ELD with downsampled sbr */ + /* output*/ + UCHAR sbrMode; /*!< 0: ELD sbr off, + 1: ELD with downsampled sbr, + 2: ELD with dualrate sbr. */ + CHANNEL_MODE chMode; /*!< Channel mode. */ } ELD_SBR_CONFIGURATOR; /** * \brief This table defines ELD/SBR default configurations. */ -static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = -{ - { 48000, 0, 1, 0 }, - { 48000, 64001, 0, 0 }, +static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = { + {1, 48000, 0, 2, MODE_1}, {1, 48000, 64000, 0, MODE_1}, + + {1, 44100, 0, 2, MODE_1}, {1, 44100, 64000, 0, MODE_1}, + + {1, 32000, 0, 2, MODE_1}, {1, 32000, 28000, 1, MODE_1}, + {1, 32000, 56000, 0, MODE_1}, - { 44100, 0, 1, 0 }, - { 44100, 64001, 0, 0 }, + {1, 24000, 0, 1, MODE_1}, {1, 24000, 40000, 0, MODE_1}, - { 32000, 0, 1, 0 }, - { 32000, 28000, 1, 1 }, - { 32000, 56000, 0, 0 }, + {1, 16000, 0, 1, MODE_1}, {1, 16000, 28000, 0, MODE_1}, - { 24000, 0, 1, 1 }, - { 24000, 40000, 0, 0 }, + {1, 15999, 0, 0, MODE_1}, - { 16000, 0, 1, 1 }, - { 16000, 28000, 0, 0 } + {2, 48000, 0, 2, MODE_2}, {2, 48000, 44000, 2, MODE_2}, + {2, 48000, 128000, 0, MODE_2}, + + {2, 44100, 0, 2, MODE_2}, {2, 44100, 44000, 2, MODE_2}, + {2, 44100, 128000, 0, MODE_2}, + + {2, 32000, 0, 2, MODE_2}, {2, 32000, 32000, 2, MODE_2}, + {2, 32000, 68000, 1, MODE_2}, {2, 32000, 96000, 0, MODE_2}, + + {2, 24000, 0, 1, MODE_2}, {2, 24000, 48000, 1, MODE_2}, + {2, 24000, 80000, 0, MODE_2}, + + {2, 16000, 0, 1, MODE_2}, {2, 16000, 32000, 1, MODE_2}, + {2, 16000, 64000, 0, MODE_2}, + + {2, 15999, 0, 0, MODE_2} }; /* * \brief Configure SBR for ELD configuration. * - * This function finds default SBR configuration for ELD based on sampling rate and channel bitrate. - * Outputparameters are SBR on/off, and SBR ratio. + * This function finds default SBR configuration for ELD based on number of + * channels, sampling rate and bitrate. * + * \param nChannels Number of audio channels. * \param samplingRate Audio signal sampling rate. - * \param channelMode Channel configuration to be used. - * \param totalBitrate Overall bitrate. - * \param eldSbr Pointer to eldSbr parameter, filled on return. - * \param eldSbrRatio Pointer to eldSbrRatio parameter, filled on return. + * \param bitrate Encoder bitrate. * - * \return - AACENC_OK, all fine. - * - AACENC_INVALID_CONFIG, on failure. + * \return - pointer to eld sbr configuration. + * - NULL, on failure. */ -static AACENC_ERROR eldSbrConfigurator( - const ULONG samplingRate, - const CHANNEL_MODE channelMode, - const ULONG totalBitrate, - UINT * const eldSbr, - UINT * const eldSbrRatio - ) -{ - AACENC_ERROR err = AACENC_OK; - int i, cfgIdx = -1; - const ULONG channelBitrate = totalBitrate / FDKaacEnc_GetChannelModeConfiguration(channelMode)->nChannelsEff; - - for (i=0; i<(int)(sizeof(eldSbrAutoConfigTab)/sizeof(ELD_SBR_CONFIGURATOR)); i++) { - if ( (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) - && (channelBitrate >= eldSbrAutoConfigTab[i].bitrateRange) ) - { - cfgIdx = i; - } - } - - if (cfgIdx != -1) { - *eldSbr = (eldSbrAutoConfigTab[cfgIdx].lowDelaySbr==0) ? 0 : 1; - *eldSbrRatio = (eldSbrAutoConfigTab[cfgIdx].downsampledSbr==0) ? 2 : 1; - } - else { - err = AACENC_INVALID_CONFIG; /* no default configuration for eld-sbr available. */ +static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels, + const ULONG samplingRate, + const ULONG bitrate) { + int i; + const ELD_SBR_CONFIGURATOR *pSetup = NULL; + + for (i = 0; + i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR)); + i++) { + if ((nChannels == eldSbrAutoConfigTab[i].nChannels) && + (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) && + (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) { + pSetup = &eldSbrAutoConfigTab[i]; } + } - return err; + return pSetup; } -static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) -{ - INT sbrUsed = 0; +static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) { + INT sbrUsed = 0; - if ( (hAacConfig->audioObjectType==AOT_SBR) || (hAacConfig->audioObjectType==AOT_PS) ) - { - sbrUsed = 1; - } - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) - { - sbrUsed = 1; - } + /* Note: Even if implicit signalling was selected, The AOT itself here is not + * AOT_AAC_LC */ + if ((hAacConfig->audioObjectType == AOT_SBR) || + (hAacConfig->audioObjectType == AOT_PS) || + (hAacConfig->audioObjectType == AOT_MP2_SBR)) { + sbrUsed = 1; + } + if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && + (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) { + sbrUsed = 1; + } - return ( sbrUsed ); + return (sbrUsed); } -static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) -{ - INT psUsed = 0; +static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) { + INT psUsed = 0; - if ( (audioObjectType==AOT_PS) ) - { - psUsed = 1; - } + if (audioObjectType == AOT_PS) { + psUsed = 1; + } - return ( psUsed ); + return (psUsed); +} + +static CHANNEL_MODE GetCoreChannelMode( + const CHANNEL_MODE channelMode, const AUDIO_OBJECT_TYPE audioObjectType) { + CHANNEL_MODE mappedChannelMode = channelMode; + if ((isPsActive(audioObjectType) && (channelMode == MODE_2)) || + (channelMode == MODE_212)) { + mappedChannelMode = MODE_1; + } + return mappedChannelMode; } static SBR_PS_SIGNALING getSbrSignalingMode( - const AUDIO_OBJECT_TYPE audioObjectType, - const TRANSPORT_TYPE transportType, - const UCHAR transportSignaling, - const UINT sbrRatio - ) + const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType, + const UCHAR transportSignaling, const UINT sbrRatio) { SBR_PS_SIGNALING sbrSignaling; - if (transportType==TT_UNKNOWN || sbrRatio==0) { + if (transportType == TT_UNKNOWN || sbrRatio == 0) { sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */ return sbrSignaling; } else { - sbrSignaling = SIG_IMPLICIT; /* default: implicit signaling */ + sbrSignaling = + SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling + */ } - if ( (audioObjectType==AOT_AAC_LC) || (audioObjectType==AOT_SBR) || (audioObjectType==AOT_PS) ) { + if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) || + (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) || + (audioObjectType == AOT_MP2_SBR)) { switch (transportType) { case TT_MP4_ADIF: case TT_MP4_ADTS: - sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only implicit signaling is possible */ + sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only + implicit signaling is possible */ break; case TT_MP4_RAW: @@ -380,16 +430,13 @@ static SBR_PS_SIGNALING getSbrSignalingMode( case TT_MP4_LATM_MCP0: case TT_MP4_LOAS: default: - if ( transportSignaling==0xFF ) { + if (transportSignaling == 0xFF) { /* Defaults */ - if ( sbrRatio==1 ) { - sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; /* For downsampled SBR, explicit signaling is mandatory */ - } else { - sbrSignaling = SIG_IMPLICIT; /* For dual-rate SBR, implicit signaling is default */ - } + sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; } else { /* User set parameters */ - /* Attention: Backward compatible explicit signaling does only work with AMV1 for LATM/LOAS */ + /* Attention: Backward compatible explicit signaling does only work + * with AMV1 for LATM/LOAS */ sbrSignaling = (SBR_PS_SIGNALING)transportSignaling; } break; @@ -403,78 +450,90 @@ static SBR_PS_SIGNALING getSbrSignalingMode( Allocate Encoder ****************************************************************************/ -H_ALLOC_MEM (_AacEncoder, AACENCODER) -C_ALLOC_MEM (_AacEncoder, AACENCODER, 1) - - - +H_ALLOC_MEM(_AacEncoder, AACENCODER) +C_ALLOC_MEM(_AacEncoder, struct AACENCODER, 1) /* * Map Encoder specific config structures to CODER_CONFIG. */ -static void FDKaacEnc_MapConfig( - CODER_CONFIG *const cc, - const USER_PARAM *const extCfg, - const SBR_PS_SIGNALING sbrSignaling, - const HANDLE_AACENC_CONFIG hAacConfig - ) -{ +static void FDKaacEnc_MapConfig(CODER_CONFIG *const cc, + const USER_PARAM *const extCfg, + const SBR_PS_SIGNALING sbrSignaling, + const HANDLE_AACENC_CONFIG hAacConfig) { AUDIO_OBJECT_TYPE transport_AOT = AOT_NULL_OBJECT; FDKmemclear(cc, sizeof(CODER_CONFIG)); cc->flags = 0; - transport_AOT = hAacConfig->audioObjectType; + cc->samplesPerFrame = hAacConfig->framelength; + cc->samplingRate = hAacConfig->sampleRate; + cc->extSamplingRate = extCfg->userSamplerate; + + /* Map virtual aot to transport aot. */ + switch (hAacConfig->audioObjectType) { + case AOT_MP2_AAC_LC: + transport_AOT = AOT_AAC_LC; + break; + case AOT_MP2_SBR: + transport_AOT = AOT_SBR; + cc->flags |= CC_SBR; + break; + default: + transport_AOT = hAacConfig->audioObjectType; + } if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { cc->flags |= (hAacConfig->syntaxFlags & AC_SBR_PRESENT) ? CC_SBR : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_LD_MPS) ? CC_SAC : 0; } /* transport type is usually AAC-LC. */ - if ( (transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS) ) { - cc->aot = AOT_AAC_LC; - } - else { - cc->aot = transport_AOT; + if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) { + cc->aot = AOT_AAC_LC; + } else { + cc->aot = transport_AOT; } /* Configure extension aot. */ - if (sbrSignaling==SIG_IMPLICIT) { - cc->extAOT = AOT_NULL_OBJECT; /* implicit */ - } - else { - if ( (sbrSignaling==SIG_EXPLICIT_BW_COMPATIBLE) && ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) ) { - cc->extAOT = AOT_SBR; /* explicit backward compatible */ - } - else { - cc->extAOT = transport_AOT; /* explicit hierarchical */ + if (sbrSignaling == SIG_IMPLICIT) { + cc->extAOT = AOT_NULL_OBJECT; /* implicit */ + } else { + if ((sbrSignaling == SIG_EXPLICIT_BW_COMPATIBLE) && + ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS))) { + cc->extAOT = AOT_SBR; /* explicit backward compatible */ + } else { + cc->extAOT = transport_AOT; /* explicit hierarchical */ } } - if ( (transport_AOT==AOT_SBR) || (transport_AOT==AOT_PS) ) { - cc->sbrPresent=1; - if (transport_AOT==AOT_PS) { - cc->psPresent=1; + if ((transport_AOT == AOT_SBR) || (transport_AOT == AOT_PS)) { + cc->sbrPresent = 1; + if (transport_AOT == AOT_PS) { + cc->psPresent = 1; } } - cc->sbrSignaling = sbrSignaling; + cc->sbrSignaling = sbrSignaling; - cc->extSamplingRate = extCfg->userSamplerate; - cc->bitRate = hAacConfig->bitRate; - cc->noChannels = hAacConfig->nChannels; - cc->flags |= CC_IS_BASELAYER; - cc->channelMode = hAacConfig->channelMode; + if (hAacConfig->downscaleFactor > 1) { + cc->downscaleSamplingRate = cc->samplingRate; + cc->samplingRate *= hAacConfig->downscaleFactor; + cc->extSamplingRate *= hAacConfig->downscaleFactor; + } + + cc->bitRate = hAacConfig->bitRate; + cc->noChannels = hAacConfig->nChannels; + cc->flags |= CC_IS_BASELAYER; + cc->channelMode = hAacConfig->channelMode; cc->nSubFrames = (hAacConfig->nSubFrames > 1 && extCfg->userTpNsubFrames == 1) - ? hAacConfig->nSubFrames - : extCfg->userTpNsubFrames; + ? hAacConfig->nSubFrames + : extCfg->userTpNsubFrames; - cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0; + cc->flags |= (extCfg->userTpProtection) ? CC_PROTECTION : 0; - if (extCfg->userTpHeaderPeriod!=0xFF) { - cc->headerPeriod = extCfg->userTpHeaderPeriod; - } - else { /* auto-mode */ + if (extCfg->userTpHeaderPeriod != 0xFF) { + cc->headerPeriod = extCfg->userTpHeaderPeriod; + } else { /* auto-mode */ switch (extCfg->userTpType) { case TT_MP4_ADTS: case TT_MP4_LOAS: @@ -486,27 +545,65 @@ static void FDKaacEnc_MapConfig( } } - cc->samplesPerFrame = hAacConfig->framelength; - cc->samplingRate = hAacConfig->sampleRate; - /* Mpeg-4 signaling for transport library. */ - cc->flags |= CC_MPEG_ID; + switch (hAacConfig->audioObjectType) { + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + cc->flags &= ~CC_MPEG_ID; /* Required for ADTS. */ + cc->extAOT = AOT_NULL_OBJECT; + break; + default: + cc->flags |= CC_MPEG_ID; + } /* ER-tools signaling. */ - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0; - cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_VCB11) ? CC_VCB11 : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_HCR) ? CC_HCR : 0; + cc->flags |= (hAacConfig->syntaxFlags & AC_ER_RVLC) ? CC_RVLC : 0; /* Matrix mixdown coefficient configuration. */ - if ( (extCfg->userPceAdditions&0x1) && (hAacConfig->epConfig==-1) - && ((cc->channelMode==MODE_1_2_2)||(cc->channelMode==MODE_1_2_2_1)) ) - { - cc->matrixMixdownA = ((extCfg->userPceAdditions>>1)&0x3)+1; - cc->flags |= (extCfg->userPceAdditions>>3)&0x1 ? CC_PSEUDO_SURROUND : 0; - } - else { + if ((extCfg->userPceAdditions & 0x1) && (hAacConfig->epConfig == -1) && + ((cc->channelMode == MODE_1_2_2) || (cc->channelMode == MODE_1_2_2_1))) { + cc->matrixMixdownA = ((extCfg->userPceAdditions >> 1) & 0x3) + 1; + cc->flags |= (extCfg->userPceAdditions >> 3) & 0x1 ? CC_PSEUDO_SURROUND : 0; + } else { cc->matrixMixdownA = 0; } + + cc->channelConfigZero = 0; +} + +/* + * Validate prefilled pointers within buffer descriptor. + * + * \param pBufDesc Pointer to buffer descriptor + + * \return - AACENC_OK, all fine. + * - AACENC_INVALID_HANDLE, on missing pointer initializiation. + * - AACENC_UNSUPPORTED_PARAMETER, on incorrect buffer descriptor + initialization. + */ +static AACENC_ERROR validateBufDesc(const AACENC_BufDesc *pBufDesc) { + AACENC_ERROR err = AACENC_OK; + + if (pBufDesc != NULL) { + int i; + if ((pBufDesc->bufferIdentifiers == NULL) || (pBufDesc->bufSizes == NULL) || + (pBufDesc->bufElSizes == NULL) || (pBufDesc->bufs == NULL)) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } + for (i = 0; i < pBufDesc->numBufs; i++) { + if (pBufDesc->bufs[i] == NULL) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } + } + } else { + err = AACENC_INVALID_HANDLE; + } +bail: + return err; } /* @@ -518,195 +615,172 @@ static void FDKaacEnc_MapConfig( * \return - Buffer descriptor index. * -1, if there is no entry available. */ -static INT getBufDescIdx( - const AACENC_BufDesc *pBufDesc, - const AACENC_BufferIdentifier identifier -) -{ - INT i, idx = -1; - - for (i=0; i<pBufDesc->numBufs; i++) { - if ( (AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] == identifier ) { +static INT getBufDescIdx(const AACENC_BufDesc *pBufDesc, + const AACENC_BufferIdentifier identifier) { + INT i, idx = -1; + + if (pBufDesc != NULL) { + for (i = 0; i < pBufDesc->numBufs; i++) { + if ((AACENC_BufferIdentifier)pBufDesc->bufferIdentifiers[i] == + identifier) { idx = i; break; } } - return idx; + } + return idx; } - /**************************************************************************** Function Declarations ****************************************************************************/ AAC_ENCODER_ERROR aacEncDefaultConfig(HANDLE_AACENC_CONFIG hAacConfig, - USER_PARAM *config) -{ - /* make reasonable default settings */ - FDKaacEnc_AacInitDefaultConfig (hAacConfig); - - /* clear configuration structure and copy default settings */ - FDKmemclear(config, sizeof(USER_PARAM)); - - /* copy encoder configuration settings */ - config->nChannels = hAacConfig->nChannels; - config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC; - config->userSamplerate = hAacConfig->sampleRate; - config->userChannelMode = hAacConfig->channelMode; - config->userBitrate = hAacConfig->bitRate; - config->userBitrateMode = hAacConfig->bitrateMode; - config->userPeakBitrate = (UINT)-1; - config->userBandwidth = hAacConfig->bandWidth; - config->userTns = hAacConfig->useTns; - config->userPns = hAacConfig->usePns; - config->userIntensity = hAacConfig->useIS; - config->userAfterburner = hAacConfig->useRequant; - config->userFramelength = (UINT)-1; - - if (hAacConfig->syntaxFlags & AC_ER_VCB11) { - config->userErTools |= 0x01; - } - if (hAacConfig->syntaxFlags & AC_ER_HCR) { - config->userErTools |= 0x02; - } - - /* initialize transport parameters */ - config->userTpType = TT_UNKNOWN; - config->userTpAmxv = 0; - config->userTpSignaling = 0xFF; /* choose signaling automatically */ - config->userTpNsubFrames = 1; - config->userTpProtection = 0; /* not crc protected*/ - config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */ - config->userPceAdditions = 0; /* no matrix mixdown coefficient */ - config->userMetaDataMode = 0; /* do not embed any meta data info */ - - config->userAncDataRate = 0; - - /* SBR rate is set to 0 here, which means it should be set automatically - in FDKaacEnc_AdjustEncSettings() if the user did not set a rate - expilicitely. */ - config->userSbrRatio = 0; - - /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable configuration. */ - config->userSbrEnabled = -1; - - return AAC_ENC_OK; + USER_PARAM *config) { + /* make reasonable default settings */ + FDKaacEnc_AacInitDefaultConfig(hAacConfig); + + /* clear configuration structure and copy default settings */ + FDKmemclear(config, sizeof(USER_PARAM)); + + /* copy encoder configuration settings */ + config->nChannels = hAacConfig->nChannels; + config->userAOT = hAacConfig->audioObjectType = AOT_AAC_LC; + config->userSamplerate = hAacConfig->sampleRate; + config->userChannelMode = hAacConfig->channelMode; + config->userBitrate = hAacConfig->bitRate; + config->userBitrateMode = hAacConfig->bitrateMode; + config->userPeakBitrate = (UINT)-1; + config->userBandwidth = hAacConfig->bandWidth; + config->userTns = hAacConfig->useTns; + config->userPns = hAacConfig->usePns; + config->userIntensity = hAacConfig->useIS; + config->userAfterburner = hAacConfig->useRequant; + config->userFramelength = (UINT)-1; + + config->userDownscaleFactor = 1; + + /* initialize transport parameters */ + config->userTpType = TT_UNKNOWN; + config->userTpAmxv = 0; + config->userTpSignaling = 0xFF; /* choose signaling automatically */ + config->userTpNsubFrames = 1; + config->userTpProtection = 0; /* not crc protected*/ + config->userTpHeaderPeriod = 0xFF; /* header period in auto mode */ + config->userPceAdditions = 0; /* no matrix mixdown coefficient */ + config->userMetaDataMode = 0; /* do not embed any meta data info */ + + config->userAncDataRate = 0; + + /* SBR rate is set to 0 here, which means it should be set automatically + in FDKaacEnc_AdjustEncSettings() if the user did not set a rate + expilicitely. */ + config->userSbrRatio = 0; + + /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable + * configuration. */ + config->userSbrEnabled = (UCHAR)-1; + + return AAC_ENC_OK; } -static -void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) -{ +static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, + SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) { INT codebits = bitRate; int el; /* Copy Element info */ - for (el=0; el<channelMapping->nElements; el++) { - sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; - sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; - sbrElInfo[el].elType = channelMapping->elInfo[el].elType; - sbrElInfo[el].bitRate = (INT)(fMultNorm(channelMapping->elInfo[el].relativeBits, (FIXP_DBL)bitRate)); - sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; - sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; - - codebits -= sbrElInfo[el].bitRate; + for (el = 0; el < channelMapping->nElements; el++) { + sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; + sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; + sbrElInfo[el].elType = channelMapping->elInfo[el].elType; + sbrElInfo[el].bitRate = + fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate); + sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; + sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; + sbrElInfo[el].fParametricStereo = 0; + sbrElInfo[el].fDualMono = 0; + + codebits -= sbrElInfo[el].bitRate; } sbrElInfo[0].bitRate += codebits; } - -static -INT aacEncoder_LimitBitrate( - const HANDLE_TRANSPORTENC hTpEnc, - const INT samplingRate, - const INT frameLength, - const INT nChannels, - const CHANNEL_MODE channelMode, - INT bitRate, - const INT nSubFrames, - const INT sbrActive, - const INT sbrDownSampleRate, - const AUDIO_OBJECT_TYPE aot - ) -{ +static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc, + const INT samplingRate, + const INT frameLength, const INT nChannels, + const CHANNEL_MODE channelMode, INT bitRate, + const INT nSubFrames, const INT sbrActive, + const INT sbrDownSampleRate, + const UINT syntaxFlags, + const AUDIO_OBJECT_TYPE aot) { INT coreSamplingRate; CHANNEL_MAPPING cm; FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm); if (sbrActive) { - coreSamplingRate = samplingRate >> (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate-1):1); + coreSamplingRate = + samplingRate >> + (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1); } else { coreSamplingRate = samplingRate; } - /* Consider bandwidth channel bit rate limit (see bandwidth.cpp: GetBandwidthEntry()) */ - if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { - bitRate = FDKmin(360000*nChannels, bitRate); - bitRate = FDKmax(8000*nChannels, bitRate); - } - - if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { - bitRate = FDKmin(576000*nChannels, bitRate); - /*bitRate = FDKmax(0*nChannels, bitRate);*/ - } - - /* Limit bit rate in respect to the core coder */ - bitRate = FDKaacEnc_LimitBitrate( - hTpEnc, - coreSamplingRate, - frameLength, - nChannels, - cm.nChannelsEff, - bitRate, - -1, - NULL, - -1, - nSubFrames - ); + bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength, + nChannels, cm.nChannelsEff, bitRate, -1, + NULL, AACENC_BR_MODE_INVALID, nSubFrames); /* Limit bit rate in respect to available SBR modes if active */ - if (sbrActive) - { + if (sbrActive) { int numIterations = 0; INT initialBitrate, adjustedBitrate; - initialBitrate = adjustedBitrate = bitRate; + adjustedBitrate = bitRate; - /* Find total bitrate which provides valid configuration for each SBR element. */ + /* Find total bitrate which provides valid configuration for each SBR + * element. */ do { int e; - SBR_ELEMENT_INFO sbrElInfo[(8)]; - FDK_ASSERT(cm.nElements <= (8)); + SBR_ELEMENT_INFO sbrElInfo[((8))]; + FDK_ASSERT(cm.nElements <= ((8))); initialBitrate = adjustedBitrate; /* Get bit rate for each SBR element */ aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate); - for (e=0; e<cm.nElements; e++) - { + for (e = 0; e < cm.nElements; e++) { INT sbrElementBitRateIn, sbrBitRateOut; if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) { continue; } sbrElementBitRateIn = sbrElInfo[e].bitRate; - sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn , cm.elInfo[e].nChannelsInEl, coreSamplingRate, aot); + + sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn, + cm.elInfo[e].nChannelsInEl, + coreSamplingRate, aot); + if (sbrBitRateOut == 0) { return 0; } - /* If bitrates don't match, distribution and limiting needs to be determined again. - Abort element loop and restart with adapted bitrate. */ + /* If bitrates don't match, distribution and limiting needs to be + determined again. Abort element loop and restart with adapted + bitrate. */ if (sbrElementBitRateIn != sbrBitRateOut) { - if (sbrElementBitRateIn < sbrBitRateOut) { - adjustedBitrate = fMax(initialBitrate, (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut+8), cm.elInfo[e].relativeBits)); + adjustedBitrate = fMax(initialBitrate, + (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8), + cm.elInfo[e].relativeBits)); break; } if (sbrElementBitRateIn > sbrBitRateOut) { - adjustedBitrate = fMin(initialBitrate, (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut-8), cm.elInfo[e].relativeBits)); + adjustedBitrate = fMin(initialBitrate, + (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8), + cm.elInfo[e].relativeBits)); break; } @@ -716,289 +790,422 @@ INT aacEncoder_LimitBitrate( numIterations++; /* restrict iteration to worst case of num elements */ - } while ( (initialBitrate!=adjustedBitrate) && (numIterations<=cm.nElements) ); + } while ((initialBitrate != adjustedBitrate) && + (numIterations <= cm.nElements)); /* Unequal bitrates mean that no reasonable bitrate configuration found. */ - bitRate = (initialBitrate==adjustedBitrate) ? adjustedBitrate : 0; + bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0; } - FDK_ASSERT(bitRate > 0); + /* Limit bit rate in respect to available MPS modes if active */ + if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) && + (channelMode == MODE_1)) { + bitRate = FDK_MpegsEnc_GetClosestBitRate( + aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0, + bitRate); + } return bitRate; } /* + * \brief Get CBR bitrate + * + * \hAacConfig Internal encoder config + * \return Bitrate + */ +static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig, + const INT userSbrRatio) { + INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannelsEff * + hAacConfig->sampleRate; + + if (isPsActive(hAacConfig->audioObjectType)) { + bitrate = 1 * bitrate; /* 0.5 bit per sample */ + } else if (isSbrActive(hAacConfig)) { + if ((userSbrRatio == 2) || + ((userSbrRatio == 0) && + (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) { + bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */ + } + if ((userSbrRatio == 1) || + ((userSbrRatio == 0) && + (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) { + bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */ + } + } else { + bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */ + } + + return bitrate; +} + +/* * \brief Consistency check of given USER_PARAM struct and * copy back configuration from public struct into internal * encoder configuration struct. * * \hAacEncoder Internal encoder config which is to be updated * \param config User provided config (public struct) - * \return ´returns always AAC_ENC_OK + * \return returns always AAC_ENC_OK */ -static -AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, - USER_PARAM *config) -{ - AACENC_ERROR err = AACENC_OK; - - /* Get struct pointers. */ - HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; - - hAacConfig->nChannels = config->nChannels; - - /* Encoder settings update. */ - hAacConfig->sampleRate = config->userSamplerate; - hAacConfig->useTns = config->userTns; - hAacConfig->usePns = config->userPns; - hAacConfig->useIS = config->userIntensity; - hAacConfig->bitRate = config->userBitrate; - hAacConfig->channelMode = config->userChannelMode; - hAacConfig->bitrateMode = config->userBitrateMode; - hAacConfig->bandWidth = config->userBandwidth; - hAacConfig->useRequant = config->userAfterburner; - - hAacConfig->audioObjectType = config->userAOT; - hAacConfig->anc_Rate = config->userAncDataRate; - hAacConfig->syntaxFlags = 0; - hAacConfig->epConfig = -1; - - if (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) { - hAacConfig->audioMuxVersion = config->userTpAmxv; - } - else { - hAacConfig->audioMuxVersion = -1; - } +static AACENC_ERROR FDKaacEnc_AdjustEncSettings(HANDLE_AACENCODER hAacEncoder, + USER_PARAM *config) { + AACENC_ERROR err = AACENC_OK; + + /* Get struct pointers. */ + HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; + + /* Encoder settings update. */ + hAacConfig->sampleRate = config->userSamplerate; + if (config->userDownscaleFactor > 1) { + hAacConfig->useTns = 0; + hAacConfig->usePns = 0; + hAacConfig->useIS = 0; + } else { + hAacConfig->useTns = config->userTns; + hAacConfig->usePns = config->userPns; + hAacConfig->useIS = config->userIntensity; + } - /* Adapt internal AOT when necessary. */ - switch ( hAacConfig->audioObjectType ) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 1024; - if (hAacConfig->framelength != 1024) { - return AACENC_INVALID_CONFIG; - } - break; - case AOT_ER_AAC_LD: - hAacConfig->epConfig = 0; - hAacConfig->syntaxFlags |= AC_ER|AC_LD; - hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512; - if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { - return AACENC_INVALID_CONFIG; - } - break; - case AOT_ER_AAC_ELD: - hAacConfig->epConfig = 0; - hAacConfig->syntaxFlags |= AC_ER|AC_ELD; - hAacConfig->syntaxFlags |= ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); - hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); - hAacConfig->syntaxFlags |= ((config->userSbrEnabled==1) ? AC_SBR_PRESENT : 0); - config->userTpType = (config->userTpType!=TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; - hAacConfig->framelength = (config->userFramelength!=(UINT)-1) ? config->userFramelength : 512; - if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { - return AACENC_INVALID_CONFIG; - } + hAacConfig->audioObjectType = config->userAOT; + hAacConfig->channelMode = + GetCoreChannelMode(config->userChannelMode, hAacConfig->audioObjectType); + hAacConfig->nChannels = + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannels; + hAacConfig->bitrateMode = (AACENC_BITRATE_MODE)config->userBitrateMode; + hAacConfig->bandWidth = config->userBandwidth; + hAacConfig->useRequant = config->userAfterburner; + + hAacConfig->anc_Rate = config->userAncDataRate; + hAacConfig->syntaxFlags = 0; + hAacConfig->epConfig = -1; + + if (hAacConfig->audioObjectType != AOT_ER_AAC_ELD && + config->userDownscaleFactor > 1) { + return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD + */ + } + if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) { + return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD + w/o SBR */ + } + if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) { + return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */ + } + + if (config->userTpType == TT_MP4_LATM_MCP1 || + config->userTpType == TT_MP4_LATM_MCP0 || + config->userTpType == TT_MP4_LOAS) { + hAacConfig->audioMuxVersion = config->userTpAmxv; + } else { + hAacConfig->audioMuxVersion = -1; + } + + /* Adapt internal AOT when necessary. */ + switch (config->userAOT) { + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + hAacConfig->usePns = 0; + case AOT_AAC_LC: + case AOT_SBR: + case AOT_PS: + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_ADTS; + hAacConfig->framelength = (config->userFramelength != (UINT)-1) + ? config->userFramelength + : 1024; + if (hAacConfig->framelength != 1024 && hAacConfig->framelength != 960) { + return AACENC_INVALID_CONFIG; + } + break; + case AOT_ER_AAC_LD: + hAacConfig->epConfig = 0; + hAacConfig->syntaxFlags |= AC_ER | AC_LD; + hAacConfig->syntaxFlags |= + ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; + hAacConfig->framelength = + (config->userFramelength != (UINT)-1) ? config->userFramelength : 512; + if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480) { + return AACENC_INVALID_CONFIG; + } + break; + case AOT_ER_AAC_ELD: + hAacConfig->epConfig = 0; + hAacConfig->syntaxFlags |= AC_ER | AC_ELD; + hAacConfig->syntaxFlags |= + ((config->userErTools & 0x1) ? AC_ER_VCB11 : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); + hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); + hAacConfig->syntaxFlags |= + ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0); + hAacConfig->syntaxFlags |= + ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0); + config->userTpType = + (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; + hAacConfig->framelength = + (config->userFramelength != (UINT)-1) ? config->userFramelength : 512; + + hAacConfig->downscaleFactor = config->userDownscaleFactor; + + switch (config->userDownscaleFactor) { + case 1: break; - default: + case 2: + case 4: + hAacConfig->syntaxFlags |= AC_ELD_DOWNSCALE; break; - } - - switch ( hAacConfig->audioObjectType ) { - case AOT_ER_AAC_LD: - case AOT_ER_AAC_ELD: - if (config->userBitrateMode==0) { - /* bitreservoir = (maxBitRes-minBitRes)/(maxBitRate-minBitrate)*(bitRate-minBitrate)+minBitRes; */ - if ( isLowDelay(hAacConfig->audioObjectType) ) { - INT bitreservoir; - INT brPerChannel = hAacConfig->bitRate/hAacConfig->nChannels; - brPerChannel = fMin(BITRATE_MAX_LD, fMax(BITRATE_MIN_LD, brPerChannel)); - FIXP_DBL slope = fDivNorm((brPerChannel-BITRATE_MIN_LD), BITRATE_MAX_LD-BITRATE_MIN_LD); /* calc slope for interpolation */ - bitreservoir = fMultI(slope, (INT)(BITRES_MAX_LD-BITRES_MIN_LD)) + BITRES_MIN_LD; /* interpolate */ - hAacConfig->bitreservoir = bitreservoir & ~7; /* align to bytes */ - } - } - if (hAacConfig->bitrateMode!=0) { + default: return AACENC_INVALID_CONFIG; - } - break; - default: - break; - } + } - hAacConfig->bitRate = config->userBitrate; + if (hAacConfig->framelength != 512 && hAacConfig->framelength != 480 && + hAacConfig->framelength != 256 && hAacConfig->framelength != 240 && + hAacConfig->framelength != 128 && hAacConfig->framelength != 120) { + return AACENC_INVALID_CONFIG; + } + break; + default: + break; + } - /* get bitrate in VBR configuration */ - if ( (hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5) ) { - /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode. */ - hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode, hAacConfig->channelMode); + /* Initialize SBR parameters */ + if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) { + /* Automatic SBR ratio configuration + * - downsampled SBR for ELD + * - otherwise always dualrate SBR + */ + if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { + hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) && + (hAacConfig->sampleRate >= 27713)) + ? 2 + : 1; + } else { + hAacConfig->sbrRatio = 2; } + } else { + /* SBR ratio has been set by the user, so use it. */ + hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0; + } + /* Set default bitrate */ + hAacConfig->bitRate = config->userBitrate; + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_CBR: + /* Set default bitrate if no external bitrate declared. */ + if (config->userBitrate == (UINT)-1) { + hAacConfig->bitRate = + FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio); + } + hAacConfig->averageBits = -1; + break; + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + /* Get bitrate in VBR configuration */ + /* In VBR mode; SBR-modul depends on bitrate, core encoder on bitrateMode. + */ + hAacConfig->bitRate = FDKaacEnc_GetVBRBitrate(hAacConfig->bitrateMode, + hAacConfig->channelMode); + break; + default: + return AACENC_INVALID_CONFIG; + } - /* Set default bitrate if no external bitrate declared. */ - if ( (hAacConfig->bitrateMode==0) && (config->userBitrate==(UINT)-1) ) { - INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff * hAacConfig->sampleRate; - - if ( isPsActive(hAacConfig->audioObjectType) ) { - hAacConfig->bitRate = (bitrate>>1); /* 0.5 bit per sample */ - } - else if ( isSbrActive(hAacConfig) ) - { - if ( (config->userSbrRatio==2) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType!=AOT_ER_AAC_ELD)) ) { - hAacConfig->bitRate = (bitrate + (bitrate>>2))>>1; /* 0.625 bits per sample */ - } - if ( (config->userSbrRatio==1) || ((config->userSbrRatio==0)&&(hAacConfig->audioObjectType==AOT_ER_AAC_ELD)) ) { - hAacConfig->bitRate = (bitrate + (bitrate>>3)); /* 1.125 bits per sample */ - } - } else - { - hAacConfig->bitRate = bitrate + (bitrate>>1); /* 1.5 bits per sample */ - } - } - - if ((hAacConfig->bitrateMode >= 0) && (hAacConfig->bitrateMode <= 5)) { + /* set bitreservoir size */ + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + case AACENC_BR_MODE_CBR: if ((INT)config->userPeakBitrate != -1) { - hAacConfig->maxBitsPerFrame = (FDKaacEnc_CalcBitsPerFrame(fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), hAacConfig->framelength, hAacConfig->sampleRate) + 7)&~7; - } - else { + hAacConfig->maxBitsPerFrame = + (FDKaacEnc_CalcBitsPerFrame( + fMax(hAacConfig->bitRate, (INT)config->userPeakBitrate), + hAacConfig->framelength, hAacConfig->sampleRate) + + 7) & + ~7; + } else { hAacConfig->maxBitsPerFrame = -1; } - if (hAacConfig->audioMuxVersion==2) { - hAacConfig->minBitsPerFrame = fMin(32*8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, hAacConfig->framelength, hAacConfig->sampleRate))&~7; - } - } - - /* Initialize SBR parameters */ - if ( (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) - && (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio==0) ) - { - UINT eldSbr = 0; - UINT eldSbrRatio = 0; - - if ( AACENC_OK!=(err=eldSbrConfigurator( - hAacConfig->sampleRate, - hAacConfig->channelMode, - hAacConfig->bitRate, - &eldSbr, - &eldSbrRatio)) ) - { - return err; + if (hAacConfig->audioMuxVersion == 2) { + hAacConfig->minBitsPerFrame = + fMin(32 * 8, FDKaacEnc_CalcBitsPerFrame(hAacConfig->bitRate, + hAacConfig->framelength, + hAacConfig->sampleRate)) & + ~7; } + break; + default: + return AACENC_INVALID_CONFIG; + } - hAacConfig->syntaxFlags |= ((eldSbr) ? AC_SBR_PRESENT : 0); - hAacConfig->sbrRatio = eldSbrRatio; - } - else - if ( (config->userSbrRatio==0) && (isSbrActive(hAacConfig)) ) { - /* Automatic SBR ratio configuration - * - downsampled SBR for ELD - * - otherwise always dualrate SBR - */ - hAacConfig->sbrRatio = (hAacConfig->audioObjectType==AOT_ER_AAC_ELD) ? 1 : 2; - } - else { - /* SBR ratio has been set by the user, so use it. */ - hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0; + /* Max bits per frame limitation depending on transport format. */ + if ((config->userTpNsubFrames > 1)) { + int maxFrameLength = 8 * hAacEncoder->outBufferInBytes; + switch (config->userTpType) { + case TT_MP4_LOAS: + maxFrameLength = + fMin(maxFrameLength, 8 * (1 << 13)) / config->userTpNsubFrames; + break; + case TT_MP4_ADTS: + maxFrameLength = fMin(maxFrameLength, 8 * ((1 << 13) - 1)) / + config->userTpNsubFrames; + break; + default: + maxFrameLength = -1; } - - { - UCHAR tpSignaling=getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio); - - if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) && - (config->userTpType==TT_MP4_LATM_MCP1 || config->userTpType==TT_MP4_LATM_MCP0 || config->userTpType==TT_MP4_LOAS) && - (tpSignaling==1) && (config->userTpAmxv==0) ) { - /* For backward compatible explicit signaling, AMV1 has to be active */ - return AACENC_INVALID_CONFIG; + if (maxFrameLength != -1) { + if (hAacConfig->maxBitsPerFrame > maxFrameLength) { + return AACENC_INVALID_CONFIG; + } else if (hAacConfig->maxBitsPerFrame == -1) { + hAacConfig->maxBitsPerFrame = maxFrameLength; } + } + } - if ( (hAacConfig->audioObjectType==AOT_AAC_LC || hAacConfig->audioObjectType==AOT_SBR || hAacConfig->audioObjectType==AOT_PS) && - (tpSignaling==0) && (hAacConfig->sbrRatio==1)) { - /* Downsampled SBR has to be signaled explicitely (for transmission of SBR sampling fequency) */ - return AACENC_INVALID_CONFIG; - } + if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) && + !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) && + (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) && + ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) { + const ELD_SBR_CONFIGURATOR *pConfig = NULL; + + if (NULL != + (pConfig = eldSbrConfigurator( + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannels, + hAacConfig->sampleRate, hAacConfig->bitRate))) { + hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT; + hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0; + hAacConfig->channelMode = + GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType); + hAacConfig->nChannels = + FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannels; + hAacConfig->sbrRatio = + (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2; } + } + { + UCHAR tpSignaling = + getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, + config->userTpSignaling, hAacConfig->sbrRatio); + + if ((hAacConfig->audioObjectType == AOT_AAC_LC || + hAacConfig->audioObjectType == AOT_SBR || + hAacConfig->audioObjectType == AOT_PS) && + (config->userTpType == TT_MP4_LATM_MCP1 || + config->userTpType == TT_MP4_LATM_MCP0 || + config->userTpType == TT_MP4_LOAS) && + (tpSignaling == 1) && (config->userTpAmxv == 0)) { + /* For backward compatible explicit signaling, AMV1 has to be active */ + return AACENC_INVALID_CONFIG; + } + + if ((hAacConfig->audioObjectType == AOT_AAC_LC || + hAacConfig->audioObjectType == AOT_SBR || + hAacConfig->audioObjectType == AOT_PS) && + (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) { + /* Downsampled SBR has to be signaled explicitely (for transmission of SBR + * sampling fequency) */ + return AACENC_INVALID_CONFIG; + } + } + switch (hAacConfig->bitrateMode) { + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + /* We need the frame length to call aacEncoder_LimitBitrate() */ + if (0 >= (hAacConfig->bitRate = aacEncoder_LimitBitrate( + NULL, hAacConfig->sampleRate, hAacConfig->framelength, + hAacConfig->nChannels, hAacConfig->channelMode, + hAacConfig->bitRate, hAacConfig->nSubFrames, + isSbrActive(hAacConfig), hAacConfig->sbrRatio, + hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) { + return AACENC_INVALID_CONFIG; + } + break; + default: + break; + } - /* We need the frame length to call aacEncoder_LimitBitrate() */ - hAacConfig->bitRate = aacEncoder_LimitBitrate( - NULL, - hAacConfig->sampleRate, - hAacConfig->framelength, - hAacConfig->nChannels, - hAacConfig->channelMode, - hAacConfig->bitRate, - hAacConfig->nSubFrames, - isSbrActive(hAacConfig), - hAacConfig->sbrRatio, - hAacConfig->audioObjectType - ); - - /* Configure PNS */ - if ( ((hAacConfig->bitrateMode>=1) && (hAacConfig->bitrateMode<=5)) /* VBR without PNS. */ - || (hAacConfig->useTns == 0) ) /* TNS required. */ - { - hAacConfig->usePns = 0; - } + /* Configure PNS */ + if (AACENC_BR_MODE_IS_VBR(hAacConfig->bitrateMode) /* VBR without PNS. */ + || (hAacConfig->useTns == 0)) /* TNS required. */ + { + hAacConfig->usePns = 0; + } - if (hAacConfig->epConfig >= 0) { - hAacConfig->syntaxFlags |= AC_ER; - if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) { - return AACENC_INVALID_CONFIG; /* Cannel config 0 not supported. */ - } + if (hAacConfig->epConfig >= 0) { + hAacConfig->syntaxFlags |= AC_ER; + if (((INT)hAacConfig->channelMode < 1) || + ((INT)hAacConfig->channelMode > 14)) { + return AACENC_INVALID_CONFIG; /* Channel config 0 not supported. */ } + } - if ( FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, hAacConfig->nChannels) != AAC_ENC_OK) { - return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is just a check-up */ + if ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0) { + if (FDKaacEnc_DetermineEncoderMode(&hAacConfig->channelMode, + hAacConfig->nChannels) != AAC_ENC_OK) { + return AACENC_INVALID_CONFIG; /* nChannels doesn't match chMode, this is + just a check-up */ } + } - if ( (hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) - || ( (FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode)->nChannelsEff > hAacEncoder->nMaxSbrChannels) && - isSbrActive(hAacConfig) ) - ) - { - return AACENC_INVALID_CONFIG; /* not enough channels allocated */ - } + if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) || + ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) + ->nChannelsEff > hAacEncoder->nMaxSbrChannels) && + isSbrActive(hAacConfig))) { + return AACENC_INVALID_CONFIG; /* not enough channels allocated */ + } - /* Meta data restriction. */ - switch (hAacConfig->audioObjectType) - { - /* Allow metadata support */ - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - hAacEncoder->metaDataAllowed = 1; - if (((INT)hAacConfig->channelMode < 1) || ((INT)hAacConfig->channelMode > 7)) { - config->userMetaDataMode = 0; - } - break; - /* Prohibit metadata support */ - default: - hAacEncoder->metaDataAllowed = 0; - } + /* Meta data restriction. */ + switch (hAacConfig->audioObjectType) { + /* Allow metadata support */ + case AOT_AAC_LC: + case AOT_SBR: + case AOT_PS: + case AOT_MP2_AAC_LC: + case AOT_MP2_SBR: + hAacEncoder->metaDataAllowed = 1; + if (!((((INT)hAacConfig->channelMode >= 1) && + ((INT)hAacConfig->channelMode <= 14)) || + (MODE_7_1_REAR_SURROUND == hAacConfig->channelMode) || + (MODE_7_1_FRONT_CENTER == hAacConfig->channelMode))) { + config->userMetaDataMode = 0; + } + break; + /* Prohibit metadata support */ + default: + hAacEncoder->metaDataAllowed = 0; + } - return err; + return err; } -static -INT aacenc_SbrCallback( - void * self, - HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, - const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, - const INT elementIndex - ) -{ +static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs, + const INT sampleRateIn, const INT sampleRateOut, + const INT samplesPerFrame, + const AUDIO_OBJECT_TYPE coreCodec, + const MP4_ELEMENT_ID elementID, + const INT elementIndex, const UCHAR harmonicSbr, + const UCHAR stereoConfigIndex, + const UCHAR configMode, UCHAR *configChanged, + const INT downscaleFactor) { HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0); @@ -1006,725 +1213,835 @@ INT aacenc_SbrCallback( return 0; } -static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, - ULONG InitFlags, - USER_PARAM *config) -{ - AACENC_ERROR err = AACENC_OK; +INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, + const AUDIO_OBJECT_TYPE coreCodec, + const INT samplingRate, const INT stereoConfigIndex, + const INT coreSbrFrameLengthIndex, const INT configBytes, + const UCHAR configMode, UCHAR *configChanged) { + HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; - INT aacBufferOffset = 0; - HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc; - HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; + return (FDK_MpegsEnc_WriteSpatialSpecificConfig(hAacEncoder->hMpsEnc, hBs)); +} - hAacEncoder->nZerosAppended = 0; /* count appended zeros */ +static AACENC_ERROR aacEncInit(HANDLE_AACENCODER hAacEncoder, ULONG InitFlags, + USER_PARAM *config) { + AACENC_ERROR err = AACENC_OK; - INT frameLength = hAacConfig->framelength; + INT aacBufferOffset = 0; + HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc; + HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - CHANNEL_MODE prevChMode = hAacConfig->channelMode; + hAacEncoder->nZerosAppended = 0; /* count appended zeros */ - /* Verify settings and update: config -> heAacEncoder */ - if ( (err=FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK ) { - return err; - } - frameLength = hAacConfig->framelength; /* adapt temporal framelength */ + INT frameLength = hAacConfig->framelength; - /* Seamless channel reconfiguration in sbr not fully implemented */ - if ( (prevChMode!=hAacConfig->channelMode) && isSbrActive(hAacConfig) ) { - InitFlags |= AACENC_INIT_STATES; - } - } + if ((InitFlags & AACENC_INIT_CONFIG)) { + CHANNEL_MODE prevChMode = hAacConfig->channelMode; - /* Clear input buffer */ - if ( InitFlags == AACENC_INIT_ALL ) { - FDKmemclear(hAacEncoder->inputBuffer, sizeof(INT_PCM)*hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE); + /* Verify settings and update: config -> heAacEncoder */ + if ((err = FDKaacEnc_AdjustEncSettings(hAacEncoder, config)) != AACENC_OK) { + return err; } + frameLength = hAacConfig->framelength; /* adapt temporal framelength */ - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - aacBufferOffset = 0; - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { - hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength); - } else - { - hAacEncoder->nDelay = DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */ - } - hAacConfig->ancDataBitRate = 0; + /* Seamless channel reconfiguration in sbr not fully implemented */ + if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) { + InitFlags |= AACENC_INIT_STATES; } + } - if ( isSbrActive(hAacConfig) && - ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) ) - { - INT sbrError; - SBR_ELEMENT_INFO sbrElInfo[(8)]; - CHANNEL_MAPPING channelMapping; - - if ( FDKaacEnc_InitChannelMapping(hAacConfig->channelMode, - hAacConfig->channelOrder, - &channelMapping) != AAC_ENC_OK ) - { - return AACENC_INIT_ERROR; - } + /* Clear input buffer */ + if (InitFlags == AACENC_INIT_ALL) { + FDKmemclear(hAacEncoder->inputBuffer, + sizeof(INT_PCM) * hAacEncoder->inputBufferSize); + } - /* Check return value and if the SBR encoder can handle enough elements */ - if (channelMapping.nElements > (8)) { - return AACENC_INIT_ERROR; - } + if ((InitFlags & AACENC_INIT_CONFIG)) { + aacBufferOffset = 0; + switch (hAacConfig->audioObjectType) { + case AOT_ER_AAC_LD: + hAacEncoder->nDelay = DELAY_AACLD(hAacConfig->framelength); + break; + case AOT_ER_AAC_ELD: + hAacEncoder->nDelay = DELAY_AACELD(hAacConfig->framelength); + break; + default: + hAacEncoder->nDelay = + DELAY_AAC(hAacConfig->framelength); /* AAC encoder delay */ + } - aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); - - UINT initFlag = 0; - initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; - - /* Let the SBR encoder take a look at the configuration and change if required. */ - sbrError = sbrEncoder_Init( - *hSbrEncoder, - sbrElInfo, - channelMapping.nElements, - hAacEncoder->inputBuffer, - &hAacConfig->bandWidth, - &aacBufferOffset, - &hAacConfig->nChannels, - &hAacConfig->sampleRate, - &hAacConfig->sbrRatio, - &frameLength, - hAacConfig->audioObjectType, - &hAacEncoder->nDelay, - (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, - (config->userTpHeaderPeriod!=0xFF) ? config->userTpHeaderPeriod : DEFAULT_HEADER_PERIOD_REPETITION_RATE, - initFlag - ); - - /* Suppress AOT reconfiguration and check error status. */ - if (sbrError) { - return AACENC_INIT_SBR_ERROR; - } + hAacConfig->ancDataBitRate = 0; + } - if (hAacConfig->nChannels == 1) { - hAacConfig->channelMode = MODE_1; - } + if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) && + ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { + INT sbrError; + UINT initFlag = 0; + SBR_ELEMENT_INFO sbrElInfo[(8)]; + CHANNEL_MAPPING channelMapping; + CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType) + ? config->userChannelMode + : hAacConfig->channelMode; + INT numChannels = isPsActive(hAacConfig->audioObjectType) + ? config->nChannels + : hAacConfig->nChannels; - /* Never use PNS if SBR is active */ - if ( hAacConfig->usePns ) { - hAacConfig->usePns = 0; - } + if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder, + &channelMapping) != AAC_ENC_OK) { + return AACENC_INIT_ERROR; + } - /* estimated bitrate consumed by SBR or PS */ - hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder) ; + /* Check return value and if the SBR encoder can handle enough elements */ + if (channelMapping.nElements > (8)) { + return AACENC_INIT_ERROR; + } - } /* sbr initialization */ + aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); + initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; - /* - * Initialize Transport - Module. - */ - if ( (InitFlags & AACENC_INIT_TRANSPORT) ) - { - UINT flags = 0; - - FDKaacEnc_MapConfig( - &hAacEncoder->coderConfig, - config, - getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, config->userTpSignaling, hAacConfig->sbrRatio), - hAacConfig); - - /* create flags for transport encoder */ - if (config->userTpAmxv != 0) { - flags |= TP_FLAG_LATM_AMV; - } - /* Clear output buffer */ - FDKmemclear(hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes*sizeof(UCHAR)); + /* Let the SBR encoder take a look at the configuration and change if + * required. */ + sbrError = sbrEncoder_Init( + *hSbrEncoder, sbrElInfo, channelMapping.nElements, + hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel, + &hAacConfig->bandWidth, &aacBufferOffset, &numChannels, + hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio, + &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay, + (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, + (config->userTpHeaderPeriod != 0xFF) + ? config->userTpHeaderPeriod + : DEFAULT_HEADER_PERIOD_REPETITION_RATE, + initFlag); - /* Initialize Bitstream encoder */ - if ( transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer, hAacEncoder->outBufferInBytes, config->userTpType, &hAacEncoder->coderConfig, flags) != 0) { - return AACENC_INIT_TP_ERROR; - } + /* Suppress AOT reconfiguration and check error status. */ + if ((sbrError) || (numChannels != hAacConfig->nChannels)) { + return AACENC_INIT_SBR_ERROR; + } - } /* transport initialization */ + if (numChannels == 1) { + hAacConfig->channelMode = MODE_1; + } - /* - * Initialize AAC - Core. - */ - if ( (InitFlags & AACENC_INIT_CONFIG) || - (InitFlags & AACENC_INIT_STATES) ) - { - AAC_ENCODER_ERROR err; - err = FDKaacEnc_Initialize(hAacEncoder->hAacEnc, - hAacConfig, - hAacEncoder->hTpEnc, - (InitFlags & AACENC_INIT_STATES) ? 1 : 0); - - if (err != AAC_ENC_OK) { - return AACENC_INIT_AAC_ERROR; - } + /* Never use PNS if SBR is active */ + if (hAacConfig->usePns) { + hAacConfig->usePns = 0; + } - } /* aac initialization */ + /* estimated bitrate consumed by SBR or PS */ + hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder); - /* - * Initialize Meta Data - Encoder. - */ - if ( hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed!=0) && - ((InitFlags & AACENC_INIT_CONFIG) ||(InitFlags & AACENC_INIT_STATES)) ) - { - INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); + } /* sbr initialization */ - if ( isSbrActive(hAacConfig) && hSbrEncoder!=NULL) { - inputDataDelay = hAacConfig->sbrRatio*inputDataDelay + sbrEncoder_GetInputDataDelay(*hSbrEncoder); - } + if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) { + int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength); - if ( FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, - ((InitFlags&AACENC_INIT_STATES) ? 1 : 0), - config->userMetaDataMode, - inputDataDelay, - frameLength, - config->userSamplerate, - config->nChannels, - config->userChannelMode, - hAacConfig->channelOrder) != 0) - { - return AACENC_INIT_META_ERROR; - } + if (isSbrActive(hAacConfig)) { + coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay + + sbrEncoder_GetInputDataDelay(*hSbrEncoder); + } - hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc); + if (MPS_ENCODER_OK != + FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType, + config->userSamplerate, hAacConfig->bitRate, + isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0, + frameLength, /* for dual rate sbr this value is + already multiplied by 2 */ + hAacEncoder->inputBufferSizePerChannel, + coreCoderDelay)) { + return AACENC_INIT_MPS_ERROR; } + } + hAacEncoder->nDelay = + fMax(FDK_MpegsEnc_GetDelay(hAacEncoder->hMpsEnc), hAacEncoder->nDelay); - /* - * Update pointer to working buffer. - */ - if ( (InitFlags & AACENC_INIT_CONFIG) ) - { - hAacEncoder->inputBufferOffset = aacBufferOffset; + /* + * Initialize Transport - Module. + */ + if ((InitFlags & AACENC_INIT_TRANSPORT)) { + UINT flags = 0; - hAacEncoder->nSamplesToRead = frameLength * config->nChannels; + FDKaacEnc_MapConfig( + &hAacEncoder->coderConfig, config, + getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, + config->userTpSignaling, hAacConfig->sbrRatio), + hAacConfig); - /* Make nDelay comparison compatible with config->nSamplesRead */ - hAacEncoder->nDelay *= config->nChannels; + /* create flags for transport encoder */ + if (config->userTpAmxv != 0) { + flags |= TP_FLAG_LATM_AMV; + } + /* Clear output buffer */ + FDKmemclear(hAacEncoder->outBuffer, + hAacEncoder->outBufferInBytes * sizeof(UCHAR)); + + /* Initialize Bitstream encoder */ + if (transportEnc_Init(hAacEncoder->hTpEnc, hAacEncoder->outBuffer, + hAacEncoder->outBufferInBytes, config->userTpType, + &hAacEncoder->coderConfig, flags) != 0) { + return AACENC_INIT_TP_ERROR; + } - } /* parameter changed */ + } /* transport initialization */ - return AACENC_OK; -} + /* + * Initialize AAC - Core. + */ + if ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES)) { + if (FDKaacEnc_Initialize( + hAacEncoder->hAacEnc, hAacConfig, hAacEncoder->hTpEnc, + (InitFlags & AACENC_INIT_STATES) ? 1 : 0) != AAC_ENC_OK) { + return AACENC_INIT_AAC_ERROR; + } + } /* aac initialization */ -AACENC_ERROR aacEncOpen( - HANDLE_AACENCODER *phAacEncoder, - const UINT encModules, - const UINT maxChannels - ) -{ - AACENC_ERROR err = AACENC_OK; - HANDLE_AACENCODER hAacEncoder = NULL; + /* + * Initialize Meta Data - Encoder. + */ + if (hAacEncoder->hMetadataEnc && (hAacEncoder->metaDataAllowed != 0) && + ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { + INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); - if (phAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; + if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { + inputDataDelay = hAacConfig->sbrRatio * inputDataDelay + + sbrEncoder_GetInputDataDelay(*hSbrEncoder); } - /* allocate memory */ - hAacEncoder = Get_AacEncoder(); - - if (hAacEncoder == NULL) { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, + ((InitFlags & AACENC_INIT_STATES) ? 1 : 0), + config->userMetaDataMode, inputDataDelay, + frameLength, config->userSamplerate, + config->nChannels, config->userChannelMode, + hAacConfig->channelOrder) != 0) { + return AACENC_INIT_META_ERROR; } - FDKmemclear(hAacEncoder, sizeof(AACENCODER)); + hAacEncoder->nDelay += FDK_MetadataEnc_GetDelay(hAacEncoder->hMetadataEnc); + } - /* Specify encoder modules to be allocated. */ - if (encModules==0) { - hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS; - hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META; - } - else { - /* consider SAC and PS module */ - hAacEncoder->encoder_modis = encModules; - } + /* Get custom delay, i.e. the codec delay w/o the decoder's SBR- or MPS delay + */ + if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) { + hAacEncoder->nDelayCore = + hAacEncoder->nDelay - + fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc)); + } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { + hAacEncoder->nDelayCore = + hAacEncoder->nDelay - + fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc)); + } else { + hAacEncoder->nDelayCore = hAacEncoder->nDelay; + } - /* Determine max channel configuration. */ - if (maxChannels==0) { - hAacEncoder->nMaxAacChannels = (8); - hAacEncoder->nMaxSbrChannels = (8); - } - else { - hAacEncoder->nMaxAacChannels = (maxChannels&0x00FF); - if ( (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) ) { - hAacEncoder->nMaxSbrChannels = (maxChannels&0xFF00) ? (maxChannels>>8) : hAacEncoder->nMaxAacChannels; - } + /* + * Update pointer to working buffer. + */ + if ((InitFlags & AACENC_INIT_CONFIG)) { + hAacEncoder->inputBufferOffset = aacBufferOffset; - if ( (hAacEncoder->nMaxAacChannels>(8)) || (hAacEncoder->nMaxSbrChannels>(8)) ) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - } /* maxChannels==0 */ + hAacEncoder->nSamplesToRead = frameLength * config->nChannels; - /* Max number of elements could be tuned any more. */ - hAacEncoder->nMaxAacElements = fixMin((8), hAacEncoder->nMaxAacChannels); - hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels); - hAacEncoder->nMaxSubFrames = (1); + } /* parameter changed */ + return AACENC_OK; +} - /* In case of memory overlay, allocate memory out of libraries */ +AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder, const UINT encModules, + const UINT maxChannels) { + AACENC_ERROR err = AACENC_OK; + HANDLE_AACENCODER hAacEncoder = NULL; - hAacEncoder->inputBuffer = (INT_PCM*)FDKcalloc(hAacEncoder->nMaxAacChannels*INPUTBUFFER_SIZE, sizeof(INT_PCM)); + if (phAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* Open SBR Encoder */ - if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SBR) { - if ( sbrEncoder_Open(&hAacEncoder->hEnvEnc, - hAacEncoder->nMaxSbrElements, - hAacEncoder->nMaxSbrChannels, - (hAacEncoder->encoder_modis&ENC_MODE_FLAG_PS) ? 1 : 0 ) ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } - } /* (encoder_modis&ENC_MODE_FLAG_SBR) */ + /* allocate memory */ + hAacEncoder = Get_AacEncoder(); + if (hAacEncoder == NULL) { + err = AACENC_MEMORY_ERROR; + goto bail; + } - /* Open Aac Encoder */ - if ( FDKaacEnc_Open(&hAacEncoder->hAacEnc, - hAacEncoder->nMaxAacElements, - hAacEncoder->nMaxAacChannels, - (1)) != AAC_ENC_OK ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } + FDKmemclear(hAacEncoder, sizeof(AACENCODER)); + + /* Specify encoder modules to be allocated. */ + if (encModules == 0) { + C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + LIB_INFO(*pLibInfo) + [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo; + FDKinitLibInfo(*pLibInfo); + aacEncGetLibInfo(*pLibInfo); - { /* Get bitstream outputbuffer size */ - UINT ld_M; - for (ld_M=1; (UINT)(1<<ld_M) < (hAacEncoder->nMaxSubFrames*hAacEncoder->nMaxAacChannels*6144)>>3; ld_M++) ; - hAacEncoder->outBufferInBytes = (1<<ld_M); /* buffer has to be 2^n */ + hAacEncoder->encoder_modis = ENC_MODE_FLAG_AAC; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_HQ) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SBR; } - hAacEncoder->outBuffer = GetRam_bsOutbuffer(); - if (OUTPUTBUFFER_SIZE < hAacEncoder->outBufferInBytes ) { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_SBRENC) & CAPF_SBR_PS_MPEG) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_PS; } - - /* Open Meta Data Encoder */ - if (hAacEncoder->encoder_modis&ENC_MODE_FLAG_META) { - if ( FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc) ) - { - err = AACENC_MEMORY_ERROR; - goto bail; - } - } /* (encoder_modis&ENC_MODE_FLAG_META) */ - - /* Open Transport Encoder */ - if ( transportEnc_Open(&hAacEncoder->hTpEnc) != 0 ) - { - err = AACENC_MEMORY_ERROR; - goto bail; + if (FDKlibInfo_getCapabilities(*pLibInfo, FDK_AACENC) & CAPF_AAC_DRC) { + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_META; } - else { - C_ALLOC_SCRATCH_START(pLibInfo, LIB_INFO, FDK_MODULE_LAST); + hAacEncoder->encoder_modis |= ENC_MODE_FLAG_SAC; - FDKinitLibInfo( pLibInfo); - transportEnc_GetLibInfo( pLibInfo ); - - /* Get capabilty flag for transport encoder. */ - hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities( pLibInfo, FDK_TPENC); + C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + } else { + hAacEncoder->encoder_modis = encModules; + } - C_ALLOC_SCRATCH_END(pLibInfo, LIB_INFO, FDK_MODULE_LAST); + /* Determine max channel configuration. */ + if (maxChannels == 0) { + hAacEncoder->nMaxAacChannels = (8); + hAacEncoder->nMaxSbrChannels = (8); + } else { + hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF); + if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) { + hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00) + ? (maxChannels >> 8) + : hAacEncoder->nMaxAacChannels; } - if ( transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, hAacEncoder) != 0 ) { - err = AACENC_INIT_TP_ERROR; + + if ((hAacEncoder->nMaxAacChannels > (8)) || + (hAacEncoder->nMaxSbrChannels > (8))) { + err = AACENC_INVALID_CONFIG; goto bail; } + } /* maxChannels==0 */ - /* Initialize encoder instance with default parameters. */ - aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam); + /* Max number of elements could be tuned any more. */ + hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels); + hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels); - /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */ - hAacEncoder->coderConfig.headerPeriod = hAacEncoder->extParam.userTpHeaderPeriod; + /* In case of memory overlay, allocate memory out of libraries */ - /* All encoder modules have to be initialized */ - hAacEncoder->InitFlags = AACENC_INIT_ALL; + if (hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR | ENC_MODE_FLAG_PS)) + hAacEncoder->inputBufferSizePerChannel = INPUTBUFFER_SIZE; + else + hAacEncoder->inputBufferSizePerChannel = (1024); - /* Return encoder instance */ - *phAacEncoder = hAacEncoder; + hAacEncoder->inputBufferSize = + hAacEncoder->nMaxAacChannels * hAacEncoder->inputBufferSizePerChannel; - return err; + if (NULL == (hAacEncoder->inputBuffer = (INT_PCM *)FDKcalloc( + hAacEncoder->inputBufferSize, sizeof(INT_PCM)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } -bail: - aacEncClose(&hAacEncoder); + /* Open SBR Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) { + if (sbrEncoder_Open( + &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements, + hAacEncoder->nMaxSbrChannels, + (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) { + err = AACENC_MEMORY_ERROR; + goto bail; + } - return err; -} + if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc( + 1, sizeof(SBRENC_EXT_PAYLOAD)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + } /* (encoder_modis&ENC_MODE_FLAG_SBR) */ + /* Open Aac Encoder */ + if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements, + hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + /* Bitstream output buffer */ + hAacEncoder->outBufferInBytes = + 1 << (DFRACT_BITS - CntLeadingZeros(fixMax( + 1, ((1) * hAacEncoder->nMaxAacChannels * 6144) >> + 3))); /* buffer has to be 2^n */ + if (NULL == (hAacEncoder->outBuffer = (UCHAR *)FDKcalloc( + hAacEncoder->outBufferInBytes, sizeof(UCHAR)))) { + err = AACENC_MEMORY_ERROR; + goto bail; + } -AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) -{ - AACENC_ERROR err = AACENC_OK; + /* Open Meta Data Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_META) { + if (FDK_MetadataEnc_Open(&hAacEncoder->hMetadataEnc, + (UINT)hAacEncoder->nMaxAacChannels)) { + err = AACENC_MEMORY_ERROR; + goto bail; + } + } /* (encoder_modis&ENC_MODE_FLAG_META) */ - if (phAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; + /* Open MPEG Surround Encoder */ + if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SAC) { + if (MPS_ENCODER_OK != FDK_MpegsEnc_Open(&hAacEncoder->hMpsEnc)) { + err = AACENC_MEMORY_ERROR; + goto bail; } + } /* (hAacEncoder->encoder_modis&ENC_MODE_FLAG_SAC) */ - if (*phAacEncoder != NULL) { - HANDLE_AACENCODER hAacEncoder = *phAacEncoder; + /* Open Transport Encoder */ + if (transportEnc_Open(&hAacEncoder->hTpEnc) != 0) { + err = AACENC_MEMORY_ERROR; + goto bail; + } else { + C_ALLOC_SCRATCH_START(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + LIB_INFO(*pLibInfo) + [FDK_MODULE_LAST] = (LIB_INFO(*)[FDK_MODULE_LAST])_pLibInfo; - if (hAacEncoder->inputBuffer!=NULL) { - FDKfree(hAacEncoder->inputBuffer); - hAacEncoder->inputBuffer = NULL; - } + FDKinitLibInfo(*pLibInfo); + transportEnc_GetLibInfo(*pLibInfo); - if (hAacEncoder->outBuffer) { - FreeRam_bsOutbuffer(&hAacEncoder->outBuffer); - } + /* Get capabilty flag for transport encoder. */ + hAacEncoder->CAPF_tpEnc = FDKlibInfo_getCapabilities(*pLibInfo, FDK_TPENC); - if (hAacEncoder->hEnvEnc) { - sbrEncoder_Close (&hAacEncoder->hEnvEnc); - } - if (hAacEncoder->hAacEnc) { - FDKaacEnc_Close (&hAacEncoder->hAacEnc); - } + C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) + } + if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, + hAacEncoder) != 0) { + err = AACENC_INIT_TP_ERROR; + goto bail; + } + if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback, + hAacEncoder) != 0) { + err = AACENC_INIT_TP_ERROR; + goto bail; + } - transportEnc_Close(&hAacEncoder->hTpEnc); + /* Initialize encoder instance with default parameters. */ + aacEncDefaultConfig(&hAacEncoder->aacConfig, &hAacEncoder->extParam); - if (hAacEncoder->hMetadataEnc) { - FDK_MetadataEnc_Close (&hAacEncoder->hMetadataEnc); - } + /* Initialize headerPeriod in coderConfig for aacEncoder_GetParam(). */ + hAacEncoder->coderConfig.headerPeriod = + hAacEncoder->extParam.userTpHeaderPeriod; - Free_AacEncoder(phAacEncoder); - } + /* All encoder modules have to be initialized */ + hAacEncoder->InitFlags = AACENC_INIT_ALL; + + /* Return encoder instance */ + *phAacEncoder = hAacEncoder; + + return err; bail: - return err; -} + aacEncClose(&hAacEncoder); -AACENC_ERROR aacEncEncode( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_BufDesc *inBufDesc, - const AACENC_BufDesc *outBufDesc, - const AACENC_InArgs *inargs, - AACENC_OutArgs *outargs - ) -{ - AACENC_ERROR err = AACENC_OK; - INT i, nBsBytes = 0; - INT outBytes[(1)]; - int nExtensions = 0; - int ancDataExtIdx = -1; - - /* deal with valid encoder handle */ - if (hAacEncoder==NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; - } + return err; +} +AACENC_ERROR aacEncClose(HANDLE_AACENCODER *phAacEncoder) { + AACENC_ERROR err = AACENC_OK; - /* - * Adjust user settings and trigger reinitialization. - */ - if (hAacEncoder->InitFlags!=0) { + if (phAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - err = aacEncInit(hAacEncoder, - hAacEncoder->InitFlags, - &hAacEncoder->extParam); + if (*phAacEncoder != NULL) { + HANDLE_AACENCODER hAacEncoder = *phAacEncoder; - if (err!=AACENC_OK) { - /* keep init flags alive! */ - goto bail; - } - hAacEncoder->InitFlags = AACENC_INIT_NONE; + if (hAacEncoder->inputBuffer != NULL) { + FDKfree(hAacEncoder->inputBuffer); + hAacEncoder->inputBuffer = NULL; } - - if (outargs!=NULL) { - FDKmemclear(outargs, sizeof(AACENC_OutArgs)); + if (hAacEncoder->outBuffer != NULL) { + FDKfree(hAacEncoder->outBuffer); + hAacEncoder->outBuffer = NULL; } - if (outBufDesc!=NULL) { - for (i=0; i<outBufDesc->numBufs; i++) { - if (outBufDesc->bufs[i]!=NULL) { - FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]); - } - } + if (hAacEncoder->hEnvEnc) { + sbrEncoder_Close(&hAacEncoder->hEnvEnc); + } + if (hAacEncoder->pSbrPayload != NULL) { + FDKfree(hAacEncoder->pSbrPayload); + hAacEncoder->pSbrPayload = NULL; + } + if (hAacEncoder->hAacEnc) { + FDKaacEnc_Close(&hAacEncoder->hAacEnc); } - /* - * If only encoder handle given, independent (re)initialization can be triggered. - */ - if ( (hAacEncoder!=NULL) & (inBufDesc==NULL) && (outBufDesc==NULL) && (inargs==NULL) && (outargs==NULL) ) { - goto bail; + transportEnc_Close(&hAacEncoder->hTpEnc); + + if (hAacEncoder->hMetadataEnc) { + FDK_MetadataEnc_Close(&hAacEncoder->hMetadataEnc); + } + if (hAacEncoder->hMpsEnc) { + FDK_MpegsEnc_Close(&hAacEncoder->hMpsEnc); } - /* reset buffer wich signals number of valid bytes in output bitstream buffer */ - FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames*sizeof(INT)); + Free_AacEncoder(phAacEncoder); + } - /* - * Manage incoming audio samples. - */ - if ( (inargs->numInSamples > 0) && (getBufDescIdx(inBufDesc,IN_AUDIO_DATA) != -1) ) - { - /* Fetch data until nSamplesToRead reached */ - INT idx = getBufDescIdx(inBufDesc,IN_AUDIO_DATA); - INT newSamples = fixMax(0,fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead-hAacEncoder->nSamplesRead)); - INT_PCM *pIn = hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead; - - /* Copy new input samples to internal buffer */ - if (inBufDesc->bufElSizes[idx]==(INT)sizeof(INT_PCM)) { - FDKmemcpy(pIn, (INT_PCM*)inBufDesc->bufs[idx], newSamples*sizeof(INT_PCM)); /* Fast copy. */ - } - else if (inBufDesc->bufElSizes[idx]>(INT)sizeof(INT_PCM)) { - for (i=0; i<newSamples; i++) { - pIn[i] = (INT_PCM)(((LONG*)inBufDesc->bufs[idx])[i]>>16); /* Convert 32 to 16 bit. */ - } - } - else { - for (i=0; i<newSamples; i++) { - pIn[i] = ((INT_PCM)(((SHORT*)inBufDesc->bufs[idx])[i]))<<16; /* Convert 16 to 32 bit. */ - } - } - hAacEncoder->nSamplesRead += newSamples; +bail: + return err; +} - /* Number of fetched input buffer samples. */ - outargs->numInSamples = newSamples; - } +AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER hAacEncoder, + const AACENC_BufDesc *inBufDesc, + const AACENC_BufDesc *outBufDesc, + const AACENC_InArgs *inargs, + AACENC_OutArgs *outargs) { + AACENC_ERROR err = AACENC_OK; + INT i, nBsBytes = 0; + INT outBytes[(1)]; + int nExtensions = 0; + int ancDataExtIdx = -1; + + /* deal with valid encoder handle */ + if (hAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* input buffer completely filled ? */ - if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) - { - /* - eof reached and flushing enabled, or - - return to main and wait for further incoming audio samples */ - if (inargs->numInSamples==-1) - { - if ( (hAacEncoder->nZerosAppended < hAacEncoder->nDelay) - ) - { - int nZeros = hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead; - - FDK_ASSERT(nZeros >= 0); - - /* clear out until end-of-buffer */ - if (nZeros) { - FDKmemclear(hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset+hAacEncoder->nSamplesRead, sizeof(INT_PCM)*nZeros ); - hAacEncoder->nZerosAppended += nZeros; - hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead; - } - } - else { /* flushing completed */ - err = AACENC_ENCODE_EOF; /* eof reached */ - goto bail; - } - } - else { /* inargs->numInSamples!= -1 */ - goto bail; /* not enough samples in input buffer and no flushing enabled */ - } - } + /* + * Adjust user settings and trigger reinitialization. + */ + if (hAacEncoder->InitFlags != 0) { + err = + aacEncInit(hAacEncoder, hAacEncoder->InitFlags, &hAacEncoder->extParam); - /* init payload */ - FDKmemclear(hAacEncoder->extPayload, sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS); - for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) { - hAacEncoder->extPayload[i].associatedChElement = -1; + if (err != AACENC_OK) { + /* keep init flags alive! */ + goto bail; } - FDKmemclear(hAacEncoder->extPayloadData, sizeof(hAacEncoder->extPayloadData)); - FDKmemclear(hAacEncoder->extPayloadSize, sizeof(hAacEncoder->extPayloadSize)); + hAacEncoder->InitFlags = AACENC_INIT_NONE; + } + if (outargs != NULL) { + FDKmemclear(outargs, sizeof(AACENC_OutArgs)); + } - /* - * Calculate Meta Data info. - */ - if ( (hAacEncoder->hMetadataEnc!=NULL) && (hAacEncoder->metaDataAllowed!=0) ) { + if (outBufDesc != NULL) { + for (i = 0; i < outBufDesc->numBufs; i++) { + if (outBufDesc->bufs[i] != NULL) { + FDKmemclear(outBufDesc->bufs[i], outBufDesc->bufSizes[i]); + } + } + } - const AACENC_MetaData *pMetaData = NULL; - AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL; - UINT nMetaDataExtensions = 0; - INT matrix_mixdown_idx = 0; + /* + * If only encoder handle given, independent (re)initialization can be + * triggered. + */ + if ((inBufDesc == NULL) && (outBufDesc == NULL) && (inargs == NULL) && + (outargs == NULL)) { + goto bail; + } - /* New meta data info available ? */ - if ( getBufDescIdx(inBufDesc,IN_METADATA_SETUP) != -1 ) { - pMetaData = (AACENC_MetaData*)inBufDesc->bufs[getBufDescIdx(inBufDesc,IN_METADATA_SETUP)]; - } + /* check if buffer descriptors are filled out properly. */ + if ((AACENC_OK != validateBufDesc(inBufDesc)) || + (AACENC_OK != validateBufDesc(outBufDesc)) || (inargs == NULL) || + (outargs == NULL)) { + err = AACENC_UNSUPPORTED_PARAMETER; + goto bail; + } - FDK_MetadataEnc_Process(hAacEncoder->hMetadataEnc, - hAacEncoder->inputBuffer+hAacEncoder->inputBufferOffset, - hAacEncoder->nSamplesRead, - pMetaData, - &pMetaDataExtPayload, - &nMetaDataExtensions, - &matrix_mixdown_idx - ); - - for (i=0; i<(INT)nMetaDataExtensions; i++) { /* Get meta data extension payload. */ - hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i]; - } + /* reset buffer wich signals number of valid bytes in output bitstream buffer + */ + FDKmemclear(outBytes, hAacEncoder->aacConfig.nSubFrames * sizeof(INT)); + + /* + * Manage incoming audio samples. + */ + if ((inBufDesc != NULL) && (inargs->numInSamples > 0) && + (getBufDescIdx(inBufDesc, IN_AUDIO_DATA) != -1)) { + /* Fetch data until nSamplesToRead reached */ + INT idx = getBufDescIdx(inBufDesc, IN_AUDIO_DATA); + INT newSamples = + fixMax(0, fixMin(inargs->numInSamples, hAacEncoder->nSamplesToRead - + hAacEncoder->nSamplesRead)); + INT_PCM *pIn = + hAacEncoder->inputBuffer + + (hAacEncoder->inputBufferOffset + hAacEncoder->nSamplesRead) / + hAacEncoder->aacConfig.nChannels; + + /* Copy new input samples to internal buffer */ + if (inBufDesc->bufElSizes[idx] == (INT)sizeof(INT_PCM)) { + FDK_deinterleave((INT_PCM *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } else if (inBufDesc->bufElSizes[idx] > (INT)sizeof(INT_PCM)) { + FDK_deinterleave((LONG *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } else { + FDK_deinterleave((SHORT *)inBufDesc->bufs[idx], pIn, + hAacEncoder->extParam.nChannels, + newSamples / hAacEncoder->extParam.nChannels, + hAacEncoder->inputBufferSizePerChannel); + } + hAacEncoder->nSamplesRead += newSamples; + + /* Number of fetched input buffer samples. */ + outargs->numInSamples = newSamples; + } - if ( (matrix_mixdown_idx!=-1) - && ((hAacEncoder->extParam.userChannelMode==MODE_1_2_2)||(hAacEncoder->extParam.userChannelMode==MODE_1_2_2_1)) ) - { - /* Set matrix mixdown coefficient. */ - UINT pceValue = (UINT)( (0<<3) | ((matrix_mixdown_idx&0x3)<<1) | 1 ); - if (hAacEncoder->extParam.userPceAdditions != pceValue) { - hAacEncoder->extParam.userPceAdditions = pceValue; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + /* input buffer completely filled ? */ + if (hAacEncoder->nSamplesRead < hAacEncoder->nSamplesToRead) { + /* - eof reached and flushing enabled, or + - return to main and wait for further incoming audio samples */ + if (inargs->numInSamples == -1) { + if ((hAacEncoder->nZerosAppended < hAacEncoder->nDelay)) { + int nZeros = (hAacEncoder->nSamplesToRead - hAacEncoder->nSamplesRead) / + hAacEncoder->extParam.nChannels; + + FDK_ASSERT(nZeros >= 0); + + /* clear out until end-of-buffer */ + if (nZeros) { + for (i = 0; i < (int)hAacEncoder->extParam.nChannels; i++) { + FDKmemclear(hAacEncoder->inputBuffer + + i * hAacEncoder->inputBufferSizePerChannel + + (hAacEncoder->inputBufferOffset + + hAacEncoder->nSamplesRead) / + hAacEncoder->extParam.nChannels, + sizeof(INT_PCM) * nZeros); } + hAacEncoder->nZerosAppended += nZeros; + hAacEncoder->nSamplesRead = hAacEncoder->nSamplesToRead; } + } else { /* flushing completed */ + err = AACENC_ENCODE_EOF; /* eof reached */ + goto bail; + } + } else { /* inargs->numInSamples!= -1 */ + goto bail; /* not enough samples in input buffer and no flushing enabled + */ } + } + /* init payload */ + FDKmemclear(hAacEncoder->extPayload, + sizeof(AACENC_EXT_PAYLOAD) * MAX_TOTAL_EXT_PAYLOADS); + for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) { + hAacEncoder->extPayload[i].associatedChElement = -1; + } + if (hAacEncoder->pSbrPayload != NULL) { + FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload)); + } - if ( isSbrActive(&hAacEncoder->aacConfig) ) { - - INT nPayload = 0; - - /* - * Encode SBR data. - */ - if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, - hAacEncoder->inputBuffer, - hAacEncoder->extParam.nChannels, - hAacEncoder->extPayloadSize[nPayload], - hAacEncoder->extPayloadData[nPayload] -#if defined(EVAL_PACKAGE_SILENCE) || defined(EVAL_PACKAGE_SBR_SILENCE) - ,hAacEncoder->hAacEnc->clearOutput -#endif - )) - { - err = AACENC_ENCODE_ERROR; - goto bail; - } - else { - /* Add SBR extension payload */ - for (i = 0; i < (8); i++) { - if (hAacEncoder->extPayloadSize[nPayload][i] > 0) { - hAacEncoder->extPayload[nExtensions].pData = hAacEncoder->extPayloadData[nPayload][i]; - { - hAacEncoder->extPayload[nExtensions].dataSize = hAacEncoder->extPayloadSize[nPayload][i]; - hAacEncoder->extPayload[nExtensions].associatedChElement = i; - } - hAacEncoder->extPayload[nExtensions].dataType = EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set EXT_SBR_DATA_CRC */ - nExtensions++; /* or EXT_SBR_DATA according to configuration. */ - FDK_ASSERT(nExtensions<=MAX_TOTAL_EXT_PAYLOADS); - } - } - nPayload++; - } - } /* sbrEnabled */ - - if ( (inargs->numAncBytes > 0) && ( getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA)!=-1 ) ) { - INT idx = getBufDescIdx(inBufDesc,IN_ANCILLRY_DATA); - hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8; - hAacEncoder->extPayload[nExtensions].pData = (UCHAR*)inBufDesc->bufs[idx]; - hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT; - hAacEncoder->extPayload[nExtensions].associatedChElement = -1; - ancDataExtIdx = nExtensions; /* store index */ - nExtensions++; + /* + * Calculate Meta Data info. + */ + if ((hAacEncoder->hMetadataEnc != NULL) && + (hAacEncoder->metaDataAllowed != 0)) { + const AACENC_MetaData *pMetaData = NULL; + AACENC_EXT_PAYLOAD *pMetaDataExtPayload = NULL; + UINT nMetaDataExtensions = 0; + INT matrix_mixdown_idx = 0; + + /* New meta data info available ? */ + if (getBufDescIdx(inBufDesc, IN_METADATA_SETUP) != -1) { + pMetaData = + (AACENC_MetaData *) + inBufDesc->bufs[getBufDescIdx(inBufDesc, IN_METADATA_SETUP)]; + } + + FDK_MetadataEnc_Process( + hAacEncoder->hMetadataEnc, + hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset / + hAacEncoder->coderConfig.noChannels, + hAacEncoder->inputBufferSizePerChannel, hAacEncoder->nSamplesRead, + pMetaData, &pMetaDataExtPayload, &nMetaDataExtensions, + &matrix_mixdown_idx); + + for (i = 0; i < (INT)nMetaDataExtensions; + i++) { /* Get meta data extension payload. */ + hAacEncoder->extPayload[nExtensions++] = pMetaDataExtPayload[i]; + } + + if ((matrix_mixdown_idx != -1) && + ((hAacEncoder->extParam.userChannelMode == MODE_1_2_2) || + (hAacEncoder->extParam.userChannelMode == MODE_1_2_2_1))) { + /* Set matrix mixdown coefficient. */ + UINT pceValue = (UINT)((0 << 3) | ((matrix_mixdown_idx & 0x3) << 1) | 1); + if (hAacEncoder->extParam.userPceAdditions != pceValue) { + hAacEncoder->extParam.userPceAdditions = pceValue; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } } + } - /* - * Encode AAC - Core. - */ - if ( FDKaacEnc_EncodeFrame( hAacEncoder->hAacEnc, - hAacEncoder->hTpEnc, - hAacEncoder->inputBuffer, - outBytes, - hAacEncoder->extPayload - ) != AAC_ENC_OK ) - { - err = AACENC_ENCODE_ERROR; - goto bail; + /* + * Encode MPS data. + */ + if ((hAacEncoder->hMpsEnc != NULL) && + (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) { + AACENC_EXT_PAYLOAD mpsExtensionPayload; + FDKmemclear(&mpsExtensionPayload, sizeof(AACENC_EXT_PAYLOAD)); + + if (MPS_ENCODER_OK != + FDK_MpegsEnc_Process( + hAacEncoder->hMpsEnc, + hAacEncoder->inputBuffer + hAacEncoder->inputBufferOffset / + hAacEncoder->coderConfig.noChannels, + hAacEncoder->nSamplesRead, &mpsExtensionPayload)) { + err = AACENC_ENCODE_ERROR; + goto bail; } - if (ancDataExtIdx >= 0) { - outargs->numAncBytes = inargs->numAncBytes - (hAacEncoder->extPayload[ancDataExtIdx].dataSize>>3); + if ((mpsExtensionPayload.pData != NULL) && + ((mpsExtensionPayload.dataSize != 0))) { + hAacEncoder->extPayload[nExtensions++] = mpsExtensionPayload; } + } - /* samples exhausted */ - hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead; + if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) && + isSbrActive(&hAacEncoder->aacConfig)) { + INT nPayload = 0; /* - * Delay balancing buffer handling + * Encode SBR data. */ - if (isSbrActive(&hAacEncoder->aacConfig)) { - sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer); - } + if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel, + hAacEncoder->pSbrPayload->dataSize[nPayload], + hAacEncoder->pSbrPayload->data[nPayload])) { + err = AACENC_ENCODE_ERROR; + goto bail; + } else { + /* Add SBR extension payload */ + for (i = 0; i < (8); i++) { + if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) { + hAacEncoder->extPayload[nExtensions].pData = + hAacEncoder->pSbrPayload->data[nPayload][i]; + { + hAacEncoder->extPayload[nExtensions].dataSize = + hAacEncoder->pSbrPayload->dataSize[nPayload][i]; + hAacEncoder->extPayload[nExtensions].associatedChElement = i; + } + hAacEncoder->extPayload[nExtensions].dataType = + EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set + EXT_SBR_DATA_CRC */ + nExtensions++; /* or EXT_SBR_DATA according to configuration. */ + FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS); + } + } + nPayload++; + } + } /* sbrEnabled */ + + if ((inargs->numAncBytes > 0) && + (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) { + INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA); + hAacEncoder->extPayload[nExtensions].dataSize = inargs->numAncBytes * 8; + hAacEncoder->extPayload[nExtensions].pData = (UCHAR *)inBufDesc->bufs[idx]; + hAacEncoder->extPayload[nExtensions].dataType = EXT_DATA_ELEMENT; + hAacEncoder->extPayload[nExtensions].associatedChElement = -1; + ancDataExtIdx = nExtensions; /* store index */ + nExtensions++; + } - /* - * Make bitstream public - */ - if (outBufDesc->numBufs>=1) { + /* + * Encode AAC - Core. + */ + if (FDKaacEnc_EncodeFrame(hAacEncoder->hAacEnc, hAacEncoder->hTpEnc, + hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel, outBytes, + hAacEncoder->extPayload) != AAC_ENC_OK) { + err = AACENC_ENCODE_ERROR; + goto bail; + } - INT bsIdx = getBufDescIdx(outBufDesc,OUT_BITSTREAM_DATA); - INT auIdx = getBufDescIdx(outBufDesc,OUT_AU_SIZES); + if (ancDataExtIdx >= 0) { + outargs->numAncBytes = + inargs->numAncBytes - + (hAacEncoder->extPayload[ancDataExtIdx].dataSize >> 3); + } - for (i=0,nBsBytes=0; i<hAacEncoder->aacConfig.nSubFrames; i++) { - nBsBytes += outBytes[i]; + /* samples exhausted */ + hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead; - if (auIdx!=-1) { - ((INT*)outBufDesc->bufs[auIdx])[i] = outBytes[i]; - } - } + /* + * Delay balancing buffer handling + */ + if (isSbrActive(&hAacEncoder->aacConfig)) { + sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, + hAacEncoder->inputBufferSizePerChannel); + } - if ( (bsIdx!=-1) && (outBufDesc->bufSizes[bsIdx]>=nBsBytes) ) { - FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer, sizeof(UCHAR)*nBsBytes); - outargs->numOutBytes = nBsBytes; - } - else { - /* output buffer too small, can't write valid bitstream */ - err = AACENC_ENCODE_ERROR; - goto bail; - } + /* + * Make bitstream public + */ + if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) { + INT bsIdx = getBufDescIdx(outBufDesc, OUT_BITSTREAM_DATA); + INT auIdx = getBufDescIdx(outBufDesc, OUT_AU_SIZES); + + for (i = 0, nBsBytes = 0; i < hAacEncoder->aacConfig.nSubFrames; i++) { + nBsBytes += outBytes[i]; + + if (auIdx != -1) { + ((INT *)outBufDesc->bufs[auIdx])[i] = outBytes[i]; + } } -bail: - if (err == AACENC_ENCODE_ERROR) { - /* All encoder modules have to be initialized */ - hAacEncoder->InitFlags = AACENC_INIT_ALL; + if ((bsIdx != -1) && (outBufDesc->bufSizes[bsIdx] >= nBsBytes)) { + FDKmemcpy(outBufDesc->bufs[bsIdx], hAacEncoder->outBuffer, + sizeof(UCHAR) * nBsBytes); + outargs->numOutBytes = nBsBytes; + outargs->bitResState = + FDKaacEnc_GetBitReservoirState(hAacEncoder->hAacEnc); + } else { + /* output buffer too small, can't write valid bitstream */ + err = AACENC_ENCODE_ERROR; + goto bail; } + } + +bail: + if (err == AACENC_ENCODE_ERROR) { + /* All encoder modules have to be initialized */ + hAacEncoder->InitFlags = AACENC_INIT_ALL; + } - return err; + return err; } -static -AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder, - UINT *size, - UCHAR *confBuffer) -{ - FDK_BITSTREAM tmpConf; - UINT confType; - UCHAR buf[64]; - int err; +static AAC_ENCODER_ERROR aacEncGetConf(HANDLE_AACENCODER hAacEncoder, + UINT *size, UCHAR *confBuffer) { + FDK_BITSTREAM tmpConf; + UINT confType; + UCHAR buf[64]; + int err; - /* Init bit buffer */ - FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER); + /* Init bit buffer */ + FDKinitBitStream(&tmpConf, buf, 64, 0, BS_WRITER); - /* write conf in tmp buffer */ - err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig, &tmpConf, &confType); + /* write conf in tmp buffer */ + err = transportEnc_GetConf(hAacEncoder->hTpEnc, &hAacEncoder->coderConfig, + &tmpConf, &confType); - /* copy data to outbuffer: length in bytes */ - FDKbyteAlign(&tmpConf, 0); + /* copy data to outbuffer: length in bytes */ + FDKbyteAlign(&tmpConf, 0); - /* Check buffer size */ - if (FDKgetValidBits(&tmpConf) > ((*size)<<3)) - return AAC_ENC_UNKNOWN; + /* Check buffer size */ + if (FDKgetValidBits(&tmpConf) > ((*size) << 3)) return AAC_ENC_UNKNOWN; - FDKfetchBuffer(&tmpConf, confBuffer, size); + FDKfetchBuffer(&tmpConf, confBuffer, size); - if (err != 0) - return AAC_ENC_UNKNOWN; - else - return AAC_ENC_OK; + if (err != 0) + return AAC_ENC_UNKNOWN; + else + return AAC_ENC_OK; } - -AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) -{ +AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) { int i = 0; if (info == NULL) { return AACENC_INVALID_HANDLE; } - FDK_toolsGetLibInfo( info ); - transportEnc_GetLibInfo( info ); - - sbrEncoder_GetLibInfo( info ); + FDK_toolsGetLibInfo(info); + transportEnc_GetLibInfo(info); + sbrEncoder_GetLibInfo(info); + FDK_MpegsEnc_GetLibInfo(info); /* search for next free tab */ for (i = 0; i < FDK_MODULE_LAST; i++) { @@ -1735,405 +2052,451 @@ AACENC_ERROR aacEncGetLibInfo(LIB_INFO *info) } info[i].module_id = FDK_AACENC; - info[i].build_date = (char*)AACENCODER_LIB_BUILD_DATE; - info[i].build_time = (char*)AACENCODER_LIB_BUILD_TIME; - info[i].title = (char*)AACENCODER_LIB_TITLE; - info[i].version = LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2);; + info[i].build_date = AACENCODER_LIB_BUILD_DATE; + info[i].build_time = AACENCODER_LIB_BUILD_TIME; + info[i].title = AACENCODER_LIB_TITLE; + info[i].version = + LIB_VERSION(AACENCODER_LIB_VL0, AACENCODER_LIB_VL1, AACENCODER_LIB_VL2); + ; LIB_VERSION_STRING(&info[i]); /* Capability flags */ - info[i].flags = 0 - | CAPF_AAC_1024 | CAPF_AAC_LC - | CAPF_AAC_512 - | CAPF_AAC_480 - | CAPF_AAC_DRC - ; + info[i].flags = 0 | CAPF_AAC_1024 | CAPF_AAC_LC | CAPF_AAC_512 | + CAPF_AAC_480 | CAPF_AAC_DRC | CAPF_AAC_ELD_DOWNSCALE; /* End of flags */ return AACENC_OK; } -AACENC_ERROR aacEncoder_SetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param, - const UINT value - ) -{ - AACENC_ERROR err = AACENC_OK; - USER_PARAM *settings = &hAacEncoder->extParam; +AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param, const UINT value) { + AACENC_ERROR err = AACENC_OK; + USER_PARAM *settings = &hAacEncoder->extParam; - /* check encoder handle */ - if (hAacEncoder == NULL) { - err = AACENC_INVALID_HANDLE; - goto bail; - } + /* check encoder handle */ + if (hAacEncoder == NULL) { + err = AACENC_INVALID_HANDLE; + goto bail; + } - /* apply param value */ - switch (param) - { + /* apply param value */ + switch (param) { case AACENC_AOT: - if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) { - /* check if AOT matches the allocated modules */ - switch ( value ) { - case AOT_PS: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - case AOT_SBR: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - case AOT_AAC_LC: - case AOT_ER_AAC_LD: - case AOT_ER_AAC_ELD: - if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { - err = AACENC_INVALID_CONFIG; - goto bail; - } - break; - default: - err = AACENC_INVALID_CONFIG; - goto bail; - }/* switch value */ - settings->userAOT = (AUDIO_OBJECT_TYPE)value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userAOT != (AUDIO_OBJECT_TYPE)value) { + /* check if AOT matches the allocated modules */ + switch (value) { + case AOT_PS: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_PS))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + case AOT_SBR: + case AOT_MP2_SBR: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_SBR))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + case AOT_AAC_LC: + case AOT_MP2_AAC_LC: + case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: + if (!(hAacEncoder->encoder_modis & (ENC_MODE_FLAG_AAC))) { + err = AACENC_INVALID_CONFIG; + goto bail; + } + break; + default: + err = AACENC_INVALID_CONFIG; + goto bail; + } /* switch value */ + settings->userAOT = (AUDIO_OBJECT_TYPE)value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_BITRATE: - if (settings->userBitrate != value) { - settings->userBitrate = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userBitrate != value) { + settings->userBitrate = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + } + break; case AACENC_BITRATEMODE: - if (settings->userBitrateMode != value) { - switch ( value ) { - case 0: - case 1: case 2: case 3: case 4: case 5: - case 8: - settings->userBitrateMode = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - break; - default: - err = AACENC_INVALID_CONFIG; - break; - } /* switch value */ - } - break; + if (settings->userBitrateMode != value) { + switch (value) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + settings->userBitrateMode = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + break; + default: + err = AACENC_INVALID_CONFIG; + break; + } /* switch value */ + } + break; case AACENC_SAMPLERATE: - if (settings->userSamplerate != value) { - if ( !( (value==8000) || (value==11025) || (value==12000) || (value==16000) || (value==22050) || (value==24000) || - (value==32000) || (value==44100) || (value==48000) || (value==64000) || (value==88200) || (value==96000) ) ) - { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userSamplerate = value; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (settings->userSamplerate != value) { + if (!((value == 8000) || (value == 11025) || (value == 12000) || + (value == 16000) || (value == 22050) || (value == 24000) || + (value == 32000) || (value == 44100) || (value == 48000) || + (value == 64000) || (value == 88200) || (value == 96000))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userSamplerate = value; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_CHANNELMODE: - if (settings->userChannelMode != (CHANNEL_MODE)value) { - const CHANNEL_MODE_CONFIG_TAB* pConfig = FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value); - if (pConfig==NULL) { - err = AACENC_INVALID_CONFIG; - break; - } - if ( (pConfig->nElements > hAacEncoder->nMaxAacElements) - || (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels) - || !(((value>=1) && (value<=7))||((value>=33) && (value<=34))) - ) - { - err = AACENC_INVALID_CONFIG; - break; - } + if (settings->userChannelMode != (CHANNEL_MODE)value) { + if (((CHANNEL_MODE)value == MODE_212) && + (NULL != hAacEncoder->hMpsEnc)) { + settings->userChannelMode = (CHANNEL_MODE)value; + settings->nChannels = 2; + } else { + const CHANNEL_MODE_CONFIG_TAB *pConfig = + FDKaacEnc_GetChannelModeConfiguration((CHANNEL_MODE)value); + if (pConfig == NULL) { + err = AACENC_INVALID_CONFIG; + break; + } + if ((pConfig->nElements > hAacEncoder->nMaxAacElements) || + (pConfig->nChannelsEff > hAacEncoder->nMaxAacChannels)) { + err = AACENC_INVALID_CONFIG; + break; + } - settings->userChannelMode = (CHANNEL_MODE)value; - settings->nChannels = pConfig->nChannels; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + settings->userChannelMode = (CHANNEL_MODE)value; + settings->nChannels = pConfig->nChannels; } - break; - case AACENC_BANDWIDTH: - if (settings->userBandwidth != value) { - settings->userBandwidth = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + if (!((value >= 1) && (value <= 6))) { + hAacEncoder->InitFlags |= AACENC_INIT_STATES; } - break; + } + break; + case AACENC_BANDWIDTH: + if (settings->userBandwidth != value) { + settings->userBandwidth = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_CHANNELORDER: - if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) { - if (! ((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value; - hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (hAacEncoder->aacConfig.channelOrder != (CHANNEL_ORDER)value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + hAacEncoder->aacConfig.channelOrder = (CHANNEL_ORDER)value; + hAacEncoder->nSamplesRead = 0; /* reset internal inputbuffer */ + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_AFTERBURNER: - if (settings->userAfterburner != value) { - if (! ((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userAfterburner = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + if (settings->userAfterburner != value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userAfterburner = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_GRANULE_LENGTH: - if (settings->userFramelength != value) { - switch (value) { - case 1024: - case 512: - case 480: - settings->userFramelength = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - break; - default: - err = AACENC_INVALID_CONFIG; - break; - } + if (settings->userFramelength != value) { + switch (value) { + case 1024: + case 512: + case 480: + case 256: + case 240: + case 128: + case 120: + if ((value << 1) == 480 || (value << 1) == 512) { + settings->userDownscaleFactor = 2; + } else if ((value << 2) == 480 || (value << 2) == 512) { + settings->userDownscaleFactor = 4; + } + settings->userFramelength = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + break; + default: + err = AACENC_INVALID_CONFIG; + break; } - break; + } + break; case AACENC_SBR_RATIO: - if (settings->userSbrRatio != value) { - if (! ((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userSbrRatio = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + if (settings->userSbrRatio != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userSbrRatio = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_SBR_MODE: - if (settings->userSbrEnabled != value) { - settings->userSbrEnabled = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } - break; + if ((settings->userSbrEnabled != value) && + (NULL != hAacEncoder->hEnvEnc)) { + settings->userSbrEnabled = value; + hAacEncoder->InitFlags |= + AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; + } + break; case AACENC_TRANSMUX: - if (settings->userTpType != (TRANSPORT_TYPE)value) { - - TRANSPORT_TYPE type = (TRANSPORT_TYPE)value; - UINT flags = hAacEncoder->CAPF_tpEnc; - - if ( !( ((type==TT_MP4_ADIF) && (flags&CAPF_ADIF)) - || ((type==TT_MP4_ADTS) && (flags&CAPF_ADTS)) - || ((type==TT_MP4_LATM_MCP0) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS))) - || ((type==TT_MP4_LATM_MCP1) && ((flags&CAPF_LATM) && (flags&CAPF_RAWPACKETS))) - || ((type==TT_MP4_LOAS) && (flags&CAPF_LOAS)) - || ((type==TT_MP4_RAW) && (flags&CAPF_RAWPACKETS)) - ) ) - { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpType = (TRANSPORT_TYPE)value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpType != (TRANSPORT_TYPE)value) { + TRANSPORT_TYPE type = (TRANSPORT_TYPE)value; + UINT flags = hAacEncoder->CAPF_tpEnc; + + if (!(((type == TT_MP4_ADIF) && (flags & CAPF_ADIF)) || + ((type == TT_MP4_ADTS) && (flags & CAPF_ADTS)) || + ((type == TT_MP4_LATM_MCP0) && + ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) || + ((type == TT_MP4_LATM_MCP1) && + ((flags & CAPF_LATM) && (flags & CAPF_RAWPACKETS))) || + ((type == TT_MP4_LOAS) && (flags & CAPF_LOAS)) || + ((type == TT_MP4_RAW) && (flags & CAPF_RAWPACKETS)))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpType = (TRANSPORT_TYPE)value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_SIGNALING_MODE: - if (settings->userTpSignaling != value) { - if ( !((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpSignaling = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpSignaling != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpSignaling = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_PROTECTION: - if (settings->userTpProtection != value) { - if ( !((value==0) || (value==1)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpProtection = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpProtection != value) { + if (!((value == 0) || (value == 1))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpProtection = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_HEADER_PERIOD: - if (settings->userTpHeaderPeriod != value) { - settings->userTpHeaderPeriod = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpHeaderPeriod != value) { + if (!(((INT)value >= 0) && (value <= 255))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpHeaderPeriod = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_AUDIOMUXVER: - if (settings->userTpAmxv != value) { - if ( !((value==0) || (value==1) || (value==2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpAmxv = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpAmxv != value) { + if (!((value == 0) || (value == 1) || (value == 2))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpAmxv = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_TPSUBFRAMES: - if (settings->userTpNsubFrames != value) { - if (! ( (value>=1) && (value<=4) ) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userTpNsubFrames = value; - hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + if (settings->userTpNsubFrames != value) { + if (!((value >= 1) && (value <= 4))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userTpNsubFrames = value; + hAacEncoder->InitFlags |= AACENC_INIT_TRANSPORT; + } + break; case AACENC_ANCILLARY_BITRATE: - if (settings->userAncDataRate != value) { - settings->userAncDataRate = value; - } - break; + if (settings->userAncDataRate != value) { + settings->userAncDataRate = value; + } + break; case AACENC_CONTROL_STATE: - if (hAacEncoder->InitFlags != value) { - if (value&AACENC_RESET_INBUFFER) { - hAacEncoder->nSamplesRead = 0; - } - hAacEncoder->InitFlags = value; + if (hAacEncoder->InitFlags != value) { + if (value & AACENC_RESET_INBUFFER) { + hAacEncoder->nSamplesRead = 0; } - break; + hAacEncoder->InitFlags = value; + } + break; case AACENC_METADATA_MODE: - if ((UINT)settings->userMetaDataMode != value) { - if ( !(((INT)value>=0) && ((INT)value<=2)) ) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userMetaDataMode = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + if ((UINT)settings->userMetaDataMode != value) { + if (!(((INT)value >= 0) && ((INT)value <= 3))) { + err = AACENC_INVALID_CONFIG; + break; } - break; + settings->userMetaDataMode = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG; + } + break; case AACENC_PEAK_BITRATE: - if (settings->userPeakBitrate != value) { - settings->userPeakBitrate = value; - hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; - } - break; + if (settings->userPeakBitrate != value) { + settings->userPeakBitrate = value; + hAacEncoder->InitFlags |= AACENC_INIT_CONFIG | AACENC_INIT_TRANSPORT; + } + break; default: err = AACENC_UNSUPPORTED_PARAMETER; break; - } /* switch(param) */ + } /* switch(param) */ bail: - return err; + return err; } -UINT aacEncoder_GetParam( - const HANDLE_AACENCODER hAacEncoder, - const AACENC_PARAM param - ) -{ - UINT value = 0; - USER_PARAM *settings = &hAacEncoder->extParam; +UINT aacEncoder_GetParam(const HANDLE_AACENCODER hAacEncoder, + const AACENC_PARAM param) { + UINT value = 0; + USER_PARAM *settings = &hAacEncoder->extParam; - /* check encoder handle */ - if (hAacEncoder == NULL) { - goto bail; - } + /* check encoder handle */ + if (hAacEncoder == NULL) { + goto bail; + } - /* apply param value */ - switch (param) - { + /* apply param value */ + switch (param) { case AACENC_AOT: - value = (UINT)hAacEncoder->aacConfig.audioObjectType; - break; + value = (UINT)hAacEncoder->aacConfig.audioObjectType; + break; case AACENC_BITRATE: - value = (UINT)((hAacEncoder->aacConfig.bitrateMode==AACENC_BR_MODE_CBR) ? hAacEncoder->aacConfig.bitRate : -1); - break; + switch (hAacEncoder->aacConfig.bitrateMode) { + case AACENC_BR_MODE_CBR: + value = (UINT)hAacEncoder->aacConfig.bitRate; + break; + default: + value = (UINT)-1; + } + break; case AACENC_BITRATEMODE: - value = (UINT)hAacEncoder->aacConfig.bitrateMode; - break; + value = (UINT)((hAacEncoder->aacConfig.bitrateMode != AACENC_BR_MODE_FF) + ? hAacEncoder->aacConfig.bitrateMode + : AACENC_BR_MODE_CBR); + break; case AACENC_SAMPLERATE: - value = (UINT)hAacEncoder->coderConfig.extSamplingRate; - break; + value = (UINT)hAacEncoder->coderConfig.extSamplingRate; + break; case AACENC_CHANNELMODE: + if ((MODE_1 == hAacEncoder->aacConfig.channelMode) && + (hAacEncoder->aacConfig.syntaxFlags & AC_LD_MPS)) { + value = MODE_212; + } else { value = (UINT)hAacEncoder->aacConfig.channelMode; - break; + } + break; case AACENC_BANDWIDTH: - value = (UINT)hAacEncoder->aacConfig.bandWidth; - break; + value = (UINT)hAacEncoder->aacConfig.bandWidth; + break; case AACENC_CHANNELORDER: - value = (UINT)hAacEncoder->aacConfig.channelOrder; - break; + value = (UINT)hAacEncoder->aacConfig.channelOrder; + break; case AACENC_AFTERBURNER: - value = (UINT)hAacEncoder->aacConfig.useRequant; - break; + value = (UINT)hAacEncoder->aacConfig.useRequant; + break; case AACENC_GRANULE_LENGTH: - value = (UINT)hAacEncoder->aacConfig.framelength; - break; + value = (UINT)hAacEncoder->aacConfig.framelength; + break; case AACENC_SBR_RATIO: - value = isSbrActive(&hAacEncoder->aacConfig) ? hAacEncoder->aacConfig.sbrRatio : 0; - break; + value = isSbrActive(&hAacEncoder->aacConfig) + ? hAacEncoder->aacConfig.sbrRatio + : 0; + break; case AACENC_SBR_MODE: - value = (UINT) (hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; - break; + value = + (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; + break; case AACENC_TRANSMUX: - value = (UINT)settings->userTpType; - break; + value = (UINT)settings->userTpType; + break; case AACENC_SIGNALING_MODE: - value = (UINT)getSbrSignalingMode(hAacEncoder->aacConfig.audioObjectType, settings->userTpType, settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio); - break; + value = (UINT)getSbrSignalingMode( + hAacEncoder->aacConfig.audioObjectType, settings->userTpType, + settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio); + break; case AACENC_PROTECTION: - value = (UINT)settings->userTpProtection; - break; + value = (UINT)settings->userTpProtection; + break; case AACENC_HEADER_PERIOD: - value = (UINT)hAacEncoder->coderConfig.headerPeriod; - break; + value = (UINT)hAacEncoder->coderConfig.headerPeriod; + break; case AACENC_AUDIOMUXVER: - value = (UINT)hAacEncoder->aacConfig.audioMuxVersion; - break; + value = (UINT)hAacEncoder->aacConfig.audioMuxVersion; + break; case AACENC_TPSUBFRAMES: - value = (UINT)settings->userTpNsubFrames; - break; + value = (UINT)settings->userTpNsubFrames; + break; case AACENC_ANCILLARY_BITRATE: - value = (UINT)hAacEncoder->aacConfig.anc_Rate; - break; + value = (UINT)hAacEncoder->aacConfig.anc_Rate; + break; case AACENC_CONTROL_STATE: - value = (UINT)hAacEncoder->InitFlags; - break; + value = (UINT)hAacEncoder->InitFlags; + break; case AACENC_METADATA_MODE: - value = (hAacEncoder->metaDataAllowed==0) ? 0 : (UINT)settings->userMetaDataMode; - break; + value = (hAacEncoder->metaDataAllowed == 0) + ? 0 + : (UINT)settings->userMetaDataMode; + break; case AACENC_PEAK_BITRATE: - value = (UINT)-1; /* peak bitrate parameter is meaningless */ - if ( ((INT)hAacEncoder->extParam.userPeakBitrate!=-1) ) { - value = (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, hAacEncoder->aacConfig.bitRate)); /* peak bitrate parameter is in use */ - } - break; + value = (UINT)-1; /* peak bitrate parameter is meaningless */ + if (((INT)hAacEncoder->extParam.userPeakBitrate != -1)) { + value = + (UINT)(fMax((INT)hAacEncoder->extParam.userPeakBitrate, + hAacEncoder->aacConfig + .bitRate)); /* peak bitrate parameter is in use */ + } + break; + default: - //err = MPS_INVALID_PARAMETER; + // err = MPS_INVALID_PARAMETER; break; - } /* switch(param) */ + } /* switch(param) */ bail: - return value; + return value; } -AACENC_ERROR aacEncInfo( - const HANDLE_AACENCODER hAacEncoder, - AACENC_InfoStruct *pInfo - ) -{ - AACENC_ERROR err = AACENC_OK; - - FDKmemclear(pInfo, sizeof(AACENC_InfoStruct)); - pInfo->confSize = 64; /* pre-initialize */ - - pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels*6144)+7)>>3; - pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU; - pInfo->inBufFillLevel = hAacEncoder->nSamplesRead/hAacEncoder->extParam.nChannels; - pInfo->inputChannels = hAacEncoder->extParam.nChannels; - pInfo->frameLength = hAacEncoder->nSamplesToRead/hAacEncoder->extParam.nChannels; - pInfo->encoderDelay = hAacEncoder->nDelay/hAacEncoder->extParam.nChannels; - - /* Get encoder configuration */ - if ( aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) != AAC_ENC_OK) { - err = AACENC_INIT_ERROR; - goto bail; - } +AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER hAacEncoder, + AACENC_InfoStruct *pInfo) { + AACENC_ERROR err = AACENC_OK; + + FDKmemclear(pInfo, sizeof(AACENC_InfoStruct)); + pInfo->confSize = 64; /* pre-initialize */ + + pInfo->maxOutBufBytes = ((hAacEncoder->nMaxAacChannels * 6144) + 7) >> 3; + pInfo->maxAncBytes = hAacEncoder->aacConfig.maxAncBytesPerAU; + pInfo->inBufFillLevel = + hAacEncoder->nSamplesRead / hAacEncoder->extParam.nChannels; + pInfo->inputChannels = hAacEncoder->extParam.nChannels; + pInfo->frameLength = + hAacEncoder->nSamplesToRead / hAacEncoder->extParam.nChannels; + pInfo->nDelay = hAacEncoder->nDelay; + pInfo->nDelayCore = hAacEncoder->nDelayCore; + + /* Get encoder configuration */ + if (aacEncGetConf(hAacEncoder, &pInfo->confSize, &pInfo->confBuf[0]) != + AAC_ENC_OK) { + err = AACENC_INIT_ERROR; + goto bail; + } bail: - return err; + return err; } - diff --git a/libAACenc/src/aacenc_pns.cpp b/libAACenc/src/aacenc_pns.cpp index b9640d9..f0571d6 100644 --- a/libAACenc/src/aacenc_pns.cpp +++ b/libAACenc/src/aacenc_pns.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,43 +90,37 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: pns.c + Description: pns.c -******************************************************************************/ +*******************************************************************************/ #include "aacenc_pns.h" + #include "psy_data.h" #include "pnsparam.h" #include "noisedet.h" #include "bit_cnt.h" #include "interface.h" - /* minCorrelationEnergy = (1.0e-10f)^2 ~ 2^-67 = 2^-47 * 2^-20 */ -static const FIXP_DBL minCorrelationEnergy = FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */ +static const FIXP_DBL minCorrelationEnergy = + FL2FXCONST_DBL(0.0); /* FL2FXCONST_DBL((float)FDKpow(2.0,-47)); */ /* noiseCorrelationThresh = 0.6^2 */ static const FIXP_DBL noiseCorrelationThresh = FL2FXCONST_DBL(0.36); -static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT sfbActive, - const INT *sfbOffset, - INT tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality ); - -static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, - INT *pnsFlag, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ); +static void FDKaacEnc_FDKaacEnc_noiseDetection( + PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, + const INT *sfbOffset, INT tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality); + +static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *pnsFlag, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg); /***************************************************************************** @@ -129,28 +134,15 @@ static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, - INT bitRate, - INT sampleRate, - INT usePns, - INT sfbCnt, - const INT *sfbOffset, - const INT numChan, - const INT isLC) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration( + PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt, + const INT *sfbOffset, const INT numChan, const INT isLC) { AAC_ENCODER_ERROR ErrorStatus; /* init noise detection */ - ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, - bitRate, - sampleRate, - sfbCnt, - sfbOffset, - &usePns, - numChan, - isLC); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_GetPnsParam(&pnsConf->np, bitRate, sampleRate, sfbCnt, + sfbOffset, &usePns, numChan, isLC); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; pnsConf->minCorrelationEnergy = minCorrelationEnergy; pnsConf->noiseCorrelationThresh = noiseCorrelationThresh; @@ -160,8 +152,6 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, return AAC_ENC_OK; } - - /***************************************************************************** functionname: FDKaacEnc_PnsDetect @@ -180,73 +170,55 @@ AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, output: pnsFlag in pns data structure *****************************************************************************/ -void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT lastWindowSequence, - const INT sfbActive, - const INT maxSfbPerGroup, - FIXP_DBL *sfbThresholdLdData, - const INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality, - INT tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ) +void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData, + const INT lastWindowSequence, const INT sfbActive, + const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData, + const INT *sfbOffset, FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality, + INT tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg) { int sfb; int startNoiseSfb; - if (pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) { - if ( (!pnsConf->usePns) || /* pns enabled? */ - (lastWindowSequence == SHORT_WINDOW) ) /* currently only long blocks */ - { - FDKmemclear(pnsData->pnsFlag, MAX_GROUPED_SFB*sizeof(INT)); /* clear all pnsFlags */ - for (sfb=0; sfb<MAX_GROUPED_SFB; sfb++) { - noiseNrg[sfb] = NO_NOISE_PNS; /* clear nrg's of previous frame */ - } + /* Reset pns info. */ + FDKmemclear(pnsData->pnsFlag, sizeof(pnsData->pnsFlag)); + for (sfb = 0; sfb < MAX_GROUPED_SFB; sfb++) { + noiseNrg[sfb] = NO_NOISE_PNS; + } + + /* Disable PNS and skip detection in certain cases. */ + if (pnsConf->usePns == 0) { + return; + } else { + /* AAC - LC core encoder */ + if ((pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && + (lastWindowSequence == SHORT_WINDOW)) { return; } - } - else { - if(!pnsConf->usePns) + /* AAC - (E)LD core encoder */ + if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY) && + (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) && + (lastWindowSequence != LONG_WINDOW)) { return; - - /* PNS only for long Windows */ - if (pnsConf->np.detectionAlgorithmFlags & JUST_LONG_WINDOW) { - if(lastWindowSequence != LONG_WINDOW) { - for (sfb = 0; sfb < sfbActive; sfb++) { - pnsData->pnsFlag[sfb] = 0; /* clear all pnsFlags */ - } - return; - } } } + /* call noise detection */ - FDKaacEnc_FDKaacEnc_noiseDetection( pnsConf, - pnsData, - sfbActive, - sfbOffset, - tnsOrder, - tnsPredictionGain, - tnsActive, - mdctSpectrum, - sfbMaxScaleSpec, - sfbtonality ); + FDKaacEnc_FDKaacEnc_noiseDetection( + pnsConf, pnsData, sfbActive, sfbOffset, tnsOrder, tnsPredictionGain, + tnsActive, mdctSpectrum, sfbMaxScaleSpec, sfbtonality); /* set startNoiseSfb (long) */ startNoiseSfb = pnsConf->np.startSfb; /* Set noise substitution status */ - for(sfb = 0; sfb < sfbActive; sfb++) { - + for (sfb = 0; sfb < sfbActive; sfb++) { /* No PNS below startNoiseSfb */ - if(sfb < startNoiseSfb){ + if (sfb < startNoiseSfb) { pnsData->pnsFlag[sfb] = 0; continue; } @@ -258,17 +230,17 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, signal in coder band is not masked */ - if((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) && - ( (sfbThresholdLdData[sfb] + FL2FXCONST_DBL(0.5849625f/64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */ - < sfbEnergyLdData[sfb] ) ) - { + if ((pnsData->noiseFuzzyMeasure[sfb] > FL2FXCONST_SGL(0.5)) && + ((sfbThresholdLdData[sfb] + + FL2FXCONST_DBL(0.5849625f / + 64.0f)) /* thr * 1.5 = thrLd +ld(1.5)/64 */ + < sfbEnergyLdData[sfb])) { /* mark in psyout flag array that we will code this band with PNS */ pnsData->pnsFlag[sfb] = 1; /* PNS_ON */ - } - else{ + } else { pnsData->pnsFlag[sfb] = 0; /* PNS_OFF */ } @@ -276,50 +248,49 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, } /* avoid PNS holes */ - if((pnsData->noiseFuzzyMeasure[0]>FL2FXCONST_SGL(0.5f)) && (pnsData->pnsFlag[1])) { + if ((pnsData->noiseFuzzyMeasure[0] > FL2FXCONST_SGL(0.5f)) && + (pnsData->pnsFlag[1])) { pnsData->pnsFlag[0] = 1; } - for(sfb=1; sfb<maxSfbPerGroup-1; sfb++) { - if((pnsData->noiseFuzzyMeasure[sfb]>pnsConf->np.gapFillThr) && - (pnsData->pnsFlag[sfb-1]) && (pnsData->pnsFlag[sfb+1])) { + for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { + if ((pnsData->noiseFuzzyMeasure[sfb] > pnsConf->np.gapFillThr) && + (pnsData->pnsFlag[sfb - 1]) && (pnsData->pnsFlag[sfb + 1])) { pnsData->pnsFlag[sfb] = 1; } } - if(maxSfbPerGroup>0) { + if (maxSfbPerGroup > 0) { /* avoid PNS hole */ - if((pnsData->noiseFuzzyMeasure[maxSfbPerGroup-1]>pnsConf->np.gapFillThr) && (pnsData->pnsFlag[maxSfbPerGroup-2])) { - pnsData->pnsFlag[maxSfbPerGroup-1] = 1; + if ((pnsData->noiseFuzzyMeasure[maxSfbPerGroup - 1] > + pnsConf->np.gapFillThr) && + (pnsData->pnsFlag[maxSfbPerGroup - 2])) { + pnsData->pnsFlag[maxSfbPerGroup - 1] = 1; } /* avoid single PNS band */ - if(pnsData->pnsFlag[maxSfbPerGroup-2]==0) { - pnsData->pnsFlag[maxSfbPerGroup-1] = 0; + if (pnsData->pnsFlag[maxSfbPerGroup - 2] == 0) { + pnsData->pnsFlag[maxSfbPerGroup - 1] = 0; } } /* avoid single PNS bands */ - if(pnsData->pnsFlag[1]==0) { + if (pnsData->pnsFlag[1] == 0) { pnsData->pnsFlag[0] = 0; } - for(sfb=1; sfb<maxSfbPerGroup-1; sfb++) { - if((pnsData->pnsFlag[sfb-1]==0)&&(pnsData->pnsFlag[sfb+1]==0)) { + for (sfb = 1; sfb < maxSfbPerGroup - 1; sfb++) { + if ((pnsData->pnsFlag[sfb - 1] == 0) && (pnsData->pnsFlag[sfb + 1] == 0)) { pnsData->pnsFlag[sfb] = 0; } } - /* calculate noiseNrg's */ - FDKaacEnc_CalcNoiseNrgs( sfbActive, - pnsData->pnsFlag, - sfbEnergyLdData, - noiseNrg ); + FDKaacEnc_CalcNoiseNrgs(sfbActive, pnsData->pnsFlag, sfbEnergyLdData, + noiseNrg); } - /***************************************************************************** functionname:FDKaacEnc_FDKaacEnc_noiseDetection @@ -335,49 +306,36 @@ void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, flags tonal / nontonal *****************************************************************************/ -static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT sfbActive, - const INT *sfbOffset, - int tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality ) -{ - INT condition = TRUE; - if ( !(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMLEXITY) ) { - condition = (tnsOrder > 3); - } +static void FDKaacEnc_FDKaacEnc_noiseDetection( + PNS_CONFIG *pnsConf, PNS_DATA *pnsData, const INT sfbActive, + const INT *sfbOffset, int tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality) { + INT condition = TRUE; + if (!(pnsConf->np.detectionAlgorithmFlags & IS_LOW_COMPLEXITY)) { + condition = (tnsOrder > 3); + } + /* + no PNS if heavy TNS activity + clear pnsData->noiseFuzzyMeasure + */ + if ((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) && + (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition && + !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && + (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && + (tnsActive))) { + /* clear all noiseFuzzyMeasure */ + FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive * sizeof(FIXP_SGL)); + } else { /* - no PNS if heavy TNS activity - clear pnsData->noiseFuzzyMeasure + call noise detection, output in pnsData->noiseFuzzyMeasure, + use real mdct spectral data */ - if((pnsConf->np.detectionAlgorithmFlags & USE_TNS_GAIN_THR) && - (tnsPredictionGain >= pnsConf->np.tnsGainThreshold) && condition && - !((pnsConf->np.detectionAlgorithmFlags & USE_TNS_PNS) && (tnsPredictionGain >= pnsConf->np.tnsPNSGainThreshold) && (tnsActive)) ) - { - /* clear all noiseFuzzyMeasure */ - FDKmemclear(pnsData->noiseFuzzyMeasure, sfbActive*sizeof(FIXP_SGL)); - } - else - { - /* - call noise detection, output in pnsData->noiseFuzzyMeasure, - use real mdct spectral data - */ - FDKaacEnc_noiseDetect( mdctSpectrum, - sfbMaxScaleSpec, - sfbActive, - sfbOffset, - pnsData->noiseFuzzyMeasure, - &pnsConf->np, - sfbtonality); - } + FDKaacEnc_noiseDetect(mdctSpectrum, sfbMaxScaleSpec, sfbActive, sfbOffset, + pnsData->noiseFuzzyMeasure, &pnsConf->np, + sfbtonality); + } } - /***************************************************************************** functionname:FDKaacEnc_CalcNoiseNrgs @@ -391,23 +349,21 @@ static void FDKaacEnc_FDKaacEnc_noiseDetection( PNS_CONFIG *pnsConf, *****************************************************************************/ -static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, - INT *RESTRICT pnsFlag, - FIXP_DBL *RESTRICT sfbEnergyLdData, - INT *RESTRICT noiseNrg ) -{ +static void FDKaacEnc_CalcNoiseNrgs(const INT sfbActive, INT *RESTRICT pnsFlag, + FIXP_DBL *RESTRICT sfbEnergyLdData, + INT *RESTRICT noiseNrg) { int sfb; - INT tmp = (-LOG_NORM_PCM)<<2; + INT tmp = (-LOG_NORM_PCM) << 2; - for(sfb = 0; sfb < sfbActive; sfb++) { - if(pnsFlag[sfb]) { - INT nrg = (-sfbEnergyLdData[sfb]+FL2FXCONST_DBL(0.5f/64.0f))>>(DFRACT_BITS-1-7); + for (sfb = 0; sfb < sfbActive; sfb++) { + if (pnsFlag[sfb]) { + INT nrg = (-sfbEnergyLdData[sfb] + FL2FXCONST_DBL(0.5f / 64.0f)) >> + (DFRACT_BITS - 1 - 7); noiseNrg[sfb] = tmp - nrg; } } } - /***************************************************************************** functionname:FDKaacEnc_CodePnsChannel @@ -422,20 +378,18 @@ static void FDKaacEnc_CalcNoiseNrgs( const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_CodePnsChannel(const INT sfbActive, - PNS_CONFIG *pnsConf, - INT *RESTRICT pnsFlag, - FIXP_DBL *RESTRICT sfbEnergyLdData, - INT *RESTRICT noiseNrg, - FIXP_DBL *RESTRICT sfbThresholdLdData) -{ +void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf, + INT *RESTRICT pnsFlag, + FIXP_DBL *RESTRICT sfbEnergyLdData, + INT *RESTRICT noiseNrg, + FIXP_DBL *RESTRICT sfbThresholdLdData) { INT sfb; INT lastiNoiseEnergy = 0; INT firstPNSband = 1; /* TRUE for first PNS-coded band */ /* no PNS */ - if(!pnsConf->usePns) { - for(sfb = 0; sfb < sfbActive; sfb++) { + if (!pnsConf->usePns) { + for (sfb = 0; sfb < sfbActive; sfb++) { /* no PNS coding */ noiseNrg[sfb] = NO_NOISE_PNS; } @@ -443,34 +397,32 @@ void FDKaacEnc_CodePnsChannel(const INT sfbActive, } /* code PNS */ - for(sfb = 0; sfb < sfbActive; sfb++) { - if(pnsFlag[sfb]) { + for (sfb = 0; sfb < sfbActive; sfb++) { + if (pnsFlag[sfb]) { /* high sfbThreshold causes pe = 0 */ - if(noiseNrg[sfb] != NO_NOISE_PNS) - sfbThresholdLdData[sfb] = sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f/LD_DATA_SCALING); + if (noiseNrg[sfb] != NO_NOISE_PNS) + sfbThresholdLdData[sfb] = + sfbEnergyLdData[sfb] + FL2FXCONST_DBL(1.0f / LD_DATA_SCALING); /* set noiseNrg in valid region */ - if(!firstPNSband) { + if (!firstPNSband) { INT deltaiNoiseEnergy = noiseNrg[sfb] - lastiNoiseEnergy; - if(deltaiNoiseEnergy > CODE_BOOK_PNS_LAV) - noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV; - else if(deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV) - noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV; - } - else { + if (deltaiNoiseEnergy > CODE_BOOK_PNS_LAV) + noiseNrg[sfb] -= deltaiNoiseEnergy - CODE_BOOK_PNS_LAV; + else if (deltaiNoiseEnergy < -CODE_BOOK_PNS_LAV) + noiseNrg[sfb] -= deltaiNoiseEnergy + CODE_BOOK_PNS_LAV; + } else { firstPNSband = 0; } lastiNoiseEnergy = noiseNrg[sfb]; - } - else { + } else { /* no PNS coding */ noiseNrg[sfb] = NO_NOISE_PNS; } } } - /***************************************************************************** functionname:FDKaacEnc_PreProcessPnsChannelPair @@ -486,37 +438,40 @@ void FDKaacEnc_CodePnsChannel(const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, - FIXP_DBL *RESTRICT sfbEnergyLeft, - FIXP_DBL *RESTRICT sfbEnergyRight, - FIXP_DBL *RESTRICT sfbEnergyLeftLD, - FIXP_DBL *RESTRICT sfbEnergyRightLD, - FIXP_DBL *RESTRICT sfbEnergyMid, - PNS_CONFIG *RESTRICT pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight) -{ +void FDKaacEnc_PreProcessPnsChannelPair( + const INT sfbActive, FIXP_DBL *RESTRICT sfbEnergyLeft, + FIXP_DBL *RESTRICT sfbEnergyRight, FIXP_DBL *RESTRICT sfbEnergyLeftLD, + FIXP_DBL *RESTRICT sfbEnergyRightLD, FIXP_DBL *RESTRICT sfbEnergyMid, + PNS_CONFIG *RESTRICT pnsConf, PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight) { INT sfb; FIXP_DBL ccf; - if(!pnsConf->usePns) - return; + if (!pnsConf->usePns) return; - FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL = pnsDataLeft->noiseEnergyCorrelation; - FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR = pnsDataRight->noiseEnergyCorrelation; + FIXP_DBL *RESTRICT pNoiseEnergyCorrelationL = + pnsDataLeft->noiseEnergyCorrelation; + FIXP_DBL *RESTRICT pNoiseEnergyCorrelationR = + pnsDataRight->noiseEnergyCorrelation; - for(sfb=0;sfb< sfbActive;sfb++) { - FIXP_DBL quot = (sfbEnergyLeftLD[sfb]>>1) + (sfbEnergyRightLD[sfb]>>1); + for (sfb = 0; sfb < sfbActive; sfb++) { + FIXP_DBL quot = (sfbEnergyLeftLD[sfb] >> 1) + (sfbEnergyRightLD[sfb] >> 1); - if(quot < FL2FXCONST_DBL(-32.0f/(float)LD_DATA_SCALING)) + if (quot < FL2FXCONST_DBL(-32.0f / (float)LD_DATA_SCALING)) ccf = FL2FXCONST_DBL(0.0f); else { - FIXP_DBL accu = sfbEnergyMid[sfb]- (((sfbEnergyLeft[sfb]>>1)+(sfbEnergyRight[sfb]>>1))>>1); - INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0 ; + FIXP_DBL accu = + sfbEnergyMid[sfb] - + (((sfbEnergyLeft[sfb] >> 1) + (sfbEnergyRight[sfb] >> 1)) >> 1); + INT sign = (accu < FL2FXCONST_DBL(0.0f)) ? 1 : 0; accu = fixp_abs(accu); - ccf = CalcLdData(accu) + FL2FXCONST_DBL((float)1.0f/(float)LD_DATA_SCALING) - quot; /* ld(accu*2) = ld(accu) + 1 */ - ccf = (ccf>=FL2FXCONST_DBL(0.0)) ? ((FIXP_DBL)MAXVAL_DBL) : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf); + ccf = CalcLdData(accu) + + FL2FXCONST_DBL((float)1.0f / (float)LD_DATA_SCALING) - + quot; /* ld(accu*2) = ld(accu) + 1 */ + ccf = (ccf >= FL2FXCONST_DBL(0.0)) + ? ((FIXP_DBL)MAXVAL_DBL) + : (sign) ? -CalcInvLdData(ccf) : CalcInvLdData(ccf); } pNoiseEnergyCorrelationL[sfb] = ccf; @@ -524,8 +479,6 @@ void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, } } - - /***************************************************************************** functionname:FDKaacEnc_PostProcessPnsChannelPair @@ -542,33 +495,29 @@ void FDKaacEnc_PreProcessPnsChannelPair(const INT sfbActive, *****************************************************************************/ -void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, - PNS_CONFIG *pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight, - INT *RESTRICT msMask, - INT *msDigest ) -{ +void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, + PNS_CONFIG *pnsConf, + PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight, + INT *RESTRICT msMask, INT *msDigest) { INT sfb; - if(!pnsConf->usePns) - return; + if (!pnsConf->usePns) return; - for(sfb=0;sfb<sfbActive;sfb++) { + for (sfb = 0; sfb < sfbActive; sfb++) { /* MS post processing */ - if( msMask[sfb] ) { - if( (pnsDataLeft->pnsFlag[sfb]) && - (pnsDataRight->pnsFlag[sfb]) ) { + if (msMask[sfb]) { + if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { /* AAC only: Standard */ /* do this to avoid ms flags in layers that should not have it */ - if(pnsDataLeft->noiseEnergyCorrelation[sfb] <= pnsConf->noiseCorrelationThresh){ + if (pnsDataLeft->noiseEnergyCorrelation[sfb] <= + pnsConf->noiseCorrelationThresh) { msMask[sfb] = 0; *msDigest = MS_SOME; } - } - else { + } else { /* No PNS coding */ @@ -581,8 +530,9 @@ void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, Use MS flag to signal noise correlation if pns is active in both channels */ - if( (pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb]) ) { - if(pnsDataLeft->noiseEnergyCorrelation[sfb] > pnsConf->noiseCorrelationThresh) { + if ((pnsDataLeft->pnsFlag[sfb]) && (pnsDataRight->pnsFlag[sfb])) { + if (pnsDataLeft->noiseEnergyCorrelation[sfb] > + pnsConf->noiseCorrelationThresh) { msMask[sfb] = 1; *msDigest = MS_SOME; } diff --git a/libAACenc/src/aacenc_pns.h b/libAACenc/src/aacenc_pns.h index 3bda9de..4938fcf 100644 --- a/libAACenc/src/aacenc_pns.h +++ b/libAACenc/src/aacenc_pns.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,35 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: pns.h + Author(s): M. Lohwasser -******************************************************************************/ + Description: pns.h -#ifndef __PNS_H -#define __PNS_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef AACENC_PNS_H +#define AACENC_PNS_H +#include "common_fix.h" #include "pnsparam.h" #define NO_NOISE_PNS FDK_INT_MIN -typedef struct{ +typedef struct { NOISEPARAMS np; FIXP_DBL minCorrelationEnergy; FIXP_DBL noiseCorrelationThresh; - INT usePns; + INT usePns; } PNS_CONFIG; -typedef struct{ +typedef struct { FIXP_SGL noiseFuzzyMeasure[MAX_GROUPED_SFB]; FIXP_DBL noiseEnergyCorrelation[MAX_GROUPED_SFB]; - INT pnsFlag[MAX_GROUPED_SFB]; + INT pnsFlag[MAX_GROUPED_SFB]; } PNS_DATA; -#endif +#endif /* AACENC_PNS_H */ diff --git a/libAACenc/src/aacenc_tns.cpp b/libAACenc/src/aacenc_tns.cpp index 9a07e8f..4462600 100644 --- a/libAACenc/src/aacenc_tns.cpp +++ b/libAACenc/src/aacenc_tns.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): Alex Groeschel, Tobias Chalupka - Initial author: Alex Groeschel, Tobias Chalupka - contents/description: Temporal noise shaping + Description: Temporal noise shaping -******************************************************************************/ +*******************************************************************************/ #include "aacenc_tns.h" #include "psy_const.h" @@ -94,192 +106,213 @@ amm-info@iis.fraunhofer.de #include "tns_func.h" #include "aacEnc_rom.h" #include "aacenc_tns.h" +#include "FDK_lpc.h" #define FILTER_DIRECTION 0 /* 0 = up, 1 = down */ -static const FIXP_DBL acfWindowLong[12+3+1] = { - 0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000, - 0x6e000000,0x69380000,0x63e00000,0x5df80000,0x57800000,0x50780000,0x48e00000,0x40b80000 -}; +static const FIXP_DBL acfWindowLong[12 + 3 + 1] = { + 0x7fffffff, 0x7fb80000, 0x7ee00000, 0x7d780000, 0x7b800000, 0x78f80000, + 0x75e00000, 0x72380000, 0x6e000000, 0x69380000, 0x63e00000, 0x5df80000, + 0x57800000, 0x50780000, 0x48e00000, 0x40b80000}; -static const FIXP_DBL acfWindowShort[4+3+1] = { - 0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000 -}; +static const FIXP_DBL acfWindowShort[4 + 3 + 1] = { + 0x7fffffff, 0x7e000000, 0x78000000, 0x6e000000, + 0x60000000, 0x4e000000, 0x38000000, 0x1e000000}; -typedef struct{ - INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ - INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ - TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */ +typedef struct { + INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ + INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ + TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */ } TNS_INFO_TAB; -#define TNS_TIMERES_SCALE (1) -#define FL2_TIMERES_FIX(a) ( FL2FXCONST_DBL(a/(float)(1<<TNS_TIMERES_SCALE)) ) - -static const TNS_INFO_TAB tnsInfoTab[] = -{ - { - { 16000, 13500}, - { 32000, 28000}, - { - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 12}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, 1 }, - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 12}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, 1 } - } - }, - { - { 32001, 28001}, - { 60000, 52000}, - { - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 10}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 }, - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 10}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 } - } - }, - { - { 60001, 52001}, - { 384000, 384000}, - { - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 8}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 }, - { {1, 1}, {1437, 1500}, {1400, 600}, {12, 8}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 } - } - } -}; +#define TNS_TIMERES_SCALE (1) +#define FL2_TIMERES_FIX(a) (FL2FXCONST_DBL(a / (float)(1 << TNS_TIMERES_SCALE))) + +static const TNS_INFO_TAB tnsInfoTab[] = { + {{16000, 13500}, + {32000, 28000}, + {{{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 12}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, + 1}, + {{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 12}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, + 1}}}, + {{32001, 28001}, + {60000, 52000}, + {{{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 10}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, + 1}, + {{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 10}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, + 1}}}, + {{60001, 52001}, + {384000, 384000}, + {{{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 8}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, + 1}, + {{1, 1}, + {1437, 1500}, + {1400, 600}, + {12, 8}, + {FILTER_DIRECTION, FILTER_DIRECTION}, + {3, 1}, + {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, + 1}}}}; typedef struct { - INT samplingRate; + INT samplingRate; SCHAR maxBands[2]; /* long=0; short=1 */ } TNS_MAX_TAB_ENTRY; -static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = -{ - { 96000, { 31, 9}}, - { 88200, { 31, 9}}, - { 64000, { 34, 10}}, - { 48000, { 40, 14}}, - { 44100, { 42, 14}}, - { 32000, { 51, 14}}, - { 24000, { 46, 14}}, - { 22050, { 46, 14}}, - { 16000, { 42, 14}}, - { 12000, { 42, 14}}, - { 11025, { 42, 14}}, - { 8000, { 39, 14}} +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = { + {96000, {31, 9}}, {88200, {31, 9}}, {64000, {34, 10}}, {48000, {40, 14}}, + {44100, {42, 14}}, {32000, {51, 14}}, {24000, {46, 14}}, {22050, {46, 14}}, + {16000, {42, 14}}, {12000, {42, 14}}, {11025, {42, 14}}, {8000, {39, 14}}}; + +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab120[] = { + {48000, {12, -1}}, /* 48000 */ + {44100, {12, -1}}, /* 44100 */ + {32000, {15, -1}}, /* 32000 */ + {24000, {15, -1}}, /* 24000 */ + {22050, {15, -1}} /* 22050 */ }; -static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = -{ - { 48000, { 31, -1}}, - { 44100, { 32, -1}}, - { 32000, { 37, -1}}, - { 24000, { 30, -1}}, - { 22050, { 30, -1}} +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab128[] = { + {48000, {12, -1}}, /* 48000 */ + {44100, {12, -1}}, /* 44100 */ + {32000, {15, -1}}, /* 32000 */ + {24000, {15, -1}}, /* 24000 */ + {22050, {15, -1}} /* 22050 */ }; -static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = -{ - { 48000, { 31, -1}}, - { 44100, { 32, -1}}, - { 32000, { 37, -1}}, - { 24000, { 31, -1}}, - { 22050, { 31, -1}} +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab240[] = { + {96000, {22, -1}}, /* 96000 */ + {48000, {22, -1}}, /* 48000 */ + {44100, {22, -1}}, /* 44100 */ + {32000, {21, -1}}, /* 32000 */ + {24000, {21, -1}}, /* 24000 */ + {22050, {21, -1}} /* 22050 */ }; -static INT FDKaacEnc_AutoToParcor( - FIXP_DBL *RESTRICT input, - FIXP_DBL *RESTRICT reflCoeff, - const INT numOfCoeff - ); - -static void FDKaacEnc_Parcor2Index( - const FIXP_DBL *parcor, - INT *RESTRICT index, - const INT order, - const INT bitsPerCoeff - ); - -static void FDKaacEnc_Index2Parcor( - const INT *index, - FIXP_DBL *RESTRICT parcor, - const INT order, - const INT bitsPerCoeff - ); - -static INT FDKaacEnc_ParcorToLpc( - const FIXP_DBL *reflCoeff, - FIXP_DBL *RESTRICT LpcCoeff, - const INT numOfCoeff, - FIXP_DBL *RESTRICT workBuffer - ); - -static void FDKaacEnc_AnalysisFilter( - FIXP_DBL *RESTRICT signal, - const INT numOfLines, - const FIXP_DBL *predictorCoeff, - const INT order, - const INT lpcGainFactor - ); - -static void FDKaacEnc_CalcGaussWindow( - FIXP_DBL *win, - const int winSize, - const INT samplingRate, - const INT transformResolution, - const FIXP_DBL timeResolution, - const INT timeResolution_e - ); - -static const TNS_PARAMETER_TABULATED* FDKaacEnc_GetTnsParam( - const INT bitRate, - const INT channels, - const INT sbrLd - ) -{ +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab256[] = { + {96000, {25, -1}}, /* 96000 */ + {48000, {25, -1}}, /* 48000 */ + {44100, {25, -1}}, /* 44100 */ + {32000, {24, -1}}, /* 32000 */ + {24000, {24, -1}}, /* 24000 */ + {22050, {24, -1}} /* 22050 */ +}; +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = {{48000, {31, -1}}, + {44100, {32, -1}}, + {32000, {37, -1}}, + {24000, {30, -1}}, + {22050, {30, -1}}}; + +static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = {{48000, {31, -1}}, + {44100, {32, -1}}, + {32000, {37, -1}}, + {24000, {31, -1}}, + {22050, {31, -1}}}; + +static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index, + const INT order, const INT bitsPerCoeff); + +static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor, + const INT order, const INT bitsPerCoeff); + +static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize, + const INT samplingRate, + const INT transformResolution, + const FIXP_DBL timeResolution, + const INT timeResolution_e); + +static const TNS_PARAMETER_TABULATED *FDKaacEnc_GetTnsParam(const INT bitRate, + const INT channels, + const INT sbrLd) { int i; const TNS_PARAMETER_TABULATED *tnsConfigTab = NULL; - for (i = 0; i < (int) (sizeof(tnsInfoTab)/sizeof(TNS_INFO_TAB)); i++) { - if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd?1:0]) && - bitRate <= tnsInfoTab[i].bitRateTo[sbrLd?1:0]) - { - tnsConfigTab = &tnsInfoTab[i].paramTab[(channels==1)?0:1]; + for (i = 0; i < (int)(sizeof(tnsInfoTab) / sizeof(TNS_INFO_TAB)); i++) { + if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd ? 1 : 0]) && + bitRate <= tnsInfoTab[i].bitRateTo[sbrLd ? 1 : 0]) { + tnsConfigTab = &tnsInfoTab[i].paramTab[(channels == 1) ? 0 : 1]; } } return tnsConfigTab; } - -static INT getTnsMaxBands( - const INT sampleRate, - const INT granuleLength, - const INT isShortBlock - ) -{ +static INT getTnsMaxBands(const INT sampleRate, const INT granuleLength, + const INT isShortBlock) { int i; INT numBands = -1; const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL; int maxBandsTabSize = 0; switch (granuleLength) { + case 960: case 1024: pMaxBandsTab = tnsMaxBandsTab1024; - maxBandsTabSize = sizeof(tnsMaxBandsTab1024)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab1024) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 120: + pMaxBandsTab = tnsMaxBandsTab120; + maxBandsTabSize = sizeof(tnsMaxBandsTab120) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 128: + pMaxBandsTab = tnsMaxBandsTab128; + maxBandsTabSize = sizeof(tnsMaxBandsTab128) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 240: + pMaxBandsTab = tnsMaxBandsTab240; + maxBandsTabSize = sizeof(tnsMaxBandsTab240) / sizeof(TNS_MAX_TAB_ENTRY); + break; + case 256: + pMaxBandsTab = tnsMaxBandsTab256; + maxBandsTabSize = sizeof(tnsMaxBandsTab256) / sizeof(TNS_MAX_TAB_ENTRY); break; case 480: pMaxBandsTab = tnsMaxBandsTab480; - maxBandsTabSize = sizeof(tnsMaxBandsTab480)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab480) / sizeof(TNS_MAX_TAB_ENTRY); break; case 512: pMaxBandsTab = tnsMaxBandsTab512; - maxBandsTabSize = sizeof(tnsMaxBandsTab512)/sizeof(TNS_MAX_TAB_ENTRY); + maxBandsTabSize = sizeof(tnsMaxBandsTab512) / sizeof(TNS_MAX_TAB_ENTRY); break; default: numBands = -1; } - if (pMaxBandsTab!=NULL) { - for (i=0; i<maxBandsTabSize; i++) { - numBands = pMaxBandsTab[i].maxBands[(!isShortBlock)?0:1]; + if (pMaxBandsTab != NULL) { + for (i = 0; i < maxBandsTabSize; i++) { + numBands = pMaxBandsTab[i].maxBands[(!isShortBlock) ? 0 : 1]; if (sampleRate >= pMaxBandsTab[i].samplingRate) { break; } @@ -291,7 +324,7 @@ static INT getTnsMaxBands( /***************************************************************************/ /*! - \brief FDKaacEnc_FreqToBandWithRounding + \brief FDKaacEnc_FreqToBandWidthRounding Returns index of nearest band border @@ -303,38 +336,31 @@ static INT getTnsMaxBands( \return band border ****************************************************************************/ -INT FDKaacEnc_FreqToBandWithRounding( - const INT freq, - const INT fs, - const INT numOfBands, - const INT *bandStartOffset - ) -{ +INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs, + const INT numOfBands, + const INT *bandStartOffset) { INT lineNumber, band; /* assert(freq >= 0); */ - lineNumber = (freq*bandStartOffset[numOfBands]*4/fs+1)/2; + lineNumber = (freq * bandStartOffset[numOfBands] * 4 / fs + 1) / 2; /* freq > fs/2 */ - if (lineNumber >= bandStartOffset[numOfBands]) - return numOfBands; + if (lineNumber >= bandStartOffset[numOfBands]) return numOfBands; /* find band the line number lies in */ - for (band=0; band<numOfBands; band++) { - if (bandStartOffset[band+1]>lineNumber) break; + for (band = 0; band < numOfBands; band++) { + if (bandStartOffset[band + 1] > lineNumber) break; } /* round to nearest band border */ if (lineNumber - bandStartOffset[band] > - bandStartOffset[band+1] - lineNumber ) - { - band++; - } + bandStartOffset[band + 1] - lineNumber) { + band++; + } - return(band); + return (band); } - /***************************************************************************** functionname: FDKaacEnc_InitTnsConfiguration @@ -348,113 +374,132 @@ INT FDKaacEnc_FreqToBandWithRounding( output: *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate, - INT sampleRate, - INT channels, - INT blockType, - INT granuleLength, - INT isLowDelay, - INT ldSbrPresent, - TNS_CONFIG *tC, - PSY_CONFIGURATION *pC, - INT active, - INT useTnsPeak) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration( + INT bitRate, INT sampleRate, INT channels, INT blockType, INT granuleLength, + INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tC, PSY_CONFIGURATION *pC, + INT active, INT useTnsPeak) { int i; - //float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f; + // float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f; - if (channels <= 0) - return (AAC_ENCODER_ERROR)1; + if (channels <= 0) return (AAC_ENCODER_ERROR)1; tC->isLowDelay = isLowDelay; - /* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */ - tC->tnsActive = (active) ? TRUE : FALSE; - tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ - if (bitRate < 16000) - tC->maxOrder -= 2; - tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4; + /* initialize TNS filter flag, order, and coefficient resolution (in bits per + * coeff) */ + tC->tnsActive = (active) ? TRUE : FALSE; + tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ + if (bitRate < 16000) tC->maxOrder -= 2; + tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4; - /* LPC stop line: highest MDCT line to be coded, but do not go beyond TNS_MAX_BANDS! */ - tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, (blockType == SHORT_WINDOW) ? 1 : 0); + /* LPC stop line: highest MDCT line to be coded, but do not go beyond + * TNS_MAX_BANDS! */ + tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, + (blockType == SHORT_WINDOW) ? 1 : 0); if (tC->lpcStopBand < 0) { return (AAC_ENCODER_ERROR)1; } - tC->lpcStopBand = FDKmin(tC->lpcStopBand, pC->sfbActive); - tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; + tC->lpcStopBand = fMin(tC->lpcStopBand, pC->sfbActive); + tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; switch (granuleLength) { + case 960: case 1024: - /* TNS start line: skip lower MDCT lines to prevent artifacts due to filter mismatch */ - tC->lpcStartBand[LOFILT] = (blockType == SHORT_WINDOW) ? 0 : ((sampleRate < 18783) ? 4 : 8); - tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; + /* TNS start line: skip lower MDCT lines to prevent artifacts due to + * filter mismatch */ + if (blockType == SHORT_WINDOW) { + tC->lpcStartBand[LOFILT] = 0; + } else { + tC->lpcStartBand[LOFILT] = + (sampleRate < 9391) ? 2 : ((sampleRate < 18783) ? 4 : 8); + } + tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; i = tC->lpcStopBand; - while (pC->sfbOffset[i] > (tC->lpcStartLine[LOFILT] + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) i--; - tC->lpcStartBand[HIFILT] = i; - tC->lpcStartLine[HIFILT] = pC->sfbOffset[i]; + while (pC->sfbOffset[i] > + (tC->lpcStartLine[LOFILT] + + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) + i--; + tC->lpcStartBand[HIFILT] = i; + tC->lpcStartLine[HIFILT] = pC->sfbOffset[i]; tC->confTab.threshOn[HIFILT] = 1437; tC->confTab.threshOn[LOFILT] = 1500; tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder; - tC->confTab.tnsLimitOrder[LOFILT] = tC->maxOrder - 7; + tC->confTab.tnsLimitOrder[LOFILT] = fMax(0, tC->maxOrder - 7); tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION; tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION; - tC->confTab.acfSplit[HIFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation*/ - tC->confTab.acfSplit[LOFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation */ + tC->confTab.acfSplit[HIFILT] = + -1; /* signal Merged4to2QuartersAutoCorrelation in + FDKaacEnc_MergedAutoCorrelation*/ + tC->confTab.acfSplit[LOFILT] = + -1; /* signal Merged4to2QuartersAutoCorrelation in + FDKaacEnc_MergedAutoCorrelation */ tC->confTab.filterEnabled[HIFILT] = 1; tC->confTab.filterEnabled[LOFILT] = 1; tC->confTab.seperateFiltersAllowed = 1; - /* compute autocorrelation window based on maximum filter order for given block type */ + /* compute autocorrelation window based on maximum filter order for given + * block type */ /* for (i = 0; i <= tC->maxOrder + 3; i++) { float acfWinTemp = acfTimeRes * i; acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp); } */ if (blockType == SHORT_WINDOW) { - FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); - FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); - } - else { - FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); - FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, + fMin((LONG)sizeof(acfWindowShort), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, + fMin((LONG)sizeof(acfWindowShort), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + } else { + FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, + fMin((LONG)sizeof(acfWindowLong), + (LONG)sizeof(tC->acfWindow[HIFILT]))); + FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, + fMin((LONG)sizeof(acfWindowLong), + (LONG)sizeof(tC->acfWindow[HIFILT]))); } break; case 480: - case 512: - { - const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); - - if ( pCfg != NULL ) { - - FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab)); - - tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); - tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; - tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); - tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; - - FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); - FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); - } - else { - tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ - } + case 512: { + const TNS_PARAMETER_TABULATED *pCfg = + FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); + if (pCfg != NULL) { + FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab)); + + tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWidthRounding( + pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, + pC->sfbOffset); + tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; + tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWidthRounding( + pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, + pC->sfbOffset); + tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; + + FDKaacEnc_CalcGaussWindow( + tC->acfWindow[HIFILT], tC->maxOrder + 1, sampleRate, granuleLength, + pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); + FDKaacEnc_CalcGaussWindow( + tC->acfWindow[LOFILT], tC->maxOrder + 1, sampleRate, granuleLength, + pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); + } else { + tC->tnsActive = + FALSE; /* no configuration available, disable tns tool */ } - break; + } break; default: tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ } return AAC_ENC_OK; - } /***************************************************************************/ @@ -471,29 +516,25 @@ AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate, \return scale factor ****************************************************************************/ -static inline INT FDKaacEnc_ScaleUpSpectrum( - FIXP_DBL *dest, - const FIXP_DBL *src, - const INT startLine, - const INT stopLine - ) -{ - INT i, scale; - - FIXP_DBL maxVal = FL2FXCONST_DBL(0.f); - - /* Get highest value in given spectrum */ - for (i=startLine; i<stopLine; i++) { - maxVal = fixMax(maxVal,fixp_abs(src[i])); - } - scale = CountLeadingBits(maxVal); +static inline INT FDKaacEnc_ScaleUpSpectrum(FIXP_DBL *dest, const FIXP_DBL *src, + const INT startLine, + const INT stopLine) { + INT i, scale; - /* Scale spectrum according to highest value */ - for (i=startLine; i<stopLine; i++) { - dest[i] = src[i]<<scale; - } + FIXP_DBL maxVal = FL2FXCONST_DBL(0.f); - return scale; + /* Get highest value in given spectrum */ + for (i = startLine; i < stopLine; i++) { + maxVal = fixMax(maxVal, fixp_abs(src[i])); + } + scale = CountLeadingBits(maxVal); + + /* Scale spectrum according to highest value */ + for (i = startLine; i < stopLine; i++) { + dest[i] = src[i] << scale; + } + + return scale; } /***************************************************************************/ @@ -509,29 +550,27 @@ static inline INT FDKaacEnc_ScaleUpSpectrum( \param scaling of the lag ****************************************************************************/ -static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue( - const FIXP_DBL *spectrum, - const INT startLine, - const INT stopLine, - const INT lag, - const INT scale - ) -{ - int i; - FIXP_DBL result = FL2FXCONST_DBL(0.f); - - if (lag==0) { - for (i=startLine; i<stopLine; i++) { - result += (fPow2(spectrum[i])>>scale); - } +static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue(const FIXP_DBL *spectrum, + const INT startLine, + const INT stopLine, + const INT lag, + const INT scale) { + int i; + FIXP_DBL result = FL2FXCONST_DBL(0.f); + + /* This versions allows to save memory accesses, when computing pow2 */ + /* It is of interest for ARM, XTENSA without parallel memory access */ + if (lag == 0) { + for (i = startLine; i < stopLine; i++) { + result += (fPow2(spectrum[i]) >> scale); } - else { - for (i=startLine; i<(stopLine-lag); i++) { - result += (fMult(spectrum[i], spectrum[i+lag])>>scale); - } + } else { + for (i = startLine; i < (stopLine - lag); i++) { + result += (fMult(spectrum[i], spectrum[i + lag]) >> scale); } + } - return result; + return result; } /***************************************************************************/ @@ -545,172 +584,173 @@ static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue( \param filter start line ****************************************************************************/ -static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac( - const FIXP_DBL value, - const INT scale, - INT *sc - ) -{ - #define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */ - #define MAX_INV_NRGFAC (1.f/HLM_MIN_NRG) - - FIXP_DBL retValue; - FIXP_DBL A, B; - - if (scale>=0) { - A = value; - B = FL2FXCONST_DBL(HLM_MIN_NRG)>>fixMin(DFRACT_BITS-1,scale); - } - else { - A = value>>fixMin(DFRACT_BITS-1,(-scale)); - B = FL2FXCONST_DBL(HLM_MIN_NRG); - } +static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac(const FIXP_DBL value, + const INT scale, INT *sc) { +#define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */ +#define MAX_INV_NRGFAC (1.f / HLM_MIN_NRG) - if (A > B) { - int shift = 0; - FIXP_DBL tmp = invSqrtNorm2(value,&shift); + FIXP_DBL retValue; + FIXP_DBL A, B; - retValue = fMult(tmp,tmp); - *sc += (2*shift); - } - else { - /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */ - retValue = /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL; - *sc += scale+28; - } + if (scale >= 0) { + A = value; + B = FL2FXCONST_DBL(HLM_MIN_NRG) >> fixMin(DFRACT_BITS - 1, scale); + } else { + A = value >> fixMin(DFRACT_BITS - 1, (-scale)); + B = FL2FXCONST_DBL(HLM_MIN_NRG); + } + + if (A > B) { + int shift = 0; + FIXP_DBL tmp = invSqrtNorm2(value, &shift); - return retValue; + retValue = fMult(tmp, tmp); + *sc += (2 * shift); + } else { + /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */ + retValue = + /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL; + *sc += scale + 28; + } + + return retValue; } static void FDKaacEnc_MergedAutoCorrelation( - const FIXP_DBL *spectrum, - const INT isLowDelay, - const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1], - const INT lpcStartLine[MAX_NUM_OF_FILTERS], - const INT lpcStopLine, - const INT maxOrder, - const INT acfSplit[MAX_NUM_OF_FILTERS], - FIXP_DBL *_rxx1, - FIXP_DBL *_rxx2 - ) -{ - int i, idx0, idx1, idx2, idx3, idx4, lag; - FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0; - - /* buffer for temporal spectrum */ - C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024)); - - /* pre-initialization output */ - FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1)); - FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1)); - - idx0 = idx1 = idx2 = idx3 = idx4 = 0; - - /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */ - if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) { - /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */ - idx0 = lpcStartLine[LOFILT]; - i = lpcStopLine - lpcStartLine[LOFILT]; - idx1 = idx0 + i / 4; - idx2 = idx0 + i / 2; - idx3 = idx0 + i * 3 / 4; - idx4 = lpcStopLine; - } - else { - FDK_ASSERT(acfSplit[LOFILT]==1); - FDK_ASSERT(acfSplit[HIFILT]==3); - i = (lpcStopLine - lpcStartLine[HIFILT]) / 3; - idx0 = lpcStartLine[LOFILT]; - idx1 = lpcStartLine[HIFILT]; - idx2 = idx1 + i; - idx3 = idx2 + i; - idx4 = lpcStopLine; - } + const FIXP_DBL *spectrum, const INT isLowDelay, + const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1], + const INT lpcStartLine[MAX_NUM_OF_FILTERS], const INT lpcStopLine, + const INT maxOrder, const INT acfSplit[MAX_NUM_OF_FILTERS], FIXP_DBL *_rxx1, + FIXP_DBL *_rxx2) { + int i, idx0, idx1, idx2, idx3, idx4, lag; + FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0; + + /* buffer for temporal spectrum */ + C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024)) + + /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters + */ + if ((acfSplit[LOFILT] == -1) || (acfSplit[HIFILT] == -1)) { + /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the + * spectrum */ + idx0 = lpcStartLine[LOFILT]; + i = lpcStopLine - lpcStartLine[LOFILT]; + idx1 = idx0 + i / 4; + idx2 = idx0 + i / 2; + idx3 = idx0 + i * 3 / 4; + idx4 = lpcStopLine; + } else { + FDK_ASSERT(acfSplit[LOFILT] == 1); + FDK_ASSERT(acfSplit[HIFILT] == 3); + i = (lpcStopLine - lpcStartLine[HIFILT]) / 3; + idx0 = lpcStartLine[LOFILT]; + idx1 = lpcStartLine[HIFILT]; + idx2 = idx1 + i; + idx3 = idx2 + i; + idx4 = lpcStopLine; + } - /* copy spectrum to temporal buffer and scale up as much as possible */ - INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1); - INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2); - INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3); - INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4); - - /* get scaling values for summation */ - INT nsc1, nsc2, nsc3, nsc4; - for (nsc1=1; (1<<nsc1)<(idx1-idx0); nsc1++); - for (nsc2=1; (1<<nsc2)<(idx2-idx1); nsc2++); - for (nsc3=1; (1<<nsc3)<(idx3-idx2); nsc3++); - for (nsc4=1; (1<<nsc4)<(idx4-idx3); nsc4++); - - /* compute autocorrelation value at lag zero, i. e. energy, for each quarter */ - rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1); - rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2); - rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3); - rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4); - - /* compute energy normalization factors, i. e. 1/energy (saves some divisions) */ - if (rxx1_0 != FL2FXCONST_DBL(0.f)) - { - INT sc_fac1 = -1; - FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1); - _rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1); - - if (isLowDelay) - { - for (lag = 1; lag <= maxOrder; lag++) { - /* compute energy-normalized and windowed autocorrelation values at this lag */ - FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); - _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][lag]); - } + /* copy spectrum to temporal buffer and scale up as much as possible */ + INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1); + INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2); + INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3); + INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4); + + /* get scaling values for summation */ + INT nsc1, nsc2, nsc3, nsc4; + for (nsc1 = 1; (1 << nsc1) < (idx1 - idx0); nsc1++) + ; + for (nsc2 = 1; (1 << nsc2) < (idx2 - idx1); nsc2++) + ; + for (nsc3 = 1; (1 << nsc3) < (idx3 - idx2); nsc3++) + ; + for (nsc4 = 1; (1 << nsc4) < (idx4 - idx3); nsc4++) + ; + + /* compute autocorrelation value at lag zero, i. e. energy, for each quarter + */ + rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1); + rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2); + rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3); + rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4); + + /* compute energy normalization factors, i. e. 1/energy (saves some divisions) + */ + if (rxx1_0 != FL2FXCONST_DBL(0.f)) { + INT sc_fac1 = -1; + FIXP_DBL fac1 = + FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2 * sc1) + nsc1), &sc_fac1); + _rxx1[0] = scaleValue(fMult(rxx1_0, fac1), sc_fac1); + + if (isLowDelay) { + for (lag = 1; lag <= maxOrder; lag++) { + /* compute energy-normalized and windowed autocorrelation values at this + * lag */ + FIXP_DBL x1 = + FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); + _rxx1[lag] = + fMult(scaleValue(fMult(x1, fac1), sc_fac1), acfWindow[LOFILT][lag]); } - else - { - for (lag = 1; lag <= maxOrder; lag++) { - if ((3 * lag) <= maxOrder + 3) { - FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); - _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]); - } + } else { + for (lag = 1; lag <= maxOrder; lag++) { + if ((3 * lag) <= maxOrder + 3) { + FIXP_DBL x1 = + FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); + _rxx1[lag] = fMult(scaleValue(fMult(x1, fac1), sc_fac1), + acfWindow[LOFILT][3 * lag]); } } } + } - /* auto corr over upper 3/4 of spectrum */ - if ( !((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) && (rxx4_0 == FL2FXCONST_DBL(0.f))) ) - { - FIXP_DBL fac2, fac3, fac4; - fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f); - INT sc_fac2, sc_fac3, sc_fac4; - sc_fac2 = sc_fac3 = sc_fac4 = 0; - - if (rxx2_0!=FL2FXCONST_DBL(0.f)) { - fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2*sc2)+nsc2), &sc_fac2); - sc_fac2 -= 2; - } - if (rxx3_0!=FL2FXCONST_DBL(0.f)) { - fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2*sc3)+nsc3), &sc_fac3); - sc_fac3 -= 2; - } - if (rxx4_0!=FL2FXCONST_DBL(0.f)) { - fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2*sc4)+nsc4), &sc_fac4); - sc_fac4 -= 2; - } - - _rxx2[0] = scaleValue(fMult(rxx2_0,fac2),sc_fac2) + - scaleValue(fMult(rxx3_0,fac3),sc_fac3) + - scaleValue(fMult(rxx4_0,fac4),sc_fac4); - - for (lag = 1; lag <= maxOrder; lag++) { - /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays separate */ - FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, lag, nsc2), fac2),sc_fac2) + - scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, lag, nsc3), fac3),sc_fac3) + - scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, lag, nsc4), fac4),sc_fac4); + /* auto corr over upper 3/4 of spectrum */ + if (!((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) && + (rxx4_0 == FL2FXCONST_DBL(0.f)))) { + FIXP_DBL fac2, fac3, fac4; + fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f); + INT sc_fac2, sc_fac3, sc_fac4; + sc_fac2 = sc_fac3 = sc_fac4 = 0; + + if (rxx2_0 != FL2FXCONST_DBL(0.f)) { + fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2 * sc2) + nsc2), &sc_fac2); + sc_fac2 -= 2; + } + if (rxx3_0 != FL2FXCONST_DBL(0.f)) { + fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2 * sc3) + nsc3), &sc_fac3); + sc_fac3 -= 2; + } + if (rxx4_0 != FL2FXCONST_DBL(0.f)) { + fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2 * sc4) + nsc4), &sc_fac4); + sc_fac4 -= 2; + } - _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]); - } + _rxx2[0] = scaleValue(fMult(rxx2_0, fac2), sc_fac2) + + scaleValue(fMult(rxx3_0, fac3), sc_fac3) + + scaleValue(fMult(rxx4_0, fac4), sc_fac4); + + for (lag = 1; lag <= maxOrder; lag++) { + /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays + * separate */ + FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue( + pSpectrum, idx1, idx2, lag, nsc2), + fac2), + sc_fac2) + + scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue( + pSpectrum, idx2, idx3, lag, nsc3), + fac3), + sc_fac3) + + scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue( + pSpectrum, idx3, idx4, lag, nsc4), + fac4), + sc_fac4); + + _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]); } + } - C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024)); + C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024)) } - /***************************************************************************** functionname: FDKaacEnc_TnsDetect description: do decision, if TNS shall be used or not @@ -723,69 +763,70 @@ static void FDKaacEnc_MergedAutoCorrelation( sfb-wise energy. *****************************************************************************/ -INT FDKaacEnc_TnsDetect( - TNS_DATA *tnsData, - const TNS_CONFIG *tC, - TNS_INFO* tnsInfo, - INT sfbCnt, - FIXP_DBL *spectrum, - INT subBlockNumber, - INT blockType - ) -{ - /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum. */ - FIXP_DBL rxx1[TNS_MAX_ORDER+1]; /* higher part */ - FIXP_DBL rxx2[TNS_MAX_ORDER+1]; /* lower part */ - FIXP_DBL parcor_tmp[TNS_MAX_ORDER]; +INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC, + TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum, + INT subBlockNumber, INT blockType) { + /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the + * spectrum. */ + FIXP_DBL rxx1[TNS_MAX_ORDER + 1]; /* higher part */ + FIXP_DBL rxx2[TNS_MAX_ORDER + 1]; /* lower part */ + FIXP_LPC parcor_tmp[TNS_MAX_ORDER]; int i; - TNS_SUBBLOCK_INFO *tsbi = (blockType == SHORT_WINDOW) - ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] - : &tnsData->dataRaw.Long.subBlockInfo; + FDKmemclear(rxx1, sizeof(rxx1)); + FDKmemclear(rxx2, sizeof(rxx2)); + + TNS_SUBBLOCK_INFO *tsbi = + (blockType == SHORT_WINDOW) + ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] + : &tnsData->dataRaw.Long.subBlockInfo; - tnsData->filtersMerged = FALSE; + tnsData->filtersMerged = FALSE; - tsbi->tnsActive[HIFILT] = FALSE; - tsbi->predictionGain[HIFILT] = 1000; - tsbi->tnsActive[LOFILT] = FALSE; - tsbi->predictionGain[LOFILT] = 1000; + tsbi->tnsActive[HIFILT] = FALSE; + tsbi->predictionGain[HIFILT] = 1000; + tsbi->tnsActive[LOFILT] = FALSE; + tsbi->predictionGain[LOFILT] = 1000; tnsInfo->numOfFilters[subBlockNumber] = 0; - tnsInfo->coefRes[subBlockNumber] = tC->coefRes; + tnsInfo->coefRes[subBlockNumber] = tC->coefRes; for (i = 0; i < tC->maxOrder; i++) { - tnsInfo->coef[subBlockNumber][HIFILT][i] = tnsInfo->coef[subBlockNumber][LOFILT][i] = 0; + tnsInfo->coef[subBlockNumber][HIFILT][i] = + tnsInfo->coef[subBlockNumber][LOFILT][i] = 0; } - tnsInfo->length[subBlockNumber][HIFILT] = tnsInfo->length[subBlockNumber][LOFILT] = 0; - tnsInfo->order [subBlockNumber][HIFILT] = tnsInfo->order [subBlockNumber][LOFILT] = 0; + tnsInfo->length[subBlockNumber][HIFILT] = + tnsInfo->length[subBlockNumber][LOFILT] = 0; + tnsInfo->order[subBlockNumber][HIFILT] = + tnsInfo->order[subBlockNumber][LOFILT] = 0; - if ( (tC->tnsActive) && (tC->maxOrder>0) ) - { + if ((tC->tnsActive) && (tC->maxOrder > 0)) { int sumSqrCoef; FDKaacEnc_MergedAutoCorrelation( - spectrum, - tC->isLowDelay, - tC->acfWindow, - tC->lpcStartLine, - tC->lpcStopLine, - tC->maxOrder, - tC->confTab.acfSplit, - rxx1, - rxx2); - - /* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ - tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]); - - /* non-linear quantization of TNS lattice coefficients with given resolution */ - FDKaacEnc_Parcor2Index( - parcor_tmp, - tnsInfo->coef[subBlockNumber][HIFILT], - tC->confTab.tnsLimitOrder[HIFILT], - tC->coefRes); - - /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ + spectrum, tC->isLowDelay, tC->acfWindow, tC->lpcStartLine, + tC->lpcStopLine, tC->maxOrder, tC->confTab.acfSplit, rxx1, rxx2); + + /* compute higher TNS filter coefficients in lattice form (ParCor) with + * LeRoux-Gueguen/Schur algorithm */ + { + FIXP_DBL predictionGain_m; + INT predictionGain_e; + + CLpc_AutoToParcor(rxx2, 0, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT], + &predictionGain_m, &predictionGain_e); + tsbi->predictionGain[HIFILT] = + (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31); + } + + /* non-linear quantization of TNS lattice coefficients with given resolution + */ + FDKaacEnc_Parcor2Index(parcor_tmp, tnsInfo->coef[subBlockNumber][HIFILT], + tC->confTab.tnsLimitOrder[HIFILT], tC->coefRes); + + /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) + */ for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) { if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { break; @@ -796,35 +837,49 @@ INT FDKaacEnc_TnsDetect( sumSqrCoef = 0; for (; i >= 0; i--) { - sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] * tnsInfo->coef[subBlockNumber][HIFILT][i]; + sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] * + tnsInfo->coef[subBlockNumber][HIFILT][i]; } - tnsInfo->direction[subBlockNumber][HIFILT] = tC->confTab.tnsFilterDirection[HIFILT]; + tnsInfo->direction[subBlockNumber][HIFILT] = + tC->confTab.tnsFilterDirection[HIFILT]; tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT]; - /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */ - if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2))) - { + /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small + */ + if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || + (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT] / 2 + 2))) { tsbi->tnsActive[HIFILT] = TRUE; tnsInfo->numOfFilters[subBlockNumber]++; - /* compute second filter for lower quarter; only allowed for long windows! */ - if ( (blockType != SHORT_WINDOW) && - (tC->confTab.filterEnabled[LOFILT]) && (tC->confTab.seperateFiltersAllowed) ) - { + /* compute second filter for lower quarter; only allowed for long windows! + */ + if ((blockType != SHORT_WINDOW) && (tC->confTab.filterEnabled[LOFILT]) && + (tC->confTab.seperateFiltersAllowed)) { /* compute second filter for lower frequencies */ - /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ - INT predGain = FDKaacEnc_AutoToParcor(rxx1, parcor_tmp, tC->confTab.tnsLimitOrder[LOFILT]); + /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen + * algorithm */ + INT predGain; + { + FIXP_DBL predictionGain_m; + INT predictionGain_e; + + CLpc_AutoToParcor(rxx1, 0, parcor_tmp, + tC->confTab.tnsLimitOrder[LOFILT], + &predictionGain_m, &predictionGain_e); + predGain = + (INT)fMultNorm(predictionGain_m, predictionGain_e, 1000, 31, 31); + } - /* non-linear quantization of TNS lattice coefficients with given resolution */ - FDKaacEnc_Parcor2Index( - parcor_tmp, - tnsInfo->coef[subBlockNumber][LOFILT], - tC->confTab.tnsLimitOrder[LOFILT], - tC->coefRes); + /* non-linear quantization of TNS lattice coefficients with given + * resolution */ + FDKaacEnc_Parcor2Index(parcor_tmp, + tnsInfo->coef[subBlockNumber][LOFILT], + tC->confTab.tnsLimitOrder[LOFILT], tC->coefRes); - /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ + /* reduce filter order by truncating trailing zeros, compute + * sum(abs(coefs)) */ for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) { if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) { break; @@ -834,29 +889,37 @@ INT FDKaacEnc_TnsDetect( sumSqrCoef = 0; for (; i >= 0; i--) { - sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] * tnsInfo->coef[subBlockNumber][LOFILT][i]; + sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] * + tnsInfo->coef[subBlockNumber][LOFILT][i]; } - tnsInfo->direction[subBlockNumber][LOFILT] = tC->confTab.tnsFilterDirection[LOFILT]; - tnsInfo->length[subBlockNumber][LOFILT] = tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT]; - - /* filter lower quarter if gain is high enough, but not if it's too high */ - if ( ( (predGain > tC->confTab.threshOn[LOFILT]) && (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT])) ) - || ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) ) - { - /* compare lower to upper filter; if they are very similar, merge them */ + tnsInfo->direction[subBlockNumber][LOFILT] = + tC->confTab.tnsFilterDirection[LOFILT]; + tnsInfo->length[subBlockNumber][LOFILT] = + tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT]; + + /* filter lower quarter if gain is high enough, but not if it's too high + */ + if (((predGain > tC->confTab.threshOn[LOFILT]) && + (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT]))) || + ((sumSqrCoef > 9) && + (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]))) { + /* compare lower to upper filter; if they are very similar, merge them + */ tsbi->tnsActive[LOFILT] = TRUE; sumSqrCoef = 0; for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) { - sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]); + sumSqrCoef += fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i] - + tnsInfo->coef[subBlockNumber][LOFILT][i]); } - if ( (sumSqrCoef < 2) && - (tnsInfo->direction[subBlockNumber][LOFILT] == tnsInfo->direction[subBlockNumber][HIFILT]) ) - { + if ((sumSqrCoef < 2) && + (tnsInfo->direction[subBlockNumber][LOFILT] == + tnsInfo->direction[subBlockNumber][HIFILT])) { tnsData->filtersMerged = TRUE; - tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[LOFILT]; + tnsInfo->length[subBlockNumber][HIFILT] = + sfbCnt - tC->lpcStartBand[LOFILT]; for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) { - if (FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { + if (fAbs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { break; } } @@ -868,22 +931,19 @@ INT FDKaacEnc_TnsDetect( if (i < tnsInfo->order[subBlockNumber][HIFILT]) { tnsInfo->order[subBlockNumber][HIFILT] = i + 1; } - } - else { + } else { tnsInfo->numOfFilters[subBlockNumber]++; } } /* filter lower part */ - tsbi->predictionGain[LOFILT]=predGain; + tsbi->predictionGain[LOFILT] = predGain; } /* second filter allowed */ - } /* if predictionGain > 1437 ... */ - } /* maxOrder > 0 && tnsActive */ + } /* if predictionGain > 1437 ... */ + } /* maxOrder > 0 && tnsActive */ return 0; - } - /***************************************************************************/ /*! \brief FDKaacLdEnc_TnsSync @@ -898,79 +958,77 @@ INT FDKaacEnc_TnsDetect( \return void ****************************************************************************/ -void FDKaacEnc_TnsSync( - TNS_DATA *tnsDataDest, - const TNS_DATA *tnsDataSrc, - TNS_INFO *tnsInfoDest, - TNS_INFO *tnsInfoSrc, - const INT blockTypeDest, - const INT blockTypeSrc, - const TNS_CONFIG *tC - ) -{ +void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc, + TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc, + const INT blockTypeDest, const INT blockTypeSrc, + const TNS_CONFIG *tC) { int i, w, absDiff, nWindows; TNS_SUBBLOCK_INFO *sbInfoDest; const TNS_SUBBLOCK_INFO *sbInfoSrc; - /* if one channel contains short blocks and the other not, do not synchronize */ - if ( (blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) || - (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW) ) - { + /* if one channel contains short blocks and the other not, do not synchronize + */ + if ((blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) || + (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW)) { return; } if (blockTypeDest != SHORT_WINDOW) { sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo; - sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo; - nWindows = 1; + sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo; + nWindows = 1; } else { sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0]; - sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0]; - nWindows = 8; + sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0]; + nWindows = 8; } - for (w=0; w<nWindows; w++) { - const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w; - TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w; - INT doSync = 1, absDiffSum = 0; - - /* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */ - if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { - for (i = 0; i < tC->maxOrder; i++) { - absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]); - absDiffSum += absDiff; - /* if coefficients diverge too much between channels, do not synchronize */ - if ((absDiff > 1) || (absDiffSum > 2)) { - doSync = 0; - break; - } - } - - if (doSync) { - /* if no significant difference was detected, synchronize coefficient sets */ - if (pSbInfoSrcW->tnsActive[HIFILT]) { - /* no dest filter, or more dest than source filters: use one dest filter */ - if ((!pSbInfoDestW->tnsActive[HIFILT]) || - ((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) - { - pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1; - } - tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; - tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT]; - tnsInfoDest->length [w][HIFILT] = tnsInfoSrc->length [w][HIFILT]; - tnsInfoDest->direction [w][HIFILT] = tnsInfoSrc->direction [w][HIFILT]; - tnsInfoDest->coefCompress[w][HIFILT] = tnsInfoSrc->coefCompress[w][HIFILT]; - - for (i = 0; i < tC->maxOrder; i++) { - tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i]; - } - } - else - pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0; - } + for (w = 0; w < nWindows; w++) { + const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w; + TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w; + INT doSync = 1, absDiffSum = 0; + + /* if TNS is active in at least one channel, check if ParCor coefficients of + * higher filter are similar */ + if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { + for (i = 0; i < tC->maxOrder; i++) { + absDiff = fAbs(tnsInfoDest->coef[w][HIFILT][i] - + tnsInfoSrc->coef[w][HIFILT][i]); + absDiffSum += absDiff; + /* if coefficients diverge too much between channels, do not synchronize + */ + if ((absDiff > 1) || (absDiffSum > 2)) { + doSync = 0; + break; } + } + if (doSync) { + /* if no significant difference was detected, synchronize coefficient + * sets */ + if (pSbInfoSrcW->tnsActive[HIFILT]) { + /* no dest filter, or more dest than source filters: use one dest + * filter */ + if ((!pSbInfoDestW->tnsActive[HIFILT]) || + ((pSbInfoDestW->tnsActive[HIFILT]) && + (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) { + pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1; + } + tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; + tnsInfoDest->order[w][HIFILT] = tnsInfoSrc->order[w][HIFILT]; + tnsInfoDest->length[w][HIFILT] = tnsInfoSrc->length[w][HIFILT]; + tnsInfoDest->direction[w][HIFILT] = tnsInfoSrc->direction[w][HIFILT]; + tnsInfoDest->coefCompress[w][HIFILT] = + tnsInfoSrc->coefCompress[w][HIFILT]; + + for (i = 0; i < tC->maxOrder; i++) { + tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i]; + } + } else + pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0; + } } + } } /***************************************************************************/ @@ -990,218 +1048,130 @@ void FDKaacEnc_TnsSync( \return ERROR STATUS ****************************************************************************/ -INT FDKaacEnc_TnsEncode( - TNS_INFO* tnsInfo, - TNS_DATA* tnsData, - const INT numOfSfb, - const TNS_CONFIG *tC, - const INT lowPassLine, - FIXP_DBL* spectrum, - const INT subBlockNumber, - const INT blockType - ) -{ - INT i, startLine, stopLine; - - if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) ) - || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) ) - { - return 1; - } +INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData, + const INT numOfSfb, const TNS_CONFIG *tC, + const INT lowPassLine, FIXP_DBL *spectrum, + const INT subBlockNumber, const INT blockType) { + INT i, startLine, stopLine; + + if (((blockType == SHORT_WINDOW) && + (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] + .tnsActive[HIFILT])) || + ((blockType != SHORT_WINDOW) && + (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]))) { + return 1; + } - startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT] : tC->lpcStartLine[HIFILT]; - stopLine = tC->lpcStopLine; - - for (i=0; i<tnsInfo->numOfFilters[subBlockNumber]; i++) { - - INT lpcGainFactor; - FIXP_DBL LpcCoeff[TNS_MAX_ORDER]; - FIXP_DBL workBuffer[TNS_MAX_ORDER]; - FIXP_DBL parcor_tmp[TNS_MAX_ORDER]; - - FDKaacEnc_Index2Parcor( - tnsInfo->coef[subBlockNumber][i], - parcor_tmp, - tnsInfo->order[subBlockNumber][i], - tC->coefRes); - - lpcGainFactor = FDKaacEnc_ParcorToLpc( - parcor_tmp, - LpcCoeff, - tnsInfo->order[subBlockNumber][i], - workBuffer); - - FDKaacEnc_AnalysisFilter( - &spectrum[startLine], - stopLine - startLine, - LpcCoeff, - tnsInfo->order[subBlockNumber][i], - lpcGainFactor); - - /* update for second filter */ - startLine = tC->lpcStartLine[LOFILT]; - stopLine = tC->lpcStartLine[HIFILT]; - } + startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT] + : tC->lpcStartLine[HIFILT]; + stopLine = tC->lpcStopLine; + + for (i = 0; i < tnsInfo->numOfFilters[subBlockNumber]; i++) { + INT lpcGainFactor; + FIXP_LPC LpcCoeff[TNS_MAX_ORDER]; + FIXP_DBL workBuffer[TNS_MAX_ORDER]; + FIXP_LPC parcor_tmp[TNS_MAX_ORDER]; + + FDKaacEnc_Index2Parcor(tnsInfo->coef[subBlockNumber][i], parcor_tmp, + tnsInfo->order[subBlockNumber][i], tC->coefRes); + + lpcGainFactor = CLpc_ParcorToLpc( + parcor_tmp, LpcCoeff, tnsInfo->order[subBlockNumber][i], workBuffer); - return(0); + FDKmemclear(workBuffer, TNS_MAX_ORDER * sizeof(FIXP_DBL)); + CLpc_Analysis(&spectrum[startLine], stopLine - startLine, LpcCoeff, + lpcGainFactor, tnsInfo->order[subBlockNumber][i], workBuffer, + NULL); + /* update for second filter */ + startLine = tC->lpcStartLine[LOFILT]; + stopLine = tC->lpcStartLine[HIFILT]; + } + + return (0); } -static void FDKaacEnc_CalcGaussWindow( - FIXP_DBL *win, - const int winSize, - const INT samplingRate, - const INT transformResolution, - const FIXP_DBL timeResolution, - const INT timeResolution_e - ) -{ - #define PI_E (2) - #define PI_M FL2FXCONST_DBL(3.1416f/(float)(1<<PI_E)) +static void FDKaacEnc_CalcGaussWindow(FIXP_DBL *win, const int winSize, + const INT samplingRate, + const INT transformResolution, + const FIXP_DBL timeResolution, + const INT timeResolution_e) { +#define PI_E (2) +#define PI_M FL2FXCONST_DBL(3.1416f / (float)(1 << PI_E)) - #define EULER_E (2) - #define EULER_M FL2FXCONST_DBL(2.7183/(float)(1<<EULER_E)) +#define EULER_E (2) +#define EULER_M FL2FXCONST_DBL(2.7183 / (float)(1 << EULER_E)) - #define COEFF_LOOP_SCALE (4) +#define COEFF_LOOP_SCALE (4) INT i, e1, e2, gaussExp_e; FIXP_DBL gaussExp_m; /* calc. window exponent from time resolution: * - * gaussExp = PI * samplingRate * 0.001f * timeResolution / transformResolution; - * gaussExp = -0.5f * gaussExp * gaussExp; + * gaussExp = PI * samplingRate * 0.001f * timeResolution / + * transformResolution; gaussExp = -0.5f * gaussExp * gaussExp; */ - gaussExp_m = fMultNorm(timeResolution, fMult(PI_M, fDivNorm( (FIXP_DBL)(samplingRate), (FIXP_DBL)(LONG)(transformResolution*1000.f), &e1)), &e2); + gaussExp_m = fMultNorm( + timeResolution, + fMult(PI_M, + fDivNorm((FIXP_DBL)(samplingRate), + (FIXP_DBL)(LONG)(transformResolution * 1000.f), &e1)), + &e2); gaussExp_m = -fPow2Div2(gaussExp_m); - gaussExp_e = 2*(e1+e2+timeResolution_e+PI_E); + gaussExp_e = 2 * (e1 + e2 + timeResolution_e + PI_E); - FDK_ASSERT( winSize < (1<<COEFF_LOOP_SCALE) ); + FDK_ASSERT(winSize < (1 << COEFF_LOOP_SCALE)); /* calc. window coefficients * win[i] = (float)exp( gaussExp * (i+0.5) * (i+0.5) ); */ - for( i=0; i<winSize; i++) { - + for (i = 0; i < winSize; i++) { win[i] = fPow( - EULER_M, - EULER_E, - fMult(gaussExp_m, fPow2((i*FL2FXCONST_DBL(1.f/(float)(1<<COEFF_LOOP_SCALE)) + FL2FXCONST_DBL(.5f/(float)(1<<COEFF_LOOP_SCALE))))), - gaussExp_e + 2*COEFF_LOOP_SCALE, - &e1); + EULER_M, EULER_E, + fMult(gaussExp_m, + fPow2((i * FL2FXCONST_DBL(1.f / (float)(1 << COEFF_LOOP_SCALE)) + + FL2FXCONST_DBL(.5f / (float)(1 << COEFF_LOOP_SCALE))))), + gaussExp_e + 2 * COEFF_LOOP_SCALE, &e1); win[i] = scaleValueSaturate(win[i], e1); } } +static INT FDKaacEnc_Search3(FIXP_LPC parcor) { + INT i, index = 0; -/***************************************************************************/ -/*! - \brief FDKaacEnc_AutoToParcor - - conversion autocorrelation to reflection coefficients - - \param pointer to input (acf) - \param pointer to output (reflection coefficients) - \param number of coefficients - - \return prediction gain -****************************************************************************/ -static INT FDKaacEnc_AutoToParcor( - FIXP_DBL *RESTRICT input, - FIXP_DBL *RESTRICT reflCoeff, - const INT numOfCoeff - ) -{ - INT i, j, scale=0; - FIXP_DBL tmp, parcorWorkBuffer[TNS_MAX_ORDER]; - INT predictionGain = (INT)(TNS_PREDGAIN_SCALE); - - FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer; - const FIXP_DBL autoCorr_0 = input[0]; - - FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL)); - - if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) { - return(predictionGain); - } - - FDKmemcpy(workBuffer,&input[1],numOfCoeff*sizeof(FIXP_DBL)); - for(i=0; i<numOfCoeff; i++) { - LONG sign = ((LONG)workBuffer[0] >> (DFRACT_BITS-1)); - tmp = (FIXP_DBL)((LONG)workBuffer[0]^sign); - - if(input[0]<tmp) - break; - - tmp = (FIXP_DBL)((LONG)schur_div(tmp, input[0], FRACT_BITS)^(~sign)); - reflCoeff[i] = tmp; - - for(j=numOfCoeff-i-1; j>=0; j--) { - FIXP_DBL accu1 = fMult(tmp, input[j]); - FIXP_DBL accu2 = fMult(tmp, workBuffer[j]); - workBuffer[j] += accu1; - input[j] += accu2; - } - - workBuffer++; - } - - tmp = fMult((FIXP_DBL)((LONG)TNS_PREDGAIN_SCALE<<21), fDivNorm(fAbs(autoCorr_0), fAbs(input[0]), &scale)); - if ( fMultDiv2(autoCorr_0, input[0])<FL2FXCONST_DBL(0.0f) ) { - tmp = -tmp; - } - predictionGain = (LONG)scaleValue(tmp,scale-21); - - return (predictionGain); -} - - -static INT FDKaacEnc_Search3(FIXP_DBL parcor) -{ - INT i, index=0; - - for(i=0;i<8;i++){ - if(parcor > FDKaacEnc_tnsCoeff3Borders[i]) - index=i; + for (i = 0; i < 8; i++) { + if (parcor > FDKaacEnc_tnsCoeff3Borders[i]) index = i; } - return(index-4); + return (index - 4); } -static INT FDKaacEnc_Search4(FIXP_DBL parcor) -{ - INT i, index=0; +static INT FDKaacEnc_Search4(FIXP_LPC parcor) { + INT i, index = 0; - for(i=0;i<16;i++){ - if(parcor > FDKaacEnc_tnsCoeff4Borders[i]) - index=i; + for (i = 0; i < 16; i++) { + if (parcor > FDKaacEnc_tnsCoeff4Borders[i]) index = i; } - return(index-8); + return (index - 8); } - /***************************************************************************** functionname: FDKaacEnc_Parcor2Index *****************************************************************************/ -static void FDKaacEnc_Parcor2Index( - const FIXP_DBL *parcor, - INT *RESTRICT index, - const INT order, - const INT bitsPerCoeff - ) -{ +static void FDKaacEnc_Parcor2Index(const FIXP_LPC *parcor, INT *RESTRICT index, + const INT order, const INT bitsPerCoeff) { INT i; - for(i=0; i<order; i++) { - if(bitsPerCoeff == 3) + for (i = 0; i < order; i++) { + if (bitsPerCoeff == 3) index[i] = FDKaacEnc_Search3(parcor[i]); else index[i] = FDKaacEnc_Search4(parcor[i]); } } - /***************************************************************************** functionname: FDKaacEnc_Index2Parcor @@ -1212,130 +1182,10 @@ static void FDKaacEnc_Parcor2Index( output: reflection coefficients *****************************************************************************/ -static void FDKaacEnc_Index2Parcor( - const INT *index, - FIXP_DBL *RESTRICT parcor, - const INT order, - const INT bitsPerCoeff - ) -{ +static void FDKaacEnc_Index2Parcor(const INT *index, FIXP_LPC *RESTRICT parcor, + const INT order, const INT bitsPerCoeff) { INT i; - for(i=0; i<order; i++) - parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i]+8] : FDKaacEnc_tnsEncCoeff3[index[i]+4]; + for (i = 0; i < order; i++) + parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i] + 8] + : FDKaacEnc_tnsEncCoeff3[index[i] + 4]; } - - -/***************************************************************************** - - functionname: FDKaacEnc_ParcorToLpc - description: conversion reflection coefficients to LPC coefficients - returns: Gain factor - input: reflection coefficients, no. of reflection coefficients <order>, - ptr. to work buffer (required size: order) - output: <order> LPC coefficients - -*****************************************************************************/ -static INT FDKaacEnc_ParcorToLpc( - const FIXP_DBL *reflCoeff, - FIXP_DBL *RESTRICT LpcCoeff, - const INT numOfCoeff, - FIXP_DBL *RESTRICT workBuffer - ) -{ - INT i, j; - INT shiftval, par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ - FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); - - LpcCoeff[0] = reflCoeff[0] >> par2LpcShiftVal; - for(i=1; i<numOfCoeff; i++) { - for(j=0; j<i; j++) { - workBuffer[j] = LpcCoeff[i-1-j]; - } - - for(j=0; j<i; j++) { - LpcCoeff[j] += fMult(reflCoeff[i],workBuffer[j]); - } - - LpcCoeff[i] = reflCoeff[i] >> par2LpcShiftVal; - } - - /* normalize LpcCoeff and calc shiftfactor */ - for(i=0; i<numOfCoeff; i++) { - maxVal = fixMax(maxVal,(FIXP_DBL)fixp_abs(LpcCoeff[i])); - } - - shiftval = CountLeadingBits(maxVal); - shiftval = (shiftval>=par2LpcShiftVal) ? par2LpcShiftVal : shiftval; - - for(i=0; i<numOfCoeff; i++) - LpcCoeff[i] = LpcCoeff[i]<<shiftval; - - return (par2LpcShiftVal - shiftval); -} - -/***************************************************************************/ -/*! - \brief FDKaacEnc_AnalysisFilter - - TNS analysis filter (all-zero filter) - - \param pointer to signal spectrum - \param number of lines - \param pointer to lpc coefficients - \param filter order - \param lpc gain factor - - \return void -****************************************************************************/ -/* Note: in-place computation possible */ -static void FDKaacEnc_AnalysisFilter( - FIXP_DBL *RESTRICT signal, - const INT numOfLines, - const FIXP_DBL *predictorCoeff, - const INT order, - const INT lpcGainFactor - ) -{ - FIXP_DBL statusVar[TNS_MAX_ORDER]; - INT i, j; - const INT shift = lpcGainFactor + 1; /* +1, because fMultDiv2 */ - FIXP_DBL tmp; - - if (order>0) { - - INT idx = 0; - - /* keep filter coefficients twice and save memory copy operation in - modulo state buffer */ -#if defined(ARCH_PREFER_MULT_32x16) - FIXP_SGL coeff[2*TNS_MAX_ORDER]; - const FIXP_SGL *pCoeff; - for(i=0;i<order;i++) { - coeff[i] = FX_DBL2FX_SGL(predictorCoeff[i]); - } - FDKmemcpy(&coeff[order], coeff, order*sizeof(FIXP_SGL)); -#else - FIXP_DBL coeff[2*TNS_MAX_ORDER]; - const FIXP_DBL *pCoeff; - FDKmemcpy(&coeff[0], predictorCoeff, order*sizeof(FIXP_DBL)); - FDKmemcpy(&coeff[order], predictorCoeff, order*sizeof(FIXP_DBL)); -#endif - FDKmemclear(statusVar, order*sizeof(FIXP_DBL)); - - for(j=0; j<numOfLines; j++) { - pCoeff = &coeff[(order-idx)]; - tmp = FL2FXCONST_DBL(0); - for(i=0; i<order; i++) { - tmp = fMultAddDiv2(tmp, pCoeff[i], statusVar[i]) ; - } - - if(--idx<0) { idx = order-1; } - statusVar[idx] = signal[j]; - - FDK_ASSERT(lpcGainFactor>=0); - signal[j] = (tmp<<shift) + signal[j]; - } - } -} - - diff --git a/libAACenc/src/aacenc_tns.h b/libAACenc/src/aacenc_tns.h index 2824cbc..a37f978 100644 --- a/libAACenc/src/aacenc_tns.h +++ b/libAACenc/src/aacenc_tns.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,25 +90,25 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): Alex Groeschel - Initial author: Alex Groeschel - contents/description: Temporal noise shaping + Description: Temporal noise shaping -******************************************************************************/ +*******************************************************************************/ -#ifndef _TNS_H -#define _TNS_H +#ifndef AACENC_TNS_H +#define AACENC_TNS_H #include "common_fix.h" #include "psy_const.h" - #ifndef PI -#define PI 3.1415926535897931f +#define PI 3.1415926535897931f #endif /** @@ -114,32 +125,33 @@ amm-info@iis.fraunhofer.de /* TNS max filter order for Low Complexity MPEG4 profile */ #define TNS_MAX_ORDER 12 - #define MAX_NUM_OF_FILTERS 2 -#define HIFILT 0 /* index of higher filter */ -#define LOFILT 1 /* index of lower filter */ - - -typedef struct{ /* stuff that is tabulated dependent on bitrate etc. */ - INT filterEnabled[MAX_NUM_OF_FILTERS]; - INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns TABUL*/ - INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/ - INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/ - INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, 1=down TABUL */ - INT acfSplit[MAX_NUM_OF_FILTERS]; - FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution TABUL. Should be fract but MSVC won't compile then */ - INT seperateFiltersAllowed; +#define HIFILT 0 /* index of higher filter */ +#define LOFILT 1 /* index of lower filter */ + +typedef struct { /* stuff that is tabulated dependent on bitrate etc. */ + INT filterEnabled[MAX_NUM_OF_FILTERS]; + INT threshOn[MAX_NUM_OF_FILTERS]; /* min. prediction gain for using tns + TABUL*/ + INT filterStartFreq[MAX_NUM_OF_FILTERS]; /* lowest freq for lpc TABUL*/ + INT tnsLimitOrder[MAX_NUM_OF_FILTERS]; /* Limit for TNS order TABUL*/ + INT tnsFilterDirection[MAX_NUM_OF_FILTERS]; /* Filtering direction, 0=up, + 1=down TABUL */ + INT acfSplit[MAX_NUM_OF_FILTERS]; + FIXP_DBL tnsTimeResolution[MAX_NUM_OF_FILTERS]; /* TNS max. time resolution + TABUL. Should be fract but + MSVC won't compile then */ + INT seperateFiltersAllowed; } TNS_PARAMETER_TABULATED; - -typedef struct { /*assigned at InitTime*/ +typedef struct { /*assigned at InitTime*/ TNS_PARAMETER_TABULATED confTab; INT isLowDelay; INT tnsActive; - INT maxOrder; /* max. order of tns filter */ + INT maxOrder; /* max. order of tns filter */ INT coefRes; - FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1]; + FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER + 3 + 1]; /* now some things that only probably can be done at Init time; could be they have to be split up for each individual (short) window or even filter. */ @@ -148,55 +160,54 @@ typedef struct { /*assigned at InitTime*/ INT lpcStopBand; INT lpcStopLine; -}TNS_CONFIG; - +} TNS_CONFIG; typedef struct { - INT tnsActive[MAX_NUM_OF_FILTERS]; - INT predictionGain[MAX_NUM_OF_FILTERS]; + INT tnsActive[MAX_NUM_OF_FILTERS]; + INT predictionGain[MAX_NUM_OF_FILTERS]; } TNS_SUBBLOCK_INFO; -typedef struct{ /*changed at runTime*/ +typedef struct { /*changed at runTime*/ TNS_SUBBLOCK_INFO subBlockInfo[TRANS_FAC]; FIXP_DBL ratioMultTable[TRANS_FAC][MAX_SFB_SHORT]; } TNS_DATA_SHORT; -typedef struct{ /*changed at runTime*/ +typedef struct { /*changed at runTime*/ TNS_SUBBLOCK_INFO subBlockInfo; FIXP_DBL ratioMultTable[MAX_SFB_LONG]; } TNS_DATA_LONG; /* can be implemented as union */ -typedef shouldBeUnion{ +typedef shouldBeUnion { TNS_DATA_LONG Long; TNS_DATA_SHORT Short; -}TNS_DATA_RAW; +} +TNS_DATA_RAW; -typedef struct{ +typedef struct { INT numOfSubblocks; TNS_DATA_RAW dataRaw; INT tnsMaxScaleSpec; INT filtersMerged; -}TNS_DATA; +} TNS_DATA; -typedef struct{ +typedef struct { INT numOfFilters[TRANS_FAC]; INT coefRes[TRANS_FAC]; INT length[TRANS_FAC][MAX_NUM_OF_FILTERS]; INT order[TRANS_FAC][MAX_NUM_OF_FILTERS]; INT direction[TRANS_FAC][MAX_NUM_OF_FILTERS]; INT coefCompress[TRANS_FAC][MAX_NUM_OF_FILTERS]; - /* for Long: length TNS_MAX_ORDER (12 for LC) is required -> 12 */ - /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required -> 8*5=40 */ - /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per channel)! Memory could be saved here! */ + /* for Long: length TNS_MAX_ORDER (12 for LC) is required -> 12 */ + /* for Short: length TRANS_FAC*TNS_MAX_ORDER (only 5 for short LC) is required + * -> 8*5=40 */ + /* Currently TRANS_FAC*TNS_MAX_ORDER = 8*12 = 96 (for LC) is used (per + * channel)! Memory could be saved here! */ INT coef[TRANS_FAC][MAX_NUM_OF_FILTERS][TNS_MAX_ORDER]; -}TNS_INFO; +} TNS_INFO; -INT FDKaacEnc_FreqToBandWithRounding( - const INT freq, - const INT fs, - const INT numOfBands, - const INT *bandStartOffset - ); +INT FDKaacEnc_FreqToBandWidthRounding(const INT freq, const INT fs, + const INT numOfBands, + const INT *bandStartOffset); -#endif /* _TNS_H */ +#endif /* AACENC_TNS_H */ diff --git a/libAACenc/src/adj_thr.cpp b/libAACenc/src/adj_thr.cpp index 09584f4..6e19680 100644 --- a/libAACenc/src/adj_thr.cpp +++ b/libAACenc/src/adj_thr.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,889 +90,1015 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Threshold compensation + Author(s): M. Werner -******************************************************************************/ + Description: Threshold compensation -#include "common_fix.h" +*******************************************************************************/ -#include "adj_thr_data.h" #include "adj_thr.h" -#include "qc_data.h" #include "sf_estim.h" #include "aacEnc_ram.h" +#define NUM_NRG_LEVS (8) +#define INV_INT_TAB_SIZE (8) +static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = { + 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa, + 0x20000000, 0x19999999, 0x15555555, 0x12492492}; - - -#define INV_INT_TAB_SIZE (8) -static const FIXP_DBL invInt[INV_INT_TAB_SIZE] = -{ - 0x7fffffff, 0x7fffffff, 0x40000000, 0x2aaaaaaa, 0x20000000, 0x19999999, 0x15555555, 0x12492492 -}; - - -#define INV_SQRT4_TAB_SIZE (8) -static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = -{ - 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5, 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1 -}; - +#define INV_SQRT4_TAB_SIZE (8) +static const FIXP_DBL invSqrt4[INV_SQRT4_TAB_SIZE] = { + 0x7fffffff, 0x7fffffff, 0x6ba27e65, 0x61424bb5, + 0x5a827999, 0x55994845, 0x51c8e33c, 0x4eb160d1}; /*static const INT invRedExp = 4;*/ -static const FIXP_DBL SnrLdMin1 = (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin2 = (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdFac = (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8) /FDKlog(2.0)/LD_DATA_SCALING);*/ - -static const FIXP_DBL SnrLdMin3 = (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin4 = (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0) /FDKlog(2.0)/LD_DATA_SCALING);*/ -static const FIXP_DBL SnrLdMin5 = (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25) /FDKlog(2.0)/LD_DATA_SCALING);*/ - +static const FIXP_DBL SnrLdMin1 = + (FIXP_DBL)0xfcad0ddf; /*FL2FXCONST_DBL(FDKlog(0.316)/FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin2 = + (FIXP_DBL)0x0351e1a2; /*FL2FXCONST_DBL(FDKlog(3.16) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdFac = + (FIXP_DBL)0xff5b2c3e; /*FL2FXCONST_DBL(FDKlog(0.8) + /FDKlog(2.0)/LD_DATA_SCALING);*/ + +static const FIXP_DBL SnrLdMin3 = + (FIXP_DBL)0xfe000000; /*FL2FXCONST_DBL(FDKlog(0.5) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin4 = + (FIXP_DBL)0x02000000; /*FL2FXCONST_DBL(FDKlog(2.0) + /FDKlog(2.0)/LD_DATA_SCALING);*/ +static const FIXP_DBL SnrLdMin5 = + (FIXP_DBL)0xfc000000; /*FL2FXCONST_DBL(FDKlog(0.25) + /FDKlog(2.0)/LD_DATA_SCALING);*/ /* The bits2Pe factors are choosen for the case that some times the crash recovery strategy will be activated once. */ +#define AFTERBURNER_STATI 2 +#define MAX_ALLOWED_EL_CHANNELS 2 typedef struct { - INT bitrate; - ULONG bits2PeFactor_mono; - ULONG bits2PeFactor_mono_slope; - ULONG bits2PeFactor_stereo; - ULONG bits2PeFactor_stereo_slope; - ULONG bits2PeFactor_mono_scfOpt; - ULONG bits2PeFactor_mono_scfOpt_slope; - ULONG bits2PeFactor_stereo_scfOpt; - ULONG bits2PeFactor_stereo_scfOpt_slope; - + INT bitrate; + FIXP_DBL bits2PeFactor[AFTERBURNER_STATI][MAX_ALLOWED_EL_CHANNELS]; } BIT_PE_SFAC; typedef struct { - const INT sampleRate; - const BIT_PE_SFAC * pPeTab; - const INT nEntries; + INT sampleRate; + const BIT_PE_SFAC *pPeTab; + INT nEntries; } BITS2PE_CFG_TAB; +#define FL2B2PE(value) FL2FXCONST_DBL((value) / (1 << 2)) + static const BIT_PE_SFAC S_Bits2PeTab16000[] = { - { 10000, 0x228F5C29, 0x02FEF55D, 0x1D70A3D7, 0x09BC9D6D, 0x228F5C29, 0x02FEF55D, 0x1C28F5C3, 0x0CBB92CA}, - { 24000, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413, 0x23D70A3D, 0x029F16B1, 0x2199999A, 0x07DD4413}, - { 32000, 0x247AE148, 0x11B1D92B, 0x23851EB8, 0x01F75105, 0x247AE148, 0x110A137F, 0x23851EB8, 0x01F75105}, - { 48000, 0x2D1EB852, 0x6833C600, 0x247AE148, 0x014F8B59, 0x2CCCCCCD, 0x68DB8BAC, 0x247AE148, 0x01F75105}, - { 64000, 0x25c28f40, 0x00000000, 0x251EB852, 0x01480000, 0x25c28f40, 0x00000000, 0x2570A3D7, 0x01480000}, - { 96000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000, 0x25c28f40, 0x00000000, 0x26000000, 0x01000000}, - {128000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000, 0x25c28f40, 0x00000000, 0x270a3d80, 0x01000000}, - {148000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000, 0x25c28f40, 0x00000000, 0x28000000, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {10000, + {{FL2B2PE(1.60f), FL2B2PE(0.00f)}, {FL2B2PE(1.40f), FL2B2PE(0.00f)}}}, + {24000, + {{FL2B2PE(1.80f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {32000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {48000, + {{FL2B2PE(1.60f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {64000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.60f)}}}, + {96000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab22050[] = { - { 16000, 0x1a8f5c29, 0x1797cc3a, 0x128f5c29, 0x18e75793, 0x175c28f6, 0x221426fe, 0x00000000, 0x5a708ede}, - { 24000, 0x2051eb85, 0x092ccf6c, 0x18a3d70a, 0x13a92a30, 0x1fae147b, 0xbcbe61d, 0x16147ae1, 0x18e75793}, - { 32000, 0x228f5c29, 0x029f16b1, 0x1d70a3d7, 0x088509c0, 0x228f5c29, 0x29f16b1, 0x1c28f5c3, 0x0b242071}, - { 48000, 0x23d70a3d, 0x014f8b59, 0x2199999a, 0x03eea20a, 0x23d70a3d, 0x14f8b59, 0x2199999a, 0x03eea20a}, - { 64000, 0x247ae148, 0x08d8ec96, 0x23851eb8, 0x00fba882, 0x247ae148, 0x88509c0, 0x23851eb8, 0x00fba882}, - { 96000, 0x2d1eb852, 0x3419e300, 0x247ae148, 0x00a7c5ac, 0x2ccccccd, 0x346dc5d6, 0x247ae148, 0x00fba882}, - {128000, 0x25c28f40, 0x00000000, 0x251eb852, 0x029f16b1, 0x60000000, 0x25c28f40, 0x2570a3d7, 0x009f16b1}, - {148000, 0x25c28f40, 0x00000000, 0x26b851ec, 0x00000000, 0x60000000, 0x25c28f40, 0x270a3d71, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}}, + {32000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.40f), FL2B2PE(1.20f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.20f), FL2B2PE(1.40f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {96000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.80f), FL2B2PE(1.80f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.80f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab24000[] = { - { 16000, 0x19eb851f, 0x13a92a30, 0x1147ae14, 0x164840e1, 0x1999999a, 0x12599ed8, 0x00000000, 0x46c764ae}, - { 24000, 0x1eb851ec, 0x0d1b7176, 0x16b851ec, 0x18e75793, 0x1e147ae1, 0x0fba8827, 0x1147ae14, 0x2c9081c3}, - { 32000, 0x21eb851f, 0x049667b6, 0x1ccccccd, 0x07357e67, 0x21eb851f, 0x03eea20a, 0x1c28f5c3, 0x07357e67}, - { 48000, 0x2428f5c3, 0x014f8b59, 0x2051eb85, 0x053e2d62, 0x23d70a3d, 0x01f75105, 0x1fae147b, 0x07357e67}, - { 64000, 0x24cccccd, 0x05e5f30e, 0x22e147ae, 0x01a36e2f, 0x24cccccd, 0x05e5f30e, 0x23333333, 0x014f8b59}, - { 96000, 0x2a8f5c29, 0x24b33db0, 0x247ae148, 0x00fba882, 0x2a8f5c29, 0x26fe718b, 0x247ae148, 0x00fba882}, - {128000, 0x4e666666, 0x1cd5f99c, 0x2570a3d7, 0x010c6f7a, 0x50a3d70a, 0x192a7371, 0x2570a3d7, 0x010c6f7a}, - {148000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000, 0x25c28f40, 0x00000000, 0x26147ae1, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(1.00f)}}}, + {32000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.40f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.40f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {96000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {128000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.80f)}}}, + {148000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.80f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab32000[] = { - { 16000, 0x247ae140, 0xFFFFAC1E, 0x270a3d80, 0xFFFE9B7C, 0x14ccccc0, 0x000110A1, 0x15c28f60, 0xFFFEEF5F}, - { 24000, 0x23333340, 0x0fba8827, 0x21999980, 0x1b866e44, 0x18f5c280, 0x0fba8827, 0x119999a0, 0x4d551d69}, - { 32000, 0x1d70a3d7, 0x07357e67, 0x17ae147b, 0x09d49518, 0x1b851eb8, 0x0a7c5ac4, 0x12e147ae, 0x110a137f}, - { 48000, 0x20f5c28f, 0x049667b6, 0x1c7ae148, 0x053e2d62, 0x20a3d70a, 0x053e2d62, 0x1b333333, 0x05e5f30e}, - { 64000, 0x23333333, 0x029f16b1, 0x1f0a3d71, 0x02f2f987, 0x23333333, 0x029f16b1, 0x1e147ae1, 0x03eea20a}, - { 96000, 0x25c28f5c, 0x2c3c9eed, 0x21eb851f, 0x01f75105, 0x25c28f5c, 0x0a7c5ac4, 0x21eb851f, 0x01a36e2f}, - {128000, 0x50f5c28f, 0x18a43bb4, 0x23d70a3d, 0x010c6f7a, 0x30000000, 0x168b5cc0, 0x23851eb8, 0x0192a737}, - {148000, 0x25c28f40, 0x00000000, 0x247ae148, 0x00dfb23b, 0x3dc28f5c, 0x300f4aaf, 0x247ae148, 0x01bf6476}, - {160000, 0x25c28f40, 0xb15b5740, 0x24cccccd, 0x053e2d62, 0x4f5c28f6, 0xbefd0072, 0x251eb852, 0x04fb1184}, - {200000, 0x25c28f40, 0x00000000, 0x2b333333, 0x0836be91, 0x25c28f40, 0x00000000, 0x2b333333, 0x0890390f}, - {320000, 0x25c28f40, 0x00000000, 0x4947ae14, 0x00000000, 0x25c28f40, 0x00000000, 0x4a8f5c29, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.20f), FL2B2PE(1.40f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}}, + {24000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.60f)}}}, + {32000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.40f), FL2B2PE(1.40f)}, {FL2B2PE(1.20f), FL2B2PE(1.20f)}}}, + {64000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {128000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {148000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {160000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.80f), FL2B2PE(1.60f)}}}, + {200000, + {{FL2B2PE(1.40f), FL2B2PE(1.60f)}, {FL2B2PE(1.40f), FL2B2PE(1.60f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.80f)}, {FL2B2PE(3.20f), FL2B2PE(1.80f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab44100[] = { - { 16000, 0x10a3d70a, 0x1797cc3a, 0x00000000, 0x00000000, 0x00000000, 0x59210386, 0x00000000, 0x00000000}, - { 24000, 0x16666666, 0x1797cc3a, 0x00000000, 0x639d5e4a, 0x15c28f5c, 0x12599ed8, 0x00000000, 0x5bc01a37}, - { 32000, 0x1c28f5c3, 0x049667b6, 0x1851eb85, 0x049667b6, 0x1a3d70a4, 0x088509c0, 0x16666666, 0x053e2d62}, - { 48000, 0x1e666666, 0x05e5f30e, 0x1a8f5c29, 0x049667b6, 0x1e666666, 0x05e5f30e, 0x18f5c28f, 0x05e5f30e}, - { 64000, 0x2147ae14, 0x0346dc5d, 0x1ccccccd, 0x02f2f987, 0x2147ae14, 0x02f2f987, 0x1bd70a3d, 0x039abf34}, - { 96000, 0x247ae148, 0x068db8bb, 0x1fae147b, 0x029f16b1, 0x2428f5c3, 0x0639d5e5, 0x1f5c28f6, 0x029f16b1}, - {128000, 0x2ae147ae, 0x1b435265, 0x223d70a4, 0x0192a737, 0x2a3d70a4, 0x1040bfe4, 0x21eb851f, 0x0192a737}, - {148000, 0x3b851eb8, 0x2832069c, 0x23333333, 0x00dfb23b, 0x3428f5c3, 0x2054c288, 0x22e147ae, 0x00dfb23b}, - {160000, 0x4a3d70a4, 0xc32ebe5a, 0x23851eb8, 0x01d5c316, 0x40000000, 0xcb923a2b, 0x23333333, 0x01d5c316}, - {200000, 0x25c28f40, 0x00000000, 0x25c28f5c, 0x0713f078, 0x25c28f40, 0x00000000, 0x2570a3d7, 0x072a4f17}, - {320000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000, 0x25c28f40, 0x00000000, 0x3fae147b, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(0.80f), FL2B2PE(1.00f)}}}, + {24000, + {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {32000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(0.80f), FL2B2PE(0.60f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(0.80f)}}}, + {64000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.20f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {128000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {148000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {160000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {200000, + {{FL2B2PE(1.80f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.60f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}}; static const BIT_PE_SFAC S_Bits2PeTab48000[] = { - { 16000, 0x0f5c28f6, 0x31ceaf25, 0x00000000, 0x00000000, 0x00000000, 0x74a771c9, 0x00000000, 0x00000000}, - { 24000, 0x1b851eb8, 0x029f16b1, 0x00000000, 0x663c74fb, 0x1c7ae148, 0xe47991bd, 0x00000000, 0x49667b5f}, - { 32000, 0x1c28f5c3, 0x029f16b1, 0x18f5c28f, 0x07357e67, 0x15c28f5c, 0x0f12c27a, 0x11eb851f, 0x13016484}, - { 48000, 0x1d70a3d7, 0x053e2d62, 0x1c7ae148, 0xfe08aefc, 0x1d1eb852, 0x068db8bb, 0x1b333333, 0xfeb074a8}, - { 64000, 0x20000000, 0x03eea20a, 0x1b851eb8, 0x0346dc5d, 0x2051eb85, 0x0346dc5d, 0x1a8f5c29, 0x039abf34}, - { 96000, 0x23d70a3d, 0x053e2d62, 0x1eb851ec, 0x029f16b1, 0x23851eb8, 0x04ea4a8c, 0x1e147ae1, 0x02f2f987}, - {128000, 0x28f5c28f, 0x14727dcc, 0x2147ae14, 0x0218def4, 0x2851eb85, 0x0e27e0f0, 0x20f5c28f, 0x0218def4}, - {148000, 0x3570a3d7, 0x1cd5f99c, 0x228f5c29, 0x01bf6476, 0x30f5c28f, 0x18777e75, 0x223d70a4, 0x01bf6476}, - {160000, 0x40000000, 0xcb923a2b, 0x23333333, 0x0192a737, 0x39eb851f, 0xd08d4bae, 0x22e147ae, 0x0192a737}, - {200000, 0x25c28f40, 0x00000000, 0x251eb852, 0x06775a1b, 0x25c28f40, 0x00000000, 0x24cccccd, 0x06a4175a}, - {320000, 0x25c28f40, 0x00000000, 0x3ccccccd, 0x00000000, 0x25c28f40, 0x00000000, 0x3d1eb852, 0x00000000} -}; + /* bitrate| afterburner off | afterburner on | | nCh=1 + | nCh=2 | nCh=1 | nCh=2 */ + {16000, + {{FL2B2PE(1.40f), FL2B2PE(0.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.00f)}}}, + {24000, + {{FL2B2PE(1.40f), FL2B2PE(1.20f)}, {FL2B2PE(1.00f), FL2B2PE(0.80f)}}}, + {32000, + {{FL2B2PE(1.00f), FL2B2PE(1.20f)}, {FL2B2PE(0.60f), FL2B2PE(0.80f)}}}, + {48000, + {{FL2B2PE(1.20f), FL2B2PE(1.00f)}, {FL2B2PE(0.80f), FL2B2PE(0.80f)}}}, + {64000, + {{FL2B2PE(1.20f), FL2B2PE(1.20f)}, {FL2B2PE(1.20f), FL2B2PE(1.00f)}}}, + {96000, + {{FL2B2PE(1.60f), FL2B2PE(1.40f)}, {FL2B2PE(1.60f), FL2B2PE(1.20f)}}}, + {128000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {148000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {160000, + {{FL2B2PE(1.60f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {200000, + {{FL2B2PE(1.20f), FL2B2PE(1.60f)}, {FL2B2PE(1.60f), FL2B2PE(1.40f)}}}, + {320000, + {{FL2B2PE(3.20f), FL2B2PE(1.60f)}, {FL2B2PE(3.20f), FL2B2PE(1.60f)}}}}; static const BITS2PE_CFG_TAB bits2PeConfigTab[] = { - { 16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000)/sizeof(BIT_PE_SFAC) }, - { 22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050)/sizeof(BIT_PE_SFAC) }, - { 24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000)/sizeof(BIT_PE_SFAC) }, - { 32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000)/sizeof(BIT_PE_SFAC) }, - { 44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100)/sizeof(BIT_PE_SFAC) }, - { 48000, S_Bits2PeTab48000, sizeof(S_Bits2PeTab48000)/sizeof(BIT_PE_SFAC) } -}; - - + {16000, S_Bits2PeTab16000, sizeof(S_Bits2PeTab16000) / sizeof(BIT_PE_SFAC)}, + {22050, S_Bits2PeTab22050, sizeof(S_Bits2PeTab22050) / sizeof(BIT_PE_SFAC)}, + {24000, S_Bits2PeTab24000, sizeof(S_Bits2PeTab24000) / sizeof(BIT_PE_SFAC)}, + {32000, S_Bits2PeTab32000, sizeof(S_Bits2PeTab32000) / sizeof(BIT_PE_SFAC)}, + {44100, S_Bits2PeTab44100, sizeof(S_Bits2PeTab44100) / sizeof(BIT_PE_SFAC)}, + {48000, S_Bits2PeTab48000, + sizeof(S_Bits2PeTab48000) / sizeof(BIT_PE_SFAC)}}; /* values for avoid hole flag */ -enum _avoid_hole_state { - NO_AH =0, - AH_INACTIVE =1, - AH_ACTIVE =2 -}; - +enum _avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 }; /* Q format definitions */ -#define Q_BITFAC (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */ -#define Q_AVGBITS (17) /* scale bit values */ - +#define Q_BITFAC \ + (24) /* Q scaling used in FDKaacEnc_bitresCalcBitFac() calculation */ +#define Q_AVGBITS (17) /* scale bit values */ /***************************************************************************** functionname: FDKaacEnc_InitBits2PeFactor description: retrieve bits2PeFactor from table *****************************************************************************/ static void FDKaacEnc_InitBits2PeFactor( - FIXP_DBL *bits2PeFactor_m, - INT *bits2PeFactor_e, - const INT bitRate, - const INT nChannels, - const INT sampleRate, - const INT advancedBitsToPe, - const INT dZoneQuantEnable, - const INT invQuant - ) -{ - /* default bits2pe factor */ - FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f/(1<<(1))); - INT bit2PE_e = 1; - - /* make use of advanced bits to pe factor table */ - if (advancedBitsToPe) { - + FIXP_DBL *bits2PeFactor_m, INT *bits2PeFactor_e, const INT bitRate, + const INT nChannels, const INT sampleRate, const INT advancedBitsToPe, + const INT dZoneQuantEnable, const INT invQuant) { + /**** 1) Set default bits2pe factor ****/ + FIXP_DBL bit2PE_m = FL2FXCONST_DBL(1.18f / (1 << (1))); + INT bit2PE_e = 1; + + /**** 2) For AAC-(E)LD, make use of advanced bits to pe factor table ****/ + if (advancedBitsToPe && nChannels <= (2)) { int i; const BIT_PE_SFAC *peTab = NULL; INT size = 0; - - /* Get correct table entry */ - for (i=0; i<(INT)(sizeof(bits2PeConfigTab)/sizeof(BITS2PE_CFG_TAB)); i++) { + /*** 2.1) Get correct table entry ***/ + for (i = 0; i < (INT)(sizeof(bits2PeConfigTab) / sizeof(BITS2PE_CFG_TAB)); + i++) { if (sampleRate >= bits2PeConfigTab[i].sampleRate) { peTab = bits2PeConfigTab[i].pPeTab; - size = bits2PeConfigTab[i].nEntries; + size = bits2PeConfigTab[i].nEntries; } } - if ( (peTab!=NULL) && (size!=0) ) { - - INT startB = -1; - LONG startPF = 0; - LONG peSlope = 0; - - /* stereo or mono mode and invQuant used or not */ - for (i=0; i<size-1; i++) - { - if ((peTab[i].bitrate<=bitRate) && ((peTab[i+1].bitrate>bitRate) || ((i==size-2)) )) - { - if (nChannels==1) - { - startPF = (!invQuant) ? peTab[i].bits2PeFactor_mono : peTab[i].bits2PeFactor_mono_scfOpt; - peSlope = (!invQuant) ? peTab[i].bits2PeFactor_mono_slope : peTab[i].bits2PeFactor_mono_scfOpt_slope; - /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_mono : peTab[i+1].bits2PeFactor_mono_scfOpt; - endB=peTab[i+1].bitrate;*/ - startB=peTab[i].bitrate; - break; - } - else - { - startPF = (!invQuant) ? peTab[i].bits2PeFactor_stereo : peTab[i].bits2PeFactor_stereo_scfOpt; - peSlope = (!invQuant) ? peTab[i].bits2PeFactor_stereo_slope : peTab[i].bits2PeFactor_stereo_scfOpt_slope; - /*endPF = (!invQuant) ? peTab[i+1].bits2PeFactor_stereo : peTab[i+1].bits2PeFactor_stereo_scfOpt; - endB=peTab[i+1].bitrate;*/ - startB=peTab[i].bitrate; + if ((peTab != NULL) && (size != 0)) { + INT startB = -1; /* bitrate entry in table that is the next-lower to + actual bitrate */ + INT stopB = -1; /* bitrate entry in table that is the next-higher to + actual bitrate */ + FIXP_DBL startPF = + FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table that is the + next-lower to actual bits2PE factor */ + FIXP_DBL stopPF = FL2FXCONST_DBL(0.0f); /* bits2PE factor entry in table + that is the next-higher to + actual bits2PE factor */ + FIXP_DBL slope = FL2FXCONST_DBL( + 0.0f); /* the slope from the start bits2Pe entry to the next one */ + const int qualityIdx = (invQuant == 0) ? 0 : 1; + + if (bitRate >= peTab[size - 1].bitrate) { + /* Chosen bitrate is higher than the highest bitrate in table. + The slope for extrapolating the bits2PE factor must be zero. + Values are set accordingly. */ + startB = peTab[size - 1].bitrate; + stopB = + bitRate + + 1; /* Can be an arbitrary value greater than startB and bitrate. */ + startPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1]; + stopPF = peTab[size - 1].bits2PeFactor[qualityIdx][nChannels - 1]; + } else { + for (i = 0; i < size - 1; i++) { + if ((peTab[i].bitrate <= bitRate) && + (peTab[i + 1].bitrate > bitRate)) { + startB = peTab[i].bitrate; + stopB = peTab[i + 1].bitrate; + startPF = peTab[i].bits2PeFactor[qualityIdx][nChannels - 1]; + stopPF = peTab[i + 1].bits2PeFactor[qualityIdx][nChannels - 1]; break; } } - } /* for i */ + } - /* if a configuration is available */ - if (startB!=-1) { - /* linear interpolate to actual PEfactor */ - FIXP_DBL peFac = fMult((FIXP_DBL)(bitRate-startB)<<14, (FIXP_DBL)peSlope) << 2; - FIXP_DBL bit2PE = peFac + (FIXP_DBL)startPF; /* startPF_float = startPF << 2 */ + /*** 2.2) Configuration available? ***/ + if (startB != -1) { + /** 2.2.1) linear interpolate to actual PEfactor **/ + FIXP_DBL bit2PE = 0; - /* sanity check if bits2pe value is high enough */ - if ( bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2) ) { + const FIXP_DBL maxBit2PE = FL2FXCONST_DBL(3.f / 4.f); + + /* bit2PE = ((stopPF-startPF)/(stopB-startB))*(bitRate-startB)+startPF; + */ + slope = fDivNorm(bitRate - startB, stopB - startB); + bit2PE = fMult(slope, stopPF - startPF) + startPF; + + bit2PE = fMin(maxBit2PE, bit2PE); + + /** 2.2.2) sanity check if bits2pe value is high enough **/ + if (bit2PE >= (FL2FXCONST_DBL(0.35f) >> 2)) { bit2PE_m = bit2PE; bit2PE_e = 2; /* table is fixed scaled */ } } /* br */ - } /* sr */ - } /* advancedBitsToPe */ + } /* sr */ + } /* advancedBitsToPe */ - - if (dZoneQuantEnable) - { - if(bit2PE_m >= (FL2FXCONST_DBL(0.6f))>>bit2PE_e) - { + if (dZoneQuantEnable) { + if (bit2PE_m >= (FL2FXCONST_DBL(0.6f)) >> bit2PE_e) { /* Additional headroom for addition */ bit2PE_m >>= 1; - bit2PE_e += 1; + bit2PE_e += 1; } - /* the quantTendencyCompensator compensates a lower bit consumption due to increasing the tendency to quantize low spectral values to the lower quantizer border for bitrates below a certain bitrate threshold --> see also function calcSfbDistLD in quantize.c */ - if ((bitRate/nChannels > 32000) && (bitRate/nChannels <= 40000)) { - bit2PE_m += (FL2FXCONST_DBL(0.4f))>>bit2PE_e; - } - else if (bitRate/nChannels > 20000) { - bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e; - } - else if (bitRate/nChannels >= 16000) { - bit2PE_m += (FL2FXCONST_DBL(0.3f))>>bit2PE_e; - } - else { - bit2PE_m += (FL2FXCONST_DBL(0.0f))>>bit2PE_e; + /* the quantTendencyCompensator compensates a lower bit consumption due to + * increasing the tendency to quantize low spectral values to the lower + * quantizer border for bitrates below a certain bitrate threshold --> see + * also function calcSfbDistLD in quantize.c */ + if ((bitRate / nChannels > 32000) && (bitRate / nChannels <= 40000)) { + bit2PE_m += (FL2FXCONST_DBL(0.4f)) >> bit2PE_e; + } else if (bitRate / nChannels > 20000) { + bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e; + } else if (bitRate / nChannels >= 16000) { + bit2PE_m += (FL2FXCONST_DBL(0.3f)) >> bit2PE_e; + } else { + bit2PE_m += (FL2FXCONST_DBL(0.0f)) >> bit2PE_e; } } - /***** 3.) Return bits2pe factor *****/ *bits2PeFactor_m = bit2PE_m; *bits2PeFactor_e = bit2PE_e; } - /***************************************************************************** functionname: FDKaacEnc_bits2pe2 description: convert from bits to pe *****************************************************************************/ -static INT FDKaacEnc_bits2pe2( - const INT bits, - const FIXP_DBL factor_m, - const INT factor_e - ) -{ - return (INT)(fMult(factor_m, (FIXP_DBL)(bits<<Q_AVGBITS)) >> (Q_AVGBITS-factor_e)); +FDK_INLINE INT FDKaacEnc_bits2pe2(const INT bits, const FIXP_DBL factor_m, + const INT factor_e) { + return (INT)(fMult(factor_m, (FIXP_DBL)(bits << Q_AVGBITS)) >> + (Q_AVGBITS - factor_e)); } /***************************************************************************** functionname: FDKaacEnc_calcThreshExp description: loudness calculation (threshold to the power of redExp) *****************************************************************************/ -static void FDKaacEnc_calcThreshExp(FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - const INT nChannels) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL thrExpLdData; - - for (ch=0; ch<nChannels; ch++) { - for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb]>>2 ; - thrExp[ch][sfbGrp+sfb] = CalcInvLdData(thrExpLdData); - } - } - } +static void FDKaacEnc_calcThreshExp( + FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) { + INT ch, sfb, sfbGrp; + FIXP_DBL thrExpLdData; + + for (ch = 0; ch < nChannels; ch++) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + thrExpLdData = psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] >> 2; + thrExp[ch][sfbGrp + sfb] = CalcInvLdData(thrExpLdData); + } + } + } } - /***************************************************************************** functionname: FDKaacEnc_adaptMinSnr - description: reduce minSnr requirements for bands with relative low energies + description: reduce minSnr requirements for bands with relative low +energies *****************************************************************************/ -static void FDKaacEnc_adaptMinSnr(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - MINSNR_ADAPT_PARAM *msaParam, - const INT nChannels) -{ +static void FDKaacEnc_adaptMinSnr( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const MINSNR_ADAPT_PARAM *const msaParam, const INT nChannels) { INT ch, sfb, sfbGrp, nSfb; FIXP_DBL avgEnLD64, dbRatio, minSnrRed; - FIXP_DBL minSnrLimitLD64 = FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */ + FIXP_DBL minSnrLimitLD64 = + FL2FXCONST_DBL(-0.00503012648262f); /* ld64(0.8f) */ FIXP_DBL nSfbLD64; FIXP_DBL accu; - for (ch=0; ch<nChannels; ch++) { + FIXP_DBL msaParam_maxRed = msaParam->maxRed; + FIXP_DBL msaParam_startRatio = msaParam->startRatio; + FIXP_DBL msaParam_redRatioFac = + fMult(msaParam->redRatioFac, FL2FXCONST_DBL(0.3010299956f)); + FIXP_DBL msaParam_redOffs = msaParam->redOffs; + + for (ch = 0; ch < nChannels; ch++) { /* calc average energy per scalefactor band */ nSfb = 0; accu = FL2FXCONST_DBL(0.0f); - for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - accu += psyOutChannel[ch]->sfbEnergy[sfbGrp+sfb]>>6; - nSfb++; - } + DWORD_ALIGNED(psyOutChannel[ch]->sfbEnergy); + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup; + nSfb += maxSfbPerGroup; + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + accu += psyOutChannel[ch]->sfbEnergy[sfbGrp + sfb] >> 6; + } } if ((accu == FL2FXCONST_DBL(0.0f)) || (nSfb == 0)) { avgEnLD64 = FL2FXCONST_DBL(-1.0f); - } - else { - nSfbLD64 = CalcLdInt(nSfb); + } else { + nSfbLD64 = CalcLdInt(nSfb); avgEnLD64 = CalcLdData(accu); - avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - nSfbLD64; /* 0.09375f: compensate shift with 6 */ + avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - + nSfbLD64; /* 0.09375f: compensate shift with 6 */ } /* reduce minSnr requirement by minSnr^minSnrRed dependent on avgEn/sfbEn */ - for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - if ( (msaParam->startRatio + qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]) < avgEnLD64 ) { - dbRatio = fMult((avgEnLD64 - qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]),FL2FXCONST_DBL(0.3010299956f)); /* scaled by (1.0f/(10.0f*64.0f)) */ - minSnrRed = msaParam->redOffs + fMult(msaParam->redRatioFac,dbRatio); /* scaled by 1.0f/64.0f*/ - minSnrRed = fixMax(minSnrRed, msaParam->maxRed); /* scaled by 1.0f/64.0f*/ - qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = (fMult(qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb],minSnrRed)) << 6; - qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(minSnrLimitLD64, qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp+sfb]); - } + int maxSfbPerGroup = psyOutChannel[ch]->maxSfbPerGroup; + int sfbCnt = psyOutChannel[ch]->sfbCnt; + int sfbPerGroup = psyOutChannel[ch]->sfbPerGroup; + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + FIXP_DBL *RESTRICT psfbEnergyLdData = + &qcOutChannel[ch]->sfbEnergyLdData[sfbGrp]; + FIXP_DBL *RESTRICT psfbMinSnrLdData = + &qcOutChannel[ch]->sfbMinSnrLdData[sfbGrp]; + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + FIXP_DBL sfbEnergyLdData = *psfbEnergyLdData++; + FIXP_DBL sfbMinSnrLdData = *psfbMinSnrLdData; + dbRatio = avgEnLD64 - sfbEnergyLdData; + int update = (msaParam_startRatio < dbRatio) ? 1 : 0; + minSnrRed = msaParam_redOffs + fMult(msaParam_redRatioFac, + dbRatio); /* scaled by 1.0f/64.0f*/ + minSnrRed = + fixMax(minSnrRed, msaParam_maxRed); /* scaled by 1.0f/64.0f*/ + minSnrRed = (fMult(sfbMinSnrLdData, minSnrRed)) << 6; + minSnrRed = fixMin(minSnrLimitLD64, minSnrRed); + *psfbMinSnrLdData++ = update ? minSnrRed : sfbMinSnrLdData; } } } } - /***************************************************************************** functionname: FDKaacEnc_initAvoidHoleFlag description: determine bands where avoid hole is not necessary resp. possible *****************************************************************************/ -static void FDKaacEnc_initAvoidHoleFlag(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - struct TOOLSINFO *toolsInfo, - const INT nChannels, - const PE_DATA *peData, - AH_PARAM *ahParam) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL sfbEn, sfbEnm1; - FIXP_DBL sfbEnLdData; - FIXP_DBL avgEnLdData; - - /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts - (avoid more holes in long blocks) */ - for (ch=0; ch<nChannels; ch++) { - INT sfbGrp, sfb; - QC_OUT_CHANNEL* qcOutChan = qcOutChannel[ch]; - - if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) { - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] >>= 1 ; - } - else { - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup) - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(FL2FXCONST_DBL(0.63f), - qcOutChan->sfbSpreadEnergy[sfbGrp+sfb]) ; - } - } - - /* increase minSnr for local peaks, decrease it for valleys */ - if (ahParam->modifyMinSnr) { - for(ch=0; ch<nChannels; ch++) { - QC_OUT_CHANNEL* qcOutChan = qcOutChannel[ch]; - for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - FIXP_DBL sfbEnp1, avgEn; - if (sfb > 0) - sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb-1]; - else - sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; - - if (sfb < psyOutChannel[ch]->maxSfbPerGroup-1) - sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb+1]; - else - sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp+sfb]; - - avgEn = (sfbEnm1>>1) + (sfbEnp1>>1); - avgEnLdData = CalcLdData(avgEn); - sfbEn = qcOutChan->sfbEnergy[sfbGrp+sfb]; - sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp+sfb]; - /* peak ? */ - if (sfbEn > avgEn) { - FIXP_DBL tmpMinSnrLdData; - if (psyOutChannel[ch]->lastWindowSequence==LONG_WINDOW) - tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin1 ) ; - else - tmpMinSnrLdData = fixMax( SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), (FIXP_DBL)SnrLdMin3 ) ; - - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = - fixMin(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb], tmpMinSnrLdData); - } - /* valley ? */ - if ( ((sfbEnLdData+(FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) && (sfbEn > FL2FXCONST_DBL(0.0)) ) { - FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData -(FIXP_DBL)SnrLdMin4 + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; - tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData); - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(tmpMinSnrLdData, - (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + SnrLdMin2 )); - } - } - } - } - } - - /* stereo: adapt the minimum requirements sfbMinSnr of mid and - side channels to avoid spending unnoticable bits */ - if (nChannels == 2) { - QC_OUT_CHANNEL* qcOutChanM = qcOutChannel[0]; - QC_OUT_CHANNEL* qcOutChanS = qcOutChannel[1]; - PSY_OUT_CHANNEL* psyOutChanM = psyOutChannel[0]; - for(sfbGrp = 0;sfbGrp < psyOutChanM->sfbCnt;sfbGrp+= psyOutChanM->sfbPerGroup){ - for (sfb=0; sfb<psyOutChanM->maxSfbPerGroup; sfb++) { - if (toolsInfo->msMask[sfbGrp+sfb]) { - FIXP_DBL maxSfbEnLd = fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp+sfb],qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]); - FIXP_DBL maxThrLd, sfbMinSnrTmpLd; - - if ( ((SnrLdMin5>>1) + (maxSfbEnLd>>1) + (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]>>1)) <= FL2FXCONST_DBL(-0.5f)) - maxThrLd = FL2FXCONST_DBL(-1.0f) ; - else - maxThrLd = SnrLdMin5 + maxSfbEnLd + qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb]; - - if (qcOutChanM->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) - sfbMinSnrTmpLd = maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp+sfb]; - else - sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); - - qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); - - if (qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) - qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanM->sfbMinSnrLdData[sfbGrp+sfb], (FIXP_DBL)SnrLdFac); - - if (qcOutChanS->sfbEnergy[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f)) - sfbMinSnrTmpLd = maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp+sfb]; - else - sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); - - qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],sfbMinSnrTmpLd); - - if (qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] <= FL2FXCONST_DBL(0.0f)) - qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb] = fixMin(qcOutChanS->sfbMinSnrLdData[sfbGrp+sfb],(FIXP_DBL)SnrLdFac); - - if (qcOutChanM->sfbEnergy[sfbGrp+sfb]>qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb]) - qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(qcOutChanS->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); - - if (qcOutChanS->sfbEnergy[sfbGrp+sfb]>qcOutChanS->sfbSpreadEnergy[sfbGrp+sfb]) - qcOutChanM->sfbSpreadEnergy[sfbGrp+sfb] = - fMult(qcOutChanM->sfbEnergy[sfbGrp+sfb], FL2FXCONST_DBL(0.9f)); - } - } - } - } - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - for(ch=0; ch<nChannels; ch++) { - QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; - PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; - for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { - if ((qcOutChan->sfbSpreadEnergy[sfbGrp+sfb] > qcOutChan->sfbEnergy[sfbGrp+sfb]) - || (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > FL2FXCONST_DBL(0.0f))) { - ahFlag[ch][sfbGrp+sfb] = NO_AH; +static void FDKaacEnc_initAvoidHoleFlag( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const struct TOOLSINFO *const toolsInfo, + const INT nChannels, const AH_PARAM *const ahParam) { + INT ch, sfb, sfbGrp; + FIXP_DBL sfbEn, sfbEnm1; + FIXP_DBL sfbEnLdData; + FIXP_DBL avgEnLdData; + + /* decrease spread energy by 3dB for long blocks, resp. 2dB for shorts + (avoid more holes in long blocks) */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch]; + + if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) + qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] >>= 1; + } else { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) + qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + FL2FXCONST_DBL(0.63f), qcOutChan->sfbSpreadEnergy[sfbGrp + sfb]); + } + } + + /* increase minSnr for local peaks, decrease it for valleys */ + if (ahParam->modifyMinSnr) { + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *const qcOutChan = qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + FIXP_DBL sfbEnp1, avgEn; + if (sfb > 0) + sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb - 1]; + else + sfbEnm1 = qcOutChan->sfbEnergy[sfbGrp + sfb]; + + if (sfb < psyOutChannel[ch]->maxSfbPerGroup - 1) + sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb + 1]; + else + sfbEnp1 = qcOutChan->sfbEnergy[sfbGrp + sfb]; + + avgEn = (sfbEnm1 >> 1) + (sfbEnp1 >> 1); + avgEnLdData = CalcLdData(avgEn); + sfbEn = qcOutChan->sfbEnergy[sfbGrp + sfb]; + sfbEnLdData = qcOutChan->sfbEnergyLdData[sfbGrp + sfb]; + /* peak ? */ + if (sfbEn > avgEn) { + FIXP_DBL tmpMinSnrLdData; + if (psyOutChannel[ch]->lastWindowSequence == LONG_WINDOW) + tmpMinSnrLdData = + fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), + (FIXP_DBL)SnrLdMin1); + else + tmpMinSnrLdData = + fixMax(SnrLdFac + (FIXP_DBL)(avgEnLdData - sfbEnLdData), + (FIXP_DBL)SnrLdMin3); + + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb], tmpMinSnrLdData); } - else { - ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; + /* valley ? */ + if (((sfbEnLdData + (FIXP_DBL)SnrLdMin4) < (FIXP_DBL)avgEnLdData) && + (sfbEn > FL2FXCONST_DBL(0.0))) { + FIXP_DBL tmpMinSnrLdData = avgEnLdData - sfbEnLdData - + (FIXP_DBL)SnrLdMin4 + + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]; + tmpMinSnrLdData = fixMin((FIXP_DBL)SnrLdFac, tmpMinSnrLdData); + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] = + fixMin(tmpMinSnrLdData, + (FIXP_DBL)(qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + + SnrLdMin2)); } } } - } -} + } + } + + /* stereo: adapt the minimum requirements sfbMinSnr of mid and + side channels to avoid spending unnoticable bits */ + if (nChannels == 2) { + QC_OUT_CHANNEL *qcOutChanM = qcOutChannel[0]; + QC_OUT_CHANNEL *qcOutChanS = qcOutChannel[1]; + const PSY_OUT_CHANNEL *const psyOutChanM = psyOutChannel[0]; + for (sfbGrp = 0; sfbGrp < psyOutChanM->sfbCnt; + sfbGrp += psyOutChanM->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChanM->maxSfbPerGroup; sfb++) { + if (toolsInfo->msMask[sfbGrp + sfb]) { + FIXP_DBL maxSfbEnLd = + fixMax(qcOutChanM->sfbEnergyLdData[sfbGrp + sfb], + qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]); + FIXP_DBL maxThrLd, sfbMinSnrTmpLd; + + if (((SnrLdMin5 >> 1) + (maxSfbEnLd >> 1) + + (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) <= + FL2FXCONST_DBL(-0.5f)) + maxThrLd = FL2FXCONST_DBL(-1.0f); + else + maxThrLd = SnrLdMin5 + maxSfbEnLd + + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb]; + + if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f)) + sfbMinSnrTmpLd = + maxThrLd - qcOutChanM->sfbEnergyLdData[sfbGrp + sfb]; + else + sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = + fixMax(qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd); + if (qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f)) + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChanM->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac); + + if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f)) + sfbMinSnrTmpLd = + maxThrLd - qcOutChanS->sfbEnergyLdData[sfbGrp + sfb]; + else + sfbMinSnrTmpLd = FL2FXCONST_DBL(0.0f); + + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = + fixMax(qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], sfbMinSnrTmpLd); + + if (qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] <= FL2FXCONST_DBL(0.0f)) + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb] = fixMin( + qcOutChanS->sfbMinSnrLdData[sfbGrp + sfb], (FIXP_DBL)SnrLdFac); + + if (qcOutChanM->sfbEnergy[sfbGrp + sfb] > + qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb]) + qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + qcOutChanS->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f)); + + if (qcOutChanS->sfbEnergy[sfbGrp + sfb] > + qcOutChanS->sfbSpreadEnergy[sfbGrp + sfb]) + qcOutChanM->sfbSpreadEnergy[sfbGrp + sfb] = fMult( + qcOutChanM->sfbEnergy[sfbGrp + sfb], FL2FXCONST_DBL(0.9f)); + + } /* if (toolsInfo->msMask[sfbGrp+sfb]) */ + } /* sfb */ + } /* sfbGrp */ + } /* nChannels==2 */ + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; + const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if ((qcOutChan->sfbSpreadEnergy[sfbGrp + sfb] > + qcOutChan->sfbEnergy[sfbGrp + sfb]) || + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > FL2FXCONST_DBL(0.0f))) { + ahFlag[ch][sfbGrp + sfb] = NO_AH; + } else { + ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE; + } + } + } + } +} /** - * \brief Calculate constants that do not change during successive pe calculations. + * \brief Calculate constants that do not change during successive pe + * calculations. * - * \param peData Pointer to structure containing PE data of current element. - * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. - * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. + * \param peData Pointer to structure containing PE data of + * current element. + * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding + * nChannels elements. + * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding + * nChannels elements. * \param nChannels Number of channels in element. - * \param peOffset Fixed PE offset defined while FDKaacEnc_AdjThrInit() depending on bitrate. + * \param peOffset Fixed PE offset defined while + * FDKaacEnc_AdjThrInit() depending on bitrate. * * \return void */ -static -void FDKaacEnc_preparePe(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - const INT nChannels, - const INT peOffset) -{ - INT ch; - - for(ch=0; ch<nChannels; ch++) { - PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; - FDKaacEnc_prepareSfbPe(&peData->peChannelData[ch], - psyOutChan->sfbEnergyLdData, - psyOutChan->sfbThresholdLdData, - qcOutChannel[ch]->sfbFormFactorLdData, - psyOutChan->sfbOffsets, - psyOutChan->sfbCnt, - psyOutChan->sfbPerGroup, - psyOutChan->maxSfbPerGroup); - } - peData->offset = peOffset; +static void FDKaacEnc_preparePe(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + const INT nChannels, const INT peOffset) { + INT ch; + + for (ch = 0; ch < nChannels; ch++) { + const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch]; + FDKaacEnc_prepareSfbPe( + &peData->peChannelData[ch], psyOutChan->sfbEnergyLdData, + psyOutChan->sfbThresholdLdData, qcOutChannel[ch]->sfbFormFactorLdData, + psyOutChan->sfbOffsets, psyOutChan->sfbCnt, psyOutChan->sfbPerGroup, + psyOutChan->maxSfbPerGroup); + } + peData->offset = peOffset; } /** * \brief Calculate weighting factor for threshold adjustment. * - * Calculate weighting factor to be applied at energies and thresholds in ld64 format. + * Calculate weighting factor to be applied at energies and thresholds in ld64 + * format. * * \param peData, Pointer to PE data in current element. - * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding nChannels elements. - * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding nChannels elements. + * \param psyOutChannel Pointer to PSY_OUT_CHANNEL struct holding + * nChannels elements. + * \param qcOutChannel Pointer to QC_OUT_CHANNEL struct holding + * nChannels elements. * \param toolsInfo Pointer to tools info struct of current element. - * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch states. + * \param adjThrStateElement Pointer to ATS_ELEMENT holding enFacPatch + * states. * \param nChannels Number of channels in element. * \param usePatchTool Apply the weighting tool 0 (no) else (yes). * * \return void */ -static -void FDKaacEnc_calcWeighting(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels, - const INT usePatchTool) -{ - int ch, noShortWindowInFrame = TRUE; - INT exePatchM = 0; - - for (ch=0; ch<nChannels; ch++) { - if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { - noShortWindowInFrame = FALSE; - } - FDKmemclear(qcOutChannel[ch]->sfbEnFacLd, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - } - - if (usePatchTool==0) { - return; /* tool is disabled */ +static void FDKaacEnc_calcWeighting( + const PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, const INT nChannels, + const INT usePatchTool) { + int ch, noShortWindowInFrame = TRUE; + INT exePatchM = 0; + + for (ch = 0; ch < nChannels; ch++) { + if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { + noShortWindowInFrame = FALSE; } + FDKmemclear(qcOutChannel[ch]->sfbEnFacLd, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + } - for (ch=0; ch<nChannels; ch++) { - - PSY_OUT_CHANNEL *psyOutChan = psyOutChannel[ch]; - - if (noShortWindowInFrame) { /* retain energy ratio between blocks of different length */ - - FIXP_DBL nrgSum14, nrgSum12, nrgSum34, nrgTotal; - FIXP_DBL nrgFacLd_14, nrgFacLd_12, nrgFacLd_34; - INT usePatch, exePatch; - int sfb, sfbGrp, nLinesSum = 0; + if (usePatchTool == 0) { + return; /* tool is disabled */ + } - nrgSum14 = nrgSum12 = nrgSum34 = nrgTotal = FL2FXCONST_DBL(0.f); + for (ch = 0; ch < nChannels; ch++) { + const PSY_OUT_CHANNEL *const psyOutChan = psyOutChannel[ch]; + + if (noShortWindowInFrame) { /* retain energy ratio between blocks of + different length */ + + FIXP_DBL nrgSum14, nrgSum12, nrgSum34, nrgTotal; + FIXP_DBL nrgFacLd_14, nrgFacLd_12, nrgFacLd_34; + INT usePatch, exePatch; + int sfb, sfbGrp, nLinesSum = 0; + + nrgSum14 = nrgSum12 = nrgSum34 = nrgTotal = FL2FXCONST_DBL(0.f); + + /* calculate flatness of audible spectrum, i.e. spectrum above masking + * threshold. */ + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + FIXP_DBL nrgFac12 = CalcInvLdData( + psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1); /* nrg^(1/2) */ + FIXP_DBL nrgFac14 = CalcInvLdData( + psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 2); /* nrg^(1/4) */ + + /* maximal number of bands is 64, results scaling factor 6 */ + nLinesSum += peData->peChannelData[ch] + .sfbNLines[sfbGrp + sfb]; /* relevant lines */ + nrgTotal += + (psyOutChan->sfbEnergy[sfbGrp + sfb] >> 6); /* sum up nrg */ + nrgSum12 += (nrgFac12 >> 6); /* sum up nrg^(2/4) */ + nrgSum14 += (nrgFac14 >> 6); /* sum up nrg^(1/4) */ + nrgSum34 += (fMult(nrgFac14, nrgFac12) >> 6); /* sum up nrg^(3/4) */ + } + } - /* calculate flatness of audible spectrum, i.e. spectrum above masking threshold. */ - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - FIXP_DBL nrgFac12 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1); /* nrg^(1/2) */ - FIXP_DBL nrgFac14 = CalcInvLdData(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>2); /* nrg^(1/4) */ + nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */ + + nrgFacLd_14 = + CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */ + nrgFacLd_12 = + CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */ + nrgFacLd_34 = + CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */ + + /* Note: nLinesSum cannot be larger than the number of total lines, thats + * taken care of in line_pe.cpp FDKaacEnc_prepareSfbPe() */ + adjThrStateElement->chaosMeasureEnFac[ch] = + fMax(FL2FXCONST_DBL(0.1875f), + fDivNorm(nLinesSum, psyOutChan->sfbOffsets[psyOutChan->sfbCnt])); + + usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.78125f)); + exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch])); + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + INT sfbExePatch; + /* for MS coupled SFBs, also execute patch in side channel if done in + * mid channel */ + if ((ch == 1) && (toolsInfo->msMask[sfbGrp + sfb])) { + sfbExePatch = exePatchM; + } else { + sfbExePatch = exePatch; + } - /* maximal number of bands is 64, results scaling factor 6 */ - nLinesSum += peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]; /* relevant lines */ - nrgTotal += ( psyOutChan->sfbEnergy[sfbGrp+sfb] >> 6 ); /* sum up nrg */ - nrgSum12 += ( nrgFac12 >> 6 ); /* sum up nrg^(2/4) */ - nrgSum14 += ( nrgFac14 >> 6 ); /* sum up nrg^(1/4) */ - nrgSum34 += ( fMult(nrgFac14, nrgFac12) >> 6 ); /* sum up nrg^(3/4) */ - } + if ((sfbExePatch) && + (psyOutChan->sfbEnergy[sfbGrp + sfb] > FL2FXCONST_DBL(0.f))) { + /* execute patch based on spectral flatness calculated above */ + if (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.8125f)) { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_14 + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1))) >> + 1); /* sfbEnergy^(3/4) */ + } else if (adjThrStateElement->chaosMeasureEnFac[ch] > + FL2FXCONST_DBL(0.796875f)) { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp + sfb]) >> + 1); /* sfbEnergy^(2/4) */ + } else { + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + ((nrgFacLd_34 + + (psyOutChan->sfbEnergyLdData[sfbGrp + sfb] >> 1)) >> + 1); /* sfbEnergy^(1/4) */ } - - nrgTotal = CalcLdData(nrgTotal); /* get ld64 of total nrg */ - - nrgFacLd_14 = CalcLdData(nrgSum14) - nrgTotal; /* ld64(nrgSum14/nrgTotal) */ - nrgFacLd_12 = CalcLdData(nrgSum12) - nrgTotal; /* ld64(nrgSum12/nrgTotal) */ - nrgFacLd_34 = CalcLdData(nrgSum34) - nrgTotal; /* ld64(nrgSum34/nrgTotal) */ - - adjThrStateElement->chaosMeasureEnFac[ch] = FDKmax( FL2FXCONST_DBL(0.1875f), fDivNorm(nLinesSum,psyOutChan->sfbOffsets[psyOutChan->sfbCnt]) ); - - usePatch = (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.78125f)); - exePatch = ((usePatch) && (adjThrStateElement->lastEnFacPatch[ch])); - - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - - INT sfbExePatch; - - /* for MS coupled SFBs, also execute patch in side channel if done in mid channel */ - if ((ch == 1) && (toolsInfo->msMask[sfbGrp+sfb])) { - sfbExePatch = exePatchM; - } - else { - sfbExePatch = exePatch; - } - - if ( (sfbExePatch) && (psyOutChan->sfbEnergy[sfbGrp+sfb]>FL2FXCONST_DBL(0.f)) ) - { - /* execute patch based on spectral flatness calculated above */ - if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.8125f)) { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_14 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]+(psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1)))>>1 ); /* sfbEnergy^(3/4) */ - } - else if (adjThrStateElement->chaosMeasureEnFac[ch] > FL2FXCONST_DBL(0.796875f)) { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_12 + psyOutChan->sfbEnergyLdData[sfbGrp+sfb])>>1 ); /* sfbEnergy^(2/4) */ - } - else { - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = ( (nrgFacLd_34 + (psyOutChan->sfbEnergyLdData[sfbGrp+sfb]>>1))>>1 ); /* sfbEnergy^(1/4) */ - } - qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb] = fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp+sfb],(FIXP_DBL)0); - - } - } - } /* sfb loop */ - - adjThrStateElement->lastEnFacPatch[ch] = usePatch; - exePatchM = exePatch; - } - else { - /* !noShortWindowInFrame */ - adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f); - adjThrStateElement->lastEnFacPatch[ch] = TRUE; /* allow use of sfbEnFac patch in upcoming frame */ + qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb] = + fixMin(qcOutChannel[ch]->sfbEnFacLd[sfbGrp + sfb], (FIXP_DBL)0); + } } + } /* sfb loop */ - } /* ch loop */ + adjThrStateElement->lastEnFacPatch[ch] = usePatch; + exePatchM = exePatch; + } else { + /* !noShortWindowInFrame */ + adjThrStateElement->chaosMeasureEnFac[ch] = FL2FXCONST_DBL(0.75f); + adjThrStateElement->lastEnFacPatch[ch] = + TRUE; /* allow use of sfbEnFac patch in upcoming frame */ + } + } /* ch loop */ } - - - /***************************************************************************** functionname: FDKaacEnc_calcPe description: calculate pe for both channels *****************************************************************************/ -static -void FDKaacEnc_calcPe(PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - PE_DATA *peData, - const INT nChannels) -{ - INT ch; - - peData->pe = peData->offset; - peData->constPart = 0; - peData->nActiveLines = 0; - for(ch=0; ch<nChannels; ch++) { - PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; - FDKaacEnc_calcSfbPe(&peData->peChannelData[ch], - qcOutChannel[ch]->sfbWeightedEnergyLdData, - qcOutChannel[ch]->sfbThresholdLdData, - psyOutChannel[ch]->sfbCnt, - psyOutChannel[ch]->sfbPerGroup, - psyOutChannel[ch]->maxSfbPerGroup, - psyOutChannel[ch]->isBook, - psyOutChannel[ch]->isScale); - - peData->pe += peChanData->pe; - peData->constPart += peChanData->constPart; - peData->nActiveLines += peChanData->nActiveLines; - } +static void FDKaacEnc_calcPe(const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + const QC_OUT_CHANNEL *const qcOutChannel[(2)], + PE_DATA *const peData, const INT nChannels) { + INT ch; + + peData->pe = peData->offset; + peData->constPart = 0; + peData->nActiveLines = 0; + for (ch = 0; ch < nChannels; ch++) { + PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; + + FDKaacEnc_calcSfbPe( + peChanData, qcOutChannel[ch]->sfbWeightedEnergyLdData, + qcOutChannel[ch]->sfbThresholdLdData, psyOutChannel[ch]->sfbCnt, + psyOutChannel[ch]->sfbPerGroup, psyOutChannel[ch]->maxSfbPerGroup, + psyOutChannel[ch]->isBook, psyOutChannel[ch]->isScale); + + peData->pe += peChanData->pe; + peData->constPart += peChanData->constPart; + peData->nActiveLines += peChanData->nActiveLines; + } } -void FDKaacEnc_peCalculation(PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels) -{ +void FDKaacEnc_peCalculation(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, + const INT nChannels) { /* constants that will not change during successive pe calculations */ - FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels, adjThrStateElement->peOffset); + FDKaacEnc_preparePe(peData, psyOutChannel, qcOutChannel, nChannels, + adjThrStateElement->peOffset); /* calculate weighting factor for threshold adjustment */ - FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo, adjThrStateElement, nChannels, 1); -{ + FDKaacEnc_calcWeighting(peData, psyOutChannel, qcOutChannel, toolsInfo, + adjThrStateElement, nChannels, 1); + { /* no weighting of threholds and energies for mlout */ /* weight energies and thresholds */ int ch; - for (ch=0; ch<nChannels; ch++) { - - int sfb, sfbGrp; - QC_OUT_CHANNEL* pQcOutCh = qcOutChannel[ch]; - - for (sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - pQcOutCh->sfbWeightedEnergyLdData[sfb+sfbGrp] = pQcOutCh->sfbEnergyLdData[sfb+sfbGrp] - pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] -= pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - } + for (ch = 0; ch < nChannels; ch++) { + int sfb, sfbGrp; + QC_OUT_CHANNEL *pQcOutCh = qcOutChannel[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + pQcOutCh->sfbWeightedEnergyLdData[sfb + sfbGrp] = + pQcOutCh->sfbEnergyLdData[sfb + sfbGrp] - + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; + pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] -= + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; } + } } -} + } /* pe without reduction */ FDKaacEnc_calcPe(psyOutChannel, qcOutChannel, peData, nChannels); } - - /***************************************************************************** functionname: FDKaacEnc_FDKaacEnc_calcPeNoAH description: sum the pe data only for bands where avoid hole is inactive *****************************************************************************/ -static void FDKaacEnc_FDKaacEnc_calcPeNoAH(INT *pe, - INT *constPart, - INT *nActiveLines, - PE_DATA *peData, - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - const INT nChannels) -{ - INT ch, sfb,sfbGrp; - - INT pe_tmp = peData->offset; - INT constPart_tmp = 0; - INT nActiveLines_tmp = 0; - for(ch=0; ch<nChannels; ch++) { - PE_CHANNEL_DATA *peChanData = &peData->peChannelData[ch]; - for(sfbGrp = 0;sfbGrp < psyOutChannel[ch]->sfbCnt;sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - if(ahFlag[ch][sfbGrp+sfb] < AH_ACTIVE) { - pe_tmp += peChanData->sfbPe[sfbGrp+sfb]; - constPart_tmp += peChanData->sfbConstPart[sfbGrp+sfb]; - nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp+sfb]; - } - } +#define CONSTPART_HEADROOM 4 +static void FDKaacEnc_FDKaacEnc_calcPeNoAH( + INT *const pe, INT *const constPart, INT *const nActiveLines, + const PE_DATA *const peData, const UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], const INT nChannels) { + INT ch, sfb, sfbGrp; + + INT pe_tmp = peData->offset; + INT constPart_tmp = 0; + INT nActiveLines_tmp = 0; + for (ch = 0; ch < nChannels; ch++) { + const PE_CHANNEL_DATA *const peChanData = &peData->peChannelData[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + if (ahFlag[ch][sfbGrp + sfb] < AH_ACTIVE) { + pe_tmp += peChanData->sfbPe[sfbGrp + sfb]; + constPart_tmp += + peChanData->sfbConstPart[sfbGrp + sfb] >> CONSTPART_HEADROOM; + nActiveLines_tmp += peChanData->sfbNActiveLines[sfbGrp + sfb]; } + } } - /* correct scaled pe and constPart values */ - *pe = pe_tmp >> PE_CONSTPART_SHIFT; - *constPart = constPart_tmp >> PE_CONSTPART_SHIFT; + } + /* correct scaled pe and constPart values */ + *pe = pe_tmp >> PE_CONSTPART_SHIFT; + *constPart = constPart_tmp >> (PE_CONSTPART_SHIFT - CONSTPART_HEADROOM); - *nActiveLines = nActiveLines_tmp; + *nActiveLines = nActiveLines_tmp; } - /***************************************************************************** functionname: FDKaacEnc_reduceThresholdsCBR description: apply reduction formula *****************************************************************************/ -static const FIXP_DBL limitThrReducedLdData = (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/ - -static void FDKaacEnc_reduceThresholdsCBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - const INT nChannels, - const FIXP_DBL redVal, - const SCHAR redValScaling) -{ - INT ch, sfb, sfbGrp; - FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; - FIXP_DBL sfbThrExp; - - for(ch=0; ch<nChannels; ch++) { - QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; - for(sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup){ - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; - sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; - sfbThrExp = thrExp[ch][sfbGrp+sfb]; - if ((sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { - - /* threshold reduction formula: - float tmp = thrExp[ch][sfb]+redVal; - tmp *= tmp; - sfbThrReduced = tmp*tmp; - */ - int minScale = fixMin(CountLeadingBits(sfbThrExp), CountLeadingBits(redVal) - (DFRACT_BITS-1-redValScaling) )-1; - - /* 4*log( sfbThrExp + redVal ) */ - sfbThrReducedLdData = CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) + scaleValue(redVal,(DFRACT_BITS-1-redValScaling)+minScale))) - - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - sfbThrReducedLdData <<= 2; - - /* avoid holes */ - if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) - && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) - { - if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ - sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); - } - else sfbThrReducedLdData = sfbThrLdData; - ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; - } +static const FIXP_DBL limitThrReducedLdData = + (FIXP_DBL)0x00008000; /*FL2FXCONST_DBL(FDKpow(2.0,-LD_DATA_SCALING/4.0));*/ + +static void FDKaacEnc_reduceThresholdsCBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels, + const FIXP_DBL redVal_m, const SCHAR redVal_e) { + INT ch, sfb, sfbGrp; + FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; + FIXP_DBL sfbThrExp; + + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]; + sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb]; + sfbThrExp = thrExp[ch][sfbGrp + sfb]; + if ((sfbEnLdData > sfbThrLdData) && + (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) { + /* threshold reduction formula: + float tmp = thrExp[ch][sfb]+redVal; + tmp *= tmp; + sfbThrReduced = tmp*tmp; + */ + int minScale = fixMin(CountLeadingBits(sfbThrExp), + CountLeadingBits(redVal_m) - redVal_e) - + 1; + + /* 4*log( sfbThrExp + redVal ) */ + sfbThrReducedLdData = + CalcLdData(fAbs(scaleValue(sfbThrExp, minScale) + + scaleValue(redVal_m, redVal_e + minScale))) - + (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + sfbThrReducedLdData <<= 2; - /* minimum of 29 dB Ratio for Thresholds */ - if ((sfbEnLdData+(FIXP_DBL)MAXVAL_DBL) > FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ - sfbThrReducedLdData = fixMax(sfbThrReducedLdData, (sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING))); - } + /* avoid holes */ + if ((sfbThrReducedLdData > + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData)) && + (ahFlag[ch][sfbGrp + sfb] != NO_AH)) { + if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) { + sfbThrReducedLdData = fixMax( + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData), + sfbThrLdData); + } else + sfbThrReducedLdData = sfbThrLdData; + ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE; + } - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; - } + /* minimum of 29 dB Ratio for Thresholds */ + if ((sfbEnLdData + (FIXP_DBL)MAXVAL_DBL) > + FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) { + sfbThrReducedLdData = fixMax( + sfbThrReducedLdData, + (sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING))); + } + + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } - } + } + } } /* similar to prepareSfbPe1() */ -static FIXP_DBL FDKaacEnc_calcChaosMeasure(PSY_OUT_CHANNEL *psyOutChannel, - const FIXP_DBL *sfbFormFactorLdData) -{ - #define SCALE_FORM_FAC (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/ - #define SCALE_NRGS (8) - #define SCALE_NLINES (16) - #define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */ - #define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */ - - INT sfbGrp, sfb; +static FIXP_DBL FDKaacEnc_calcChaosMeasure( + const PSY_OUT_CHANNEL *const psyOutChannel, + const FIXP_DBL *const sfbFormFactorLdData) { +#define SCALE_FORM_FAC \ + (4) /* (SCALE_FORM_FAC+FORM_FAC_SHIFT) >= ld(FRAME_LENGTH)*/ +#define SCALE_NRGS (8) +#define SCALE_NLINES (16) +#define SCALE_NRGS_SQRT4 (2) /* 0.25 * SCALE_NRGS */ +#define SCALE_NLINES_P34 (12) /* 0.75 * SCALE_NLINES */ + + INT sfbGrp, sfb; FIXP_DBL chaosMeasure; INT frameNLines = 0; FIXP_DBL frameFormFactor = FL2FXCONST_DBL(0.f); FIXP_DBL frameEnergy = FL2FXCONST_DBL(0.f); - for (sfbGrp=0; sfbGrp<psyOutChannel->sfbCnt; sfbGrp+=psyOutChannel->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel->maxSfbPerGroup; sfb++){ - if (psyOutChannel->sfbEnergyLdData[sfbGrp+sfb] > psyOutChannel->sfbThresholdLdData[sfbGrp+sfb]) { - frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp+sfb])>>SCALE_FORM_FAC); - frameNLines += (psyOutChannel->sfbOffsets[sfbGrp+sfb+1] - psyOutChannel->sfbOffsets[sfbGrp+sfb]); - frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp+sfb]>>SCALE_NRGS); + for (sfbGrp = 0; sfbGrp < psyOutChannel->sfbCnt; + sfbGrp += psyOutChannel->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + if (psyOutChannel->sfbEnergyLdData[sfbGrp + sfb] > + psyOutChannel->sfbThresholdLdData[sfbGrp + sfb]) { + frameFormFactor += (CalcInvLdData(sfbFormFactorLdData[sfbGrp + sfb]) >> + SCALE_FORM_FAC); + frameNLines += (psyOutChannel->sfbOffsets[sfbGrp + sfb + 1] - + psyOutChannel->sfbOffsets[sfbGrp + sfb]); + frameEnergy += (psyOutChannel->sfbEnergy[sfbGrp + sfb] >> SCALE_NRGS); } } } - if(frameNLines > 0){ - - /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy *2^SCALE_NRGS)/frameNLines)^-0.25 - chaosMeasure = frameNActiveLines / frameNLines */ - chaosMeasure = - CalcInvLdData( (((CalcLdData(frameFormFactor)>>1) - - (CalcLdData(frameEnergy)>>(2+1))) - - (fMultDiv2(FL2FXCONST_DBL(0.75f),CalcLdData((FIXP_DBL)frameNLines<<(DFRACT_BITS-1-SCALE_NLINES))) - - (((FIXP_DBL)(-((-SCALE_FORM_FAC+SCALE_NRGS_SQRT4-FORM_FAC_SHIFT+SCALE_NLINES_P34) << (DFRACT_BITS-1-LD_DATA_SHIFT))))>>1)) - )<<1 ); + if (frameNLines > 0) { + /* frameNActiveLines = frameFormFactor*2^FORM_FAC_SHIFT * ((frameEnergy + *2^SCALE_NRGS)/frameNLines)^-0.25 chaosMeasure = frameNActiveLines / + frameNLines */ + chaosMeasure = CalcInvLdData( + (((CalcLdData(frameFormFactor) >> 1) - + (CalcLdData(frameEnergy) >> (2 + 1))) - + (fMultDiv2(FL2FXCONST_DBL(0.75f), + CalcLdData((FIXP_DBL)frameNLines + << (DFRACT_BITS - 1 - SCALE_NLINES))) - + (((FIXP_DBL)(-((-SCALE_FORM_FAC + SCALE_NRGS_SQRT4 - FORM_FAC_SHIFT + + SCALE_NLINES_P34) + << (DFRACT_BITS - 1 - LD_DATA_SHIFT)))) >> + 1))) + << 1); } else { - /* assuming total chaos, if no sfb is above thresholds */ chaosMeasure = FL2FXCONST_DBL(1.f); } @@ -970,47 +1107,46 @@ static FIXP_DBL FDKaacEnc_calcChaosMeasure(PSY_OUT_CHANNEL *psyOutChannel, } /* apply reduction formula for VBR-mode */ -static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], - const INT nChannels, - const FIXP_DBL vbrQualFactor, - FIXP_DBL* chaosMeasureOld) -{ +static void FDKaacEnc_reduceThresholdsVBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[(2)][MAX_GROUPED_SFB], const INT nChannels, + const FIXP_DBL vbrQualFactor, FIXP_DBL *const chaosMeasureOld) { INT ch, sfbGrp, sfb; - FIXP_DBL chGroupEnergy[TRANS_FAC][2];/*energy for each group and channel*/ + FIXP_DBL chGroupEnergy[TRANS_FAC][2]; /*energy for each group and channel*/ FIXP_DBL chChaosMeasure[2]; FIXP_DBL frameEnergy = FL2FXCONST_DBL(1e-10f); FIXP_DBL chaosMeasure = FL2FXCONST_DBL(0.f); FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrExp; FIXP_DBL sfbThrReducedLdData; FIXP_DBL chaosMeasureAvg; - INT groupCnt; /* loop counter */ - FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one redVal for each group */ - QC_OUT_CHANNEL *qcOutChan = NULL; - PSY_OUT_CHANNEL *psyOutChan = NULL; + INT groupCnt; /* loop counter */ + FIXP_DBL redVal[TRANS_FAC]; /* reduction values; in short-block case one + redVal for each group */ + QC_OUT_CHANNEL *qcOutChan = NULL; + const PSY_OUT_CHANNEL *psyOutChan = NULL; -#define SCALE_GROUP_ENERGY (8) +#define SCALE_GROUP_ENERGY (8) -#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f)) -#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f-0.25f)) +#define CONST_CHAOS_MEAS_AVG_FAC_0 (FL2FXCONST_DBL(0.25f)) +#define CONST_CHAOS_MEAS_AVG_FAC_1 (FL2FXCONST_DBL(1.f - 0.25f)) -#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f)) +#define MIN_LDTHRESH (FL2FXCONST_DBL(-0.515625f)) - - for(ch=0; ch<nChannels; ch++){ - qcOutChan = qcOutChannel[ch]; - psyOutChan = psyOutChannel[ch]; + for (ch = 0; ch < nChannels; ch++) { + psyOutChan = psyOutChannel[ch]; /* adding up energy for each channel and each group separately */ FIXP_DBL chEnergy = FL2FXCONST_DBL(0.f); - groupCnt=0; + groupCnt = 0; - for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup, groupCnt++) { + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup, groupCnt++) { chGroupEnergy[groupCnt][ch] = FL2FXCONST_DBL(0.f); - for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++){ - chGroupEnergy[groupCnt][ch] += (psyOutChan->sfbEnergy[sfbGrp+sfb]>>SCALE_GROUP_ENERGY); + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + chGroupEnergy[groupCnt][ch] += + (psyOutChan->sfbEnergy[sfbGrp + sfb] >> SCALE_GROUP_ENERGY); } chEnergy += chGroupEnergy[groupCnt][ch]; } @@ -1018,110 +1154,133 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], /* chaosMeasure */ if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { - chChaosMeasure[ch] = FL2FXCONST_DBL(0.5f); /* assume a constant chaos measure of 0.5f for short blocks */ + chChaosMeasure[ch] = FL2FXCONST_DBL( + 0.5f); /* assume a constant chaos measure of 0.5f for short blocks */ } else { - chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure(psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData); + chChaosMeasure[ch] = FDKaacEnc_calcChaosMeasure( + psyOutChannel[ch], qcOutChannel[ch]->sfbFormFactorLdData); } chaosMeasure += fMult(chChaosMeasure[ch], chEnergy); } - if(frameEnergy > chaosMeasure) { + if (frameEnergy > chaosMeasure) { INT scale = CntLeadingZeros(frameEnergy) - 1; - FIXP_DBL num = chaosMeasure<<scale; - FIXP_DBL denum = frameEnergy<<scale; - chaosMeasure = schur_div(num,denum,16); - } - else { + FIXP_DBL num = chaosMeasure << scale; + FIXP_DBL denum = frameEnergy << scale; + chaosMeasure = schur_div(num, denum, 16); + } else { chaosMeasure = FL2FXCONST_DBL(1.f); } chaosMeasureAvg = fMult(CONST_CHAOS_MEAS_AVG_FAC_0, chaosMeasure) + - fMult(CONST_CHAOS_MEAS_AVG_FAC_1, *chaosMeasureOld); /* averaging chaos measure */ - *chaosMeasureOld = chaosMeasure = (fixMin(chaosMeasure, chaosMeasureAvg)); /* use min-value, safe for next frame */ + fMult(CONST_CHAOS_MEAS_AVG_FAC_1, + *chaosMeasureOld); /* averaging chaos measure */ + *chaosMeasureOld = chaosMeasure = (fixMin( + chaosMeasure, chaosMeasureAvg)); /* use min-value, safe for next frame */ /* characteristic curve chaosMeasure = 0.2f + 0.7f/0.3f * (chaosMeasure - 0.2f); chaosMeasure = fixMin(1.0f, fixMax(0.1f, chaosMeasure)); constants scaled by 4.f */ - chaosMeasure = ((FL2FXCONST_DBL(0.2f)>>2) + fMult(FL2FXCONST_DBL(0.7f/(4.f*0.3f)), (chaosMeasure - FL2FXCONST_DBL(0.2f)))); - chaosMeasure = (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f)>>2), fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f)>>2), chaosMeasure)))<<2; + chaosMeasure = ((FL2FXCONST_DBL(0.2f) >> 2) + + fMult(FL2FXCONST_DBL(0.7f / (4.f * 0.3f)), + (chaosMeasure - FL2FXCONST_DBL(0.2f)))); + chaosMeasure = + (fixMin((FIXP_DBL)(FL2FXCONST_DBL(1.0f) >> 2), + fixMax((FIXP_DBL)(FL2FXCONST_DBL(0.1f) >> 2), chaosMeasure))) + << 2; /* calculation of reduction value */ - if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW){ /* short-blocks */ - FDK_ASSERT(TRANS_FAC==8); - #define WIN_TYPE_SCALE (3) - - INT sfbGrp, groupCnt=0; - for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup,groupCnt++) { + if (psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) { /* short-blocks */ + FDK_ASSERT(TRANS_FAC == 8); +#define WIN_TYPE_SCALE (3) + groupCnt = 0; + for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt; + sfbGrp += psyOutChannel[0]->sfbPerGroup, groupCnt++) { FIXP_DBL groupEnergy = FL2FXCONST_DBL(0.f); - for(ch=0;ch<nChannels;ch++){ - groupEnergy += chGroupEnergy[groupCnt][ch]; /* adding up the channels groupEnergy */ + for (ch = 0; ch < nChannels; ch++) { + groupEnergy += + chGroupEnergy[groupCnt] + [ch]; /* adding up the channels groupEnergy */ } - FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt]<=INV_INT_TAB_SIZE); - groupEnergy = fMult(groupEnergy,invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of group energy */ - groupEnergy = fixMin(groupEnergy, frameEnergy>>WIN_TYPE_SCALE); /* do not allow an higher redVal as calculated framewise */ - - groupEnergy>>=2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */ - - redVal[groupCnt] = fMult(fMult(vbrQualFactor,chaosMeasure), - CalcInvLdData(CalcLdData(groupEnergy)>>2) ) - << (int)( ( 2 + (2*WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY )>>2 ) ; - + FDK_ASSERT(psyOutChannel[0]->groupLen[groupCnt] <= INV_INT_TAB_SIZE); + groupEnergy = fMult( + groupEnergy, + invInt[psyOutChannel[0]->groupLen[groupCnt]]); /* correction of + group energy */ + groupEnergy = fixMin(groupEnergy, + frameEnergy >> WIN_TYPE_SCALE); /* do not allow an + higher redVal as + calculated + framewise */ + + groupEnergy >>= + 2; /* 2*WIN_TYPE_SCALE = 6 => 6+2 = 8 ==> 8/4 = int number */ + + redVal[groupCnt] = + fMult(fMult(vbrQualFactor, chaosMeasure), + CalcInvLdData(CalcLdData(groupEnergy) >> 2)) + << (int)((2 + (2 * WIN_TYPE_SCALE) + SCALE_GROUP_ENERGY) >> 2); } } else { /* long-block */ - redVal[0] = fMult( fMult(vbrQualFactor,chaosMeasure), - CalcInvLdData(CalcLdData(frameEnergy)>>2) ) - << (int)( SCALE_GROUP_ENERGY>>2 ) ; + redVal[0] = fMult(fMult(vbrQualFactor, chaosMeasure), + CalcInvLdData(CalcLdData(frameEnergy) >> 2)) + << (int)(SCALE_GROUP_ENERGY >> 2); } - for(ch=0; ch<nChannels; ch++) { - qcOutChan = qcOutChannel[ch]; - psyOutChan = psyOutChannel[ch]; - - for (sfbGrp=0; sfbGrp<psyOutChan->sfbCnt; sfbGrp+=psyOutChan->sfbPerGroup) { - for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++){ - - sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]); - sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp+sfb]); - sfbThrExp = thrExp[ch][sfbGrp+sfb]; + for (ch = 0; ch < nChannels; ch++) { + qcOutChan = qcOutChannel[ch]; + psyOutChan = psyOutChannel[ch]; - if ( (sfbThrLdData>=MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) && (ahFlag[ch][sfbGrp+sfb] != AH_ACTIVE)) { + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + sfbEnLdData = (qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]); + sfbThrLdData = (qcOutChan->sfbThresholdLdData[sfbGrp + sfb]); + sfbThrExp = thrExp[ch][sfbGrp + sfb]; + if ((sfbThrLdData >= MIN_LDTHRESH) && (sfbEnLdData > sfbThrLdData) && + (ahFlag[ch][sfbGrp + sfb] != AH_ACTIVE)) { /* Short-Window */ if (psyOutChannel[ch]->lastWindowSequence == SHORT_WINDOW) { - const int groupNumber = (int) sfb/psyOutChan->sfbPerGroup; - - FDK_ASSERT(INV_SQRT4_TAB_SIZE>psyOutChan->groupLen[groupNumber]); - - sfbThrExp = fMult(sfbThrExp, fMult( FL2FXCONST_DBL(2.82f/4.f), invSqrt4[psyOutChan->groupLen[groupNumber]]))<<2 ; - - if ( sfbThrExp <= (limitThrReducedLdData-redVal[groupNumber]) ) { - sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f); - } - else { - if ((FIXP_DBL)redVal[groupNumber] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) - sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); - else { - /* threshold reduction formula */ - sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[groupNumber]); - sfbThrReducedLdData <<= 2; - } + const int groupNumber = (int)sfb / psyOutChan->sfbPerGroup; + + FDK_ASSERT(INV_SQRT4_TAB_SIZE > psyOutChan->groupLen[groupNumber]); + + sfbThrExp = + fMult(sfbThrExp, + fMult(FL2FXCONST_DBL(2.82f / 4.f), + invSqrt4[psyOutChan->groupLen[groupNumber]])) + << 2; + + if (sfbThrExp <= (limitThrReducedLdData - redVal[groupNumber])) { + sfbThrReducedLdData = FL2FXCONST_DBL(-1.0f); + } else { + if ((FIXP_DBL)redVal[groupNumber] >= + FL2FXCONST_DBL(1.0f) - sfbThrExp) + sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); + else { + /* threshold reduction formula */ + sfbThrReducedLdData = + CalcLdData(sfbThrExp + redVal[groupNumber]); + sfbThrReducedLdData <<= 2; + } } - sfbThrReducedLdData += ( CalcLdInt(psyOutChan->groupLen[groupNumber]) - - ((FIXP_DBL)6<<(DFRACT_BITS-1-LD_DATA_SHIFT)) ); + sfbThrReducedLdData += + (CalcLdInt(psyOutChan->groupLen[groupNumber]) - + ((FIXP_DBL)6 << (DFRACT_BITS - 1 - LD_DATA_SHIFT))); } /* Long-Window */ else { - if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f)-sfbThrExp) { + if ((FIXP_DBL)redVal[0] >= FL2FXCONST_DBL(1.0f) - sfbThrExp) { sfbThrReducedLdData = FL2FXCONST_DBL(0.0f); - } - else { + } else { /* threshold reduction formula */ sfbThrReducedLdData = CalcLdData(sfbThrExp + redVal[0]); sfbThrReducedLdData <<= 2; @@ -1129,27 +1288,33 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], } /* avoid holes */ - if ( ((sfbThrReducedLdData - sfbEnLdData) > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) - && (ahFlag[ch][sfbGrp+sfb] != NO_AH) ) - { - if (qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] > (FL2FXCONST_DBL(-1.0f) - sfbEnLdData) ){ - sfbThrReducedLdData = fixMax((qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData), sfbThrLdData); - } - else sfbThrReducedLdData = sfbThrLdData; - ahFlag[ch][sfbGrp+sfb] = AH_ACTIVE; + if (((sfbThrReducedLdData - sfbEnLdData) > + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) && + (ahFlag[ch][sfbGrp + sfb] != NO_AH)) { + if (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.0f) - sfbEnLdData)) { + sfbThrReducedLdData = fixMax( + (qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData), + sfbThrLdData); + } else + sfbThrReducedLdData = sfbThrLdData; + ahFlag[ch][sfbGrp + sfb] = AH_ACTIVE; } - if (sfbThrReducedLdData<FL2FXCONST_DBL(-0.5f)) - sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); + if (sfbThrReducedLdData < FL2FXCONST_DBL(-0.5f)) + sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); /* minimum of 29 dB Ratio for Thresholds */ - if ((sfbEnLdData+FL2FXCONST_DBL(1.0f)) > FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)){ - sfbThrReducedLdData = fixMax(sfbThrReducedLdData, sfbEnLdData - FL2FXCONST_DBL(9.6336206/LD_DATA_SCALING)); + if ((sfbEnLdData + FL2FXCONST_DBL(1.0f)) > + FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)) { + sfbThrReducedLdData = fixMax( + sfbThrReducedLdData, + sfbEnLdData - FL2FXCONST_DBL(9.6336206 / LD_DATA_SCALING)); } - sfbThrReducedLdData = fixMax(MIN_LDTHRESH,sfbThrReducedLdData); + sfbThrReducedLdData = fixMax(MIN_LDTHRESH, sfbThrReducedLdData); - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } } @@ -1158,174 +1323,197 @@ static void FDKaacEnc_reduceThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], /***************************************************************************** functionname: FDKaacEnc_correctThresh -description: if pe difference deltaPe between desired pe and real pe is small enough, -the difference can be distributed among the scale factor bands. -New thresholds can be derived from this pe-difference +description: if pe difference deltaPe between desired pe and real pe is small +enough, the difference can be distributed among the scale factor bands. New +thresholds can be derived from this pe-difference *****************************************************************************/ -static void FDKaacEnc_correctThresh(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - FIXP_DBL thrExp[(8)][(2)][MAX_GROUPED_SFB], - const FIXP_DBL redVal[(8)], - const SCHAR redValScaling[(8)], - const INT deltaPe, - const INT processElements, - const INT elementOffset) -{ - INT ch, sfb, sfbGrp; - QC_OUT_CHANNEL *qcOutChan; - PSY_OUT_CHANNEL *psyOutChan; - PE_CHANNEL_DATA *peChanData; - FIXP_DBL thrFactorLdData; - FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; - FIXP_DBL *sfbPeFactorsLdData[(8)][(2)]; - FIXP_DBL sfbNActiveLinesLdData[(8)][(2)][MAX_GROUPED_SFB]; - INT normFactorInt; - FIXP_DBL normFactorLdData; - - INT nElements = elementOffset+processElements; - INT elementId; - - /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */ - for(elementId=elementOffset;elementId<nElements;elementId++) { - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - SHORT* ptr = qcElement[elementId]->qcOutChannel[ch]->quantSpec; - sfbPeFactorsLdData[elementId][ch] = (FIXP_DBL*)ptr; - } - } - - /* for each sfb calc relative factors for pe changes */ - normFactorInt = 0; - - for(elementId=elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - - qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; - peChanData = &qcElement[elementId]->peData.peChannelData[ch]; - - for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { - - if ( peChanData->sfbNActiveLines[sfbGrp+sfb] == 0 ) { - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); - } - else { - /* Both CalcLdInt and CalcLdData can be used! - * No offset has to be subtracted, because sfbNActiveLinesLdData - * is shorted while thrFactor calculation */ - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] = CalcLdInt(peChanData->sfbNActiveLines[sfbGrp+sfb]); - } - if ( ((ahFlag[elementId][ch][sfbGrp+sfb] < AH_ACTIVE) || (deltaPe > 0)) && - peChanData->sfbNActiveLines[sfbGrp+sfb] != 0 ) - { - if (thrExp[elementId][ch][sfbGrp+sfb] > -redVal[elementId]) { - - /* sfbPeFactors[ch][sfbGrp+sfb] = peChanData->sfbNActiveLines[sfbGrp+sfb] / - (thrExp[elementId][ch][sfbGrp+sfb] + redVal[elementId]); */ - - int minScale = fixMin(CountLeadingBits(thrExp[elementId][ch][sfbGrp+sfb]), CountLeadingBits(redVal[elementId]) - (DFRACT_BITS-1-redValScaling[elementId]) ) - 1; - - /* sumld = ld64( sfbThrExp + redVal ) */ - FIXP_DBL sumLd = CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp+sfb], minScale) + scaleValue(redVal[elementId], (DFRACT_BITS-1-redValScaling[elementId])+minScale)) - - (FIXP_DBL)(minScale<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - - if (sumLd < FL2FXCONST_DBL(0.f)) { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; - } - else { - if ( sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] > (FL2FXCONST_DBL(-1.f) + sumLd) ) { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - sumLd; - } - else { - sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb]; - } - } - - normFactorInt += (INT)CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]); - } - else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(1.0f); - } - else sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); +static void FDKaacEnc_correctThresh( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], + const FIXP_DBL thrExp[((8))][(2)][MAX_GROUPED_SFB], const FIXP_DBL redVal_m, + const SCHAR redVal_e, const INT deltaPe, const INT processElements, + const INT elementOffset) { + INT ch, sfb, sfbGrp; + QC_OUT_CHANNEL *qcOutChan; + PSY_OUT_CHANNEL *psyOutChan; + PE_CHANNEL_DATA *peChanData; + FIXP_DBL thrFactorLdData; + FIXP_DBL sfbEnLdData, sfbThrLdData, sfbThrReducedLdData; + FIXP_DBL *sfbPeFactorsLdData[((8))][(2)]; + FIXP_DBL(*sfbNActiveLinesLdData)[(2)][MAX_GROUPED_SFB]; + + INT normFactorInt; + FIXP_DBL normFactorLdData; + + INT nElements = elementOffset + processElements; + INT elementId; + + /* scratch is empty; use temporal memory from quantSpec in QC_OUT_CHANNEL */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + /* The reinterpret_cast is used to suppress a compiler warning. We know + * that qcElement[elementId]->qcOutChannel[ch]->quantSpec is sufficiently + * aligned, so the cast is safe */ + sfbPeFactorsLdData[elementId][ch] = + reinterpret_cast<FIXP_DBL *>(reinterpret_cast<void *>( + qcElement[elementId]->qcOutChannel[ch]->quantSpec)); + } + } + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_SfbNActiveLinesLdData is sufficiently aligned, so the + * cast is safe */ + sfbNActiveLinesLdData = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>( + reinterpret_cast<void *>(qcElement[0]->dynMem_SfbNActiveLinesLdData)); + + /* for each sfb calc relative factors for pe changes */ + normFactorInt = 0; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; + peChanData = &qcElement[elementId]->peData.peChannelData[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if (peChanData->sfbNActiveLines[sfbGrp + sfb] == 0) { + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(-1.0f); + } else { + /* Both CalcLdInt and CalcLdData can be used! + * No offset has to be subtracted, because sfbNActiveLinesLdData + * is shorted while thrFactor calculation */ + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] = + CalcLdInt(peChanData->sfbNActiveLines[sfbGrp + sfb]); } + if (((ahFlag[elementId][ch][sfbGrp + sfb] < AH_ACTIVE) || + (deltaPe > 0)) && + peChanData->sfbNActiveLines[sfbGrp + sfb] != 0) { + if (thrExp[elementId][ch][sfbGrp + sfb] > -redVal_m) { + /* sfbPeFactors[ch][sfbGrp+sfb] = + peChanData->sfbNActiveLines[sfbGrp+sfb] / + (thrExp[elementId][ch][sfbGrp+sfb] + + redVal[elementId]); */ + + int minScale = + fixMin( + CountLeadingBits(thrExp[elementId][ch][sfbGrp + sfb]), + CountLeadingBits(redVal_m) - redVal_e) - + 1; + + /* sumld = ld64( sfbThrExp + redVal ) */ + FIXP_DBL sumLd = + CalcLdData(scaleValue(thrExp[elementId][ch][sfbGrp + sfb], + minScale) + + scaleValue(redVal_m, redVal_e + minScale)) - + (FIXP_DBL)(minScale << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + + if (sumLd < FL2FXCONST_DBL(0.f)) { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + sumLd; + } else { + if (sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] > + (FL2FXCONST_DBL(-1.f) + sumLd)) { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + sumLd; + } else { + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb]; + } + } + + normFactorInt += (INT)CalcInvLdData( + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb]); + } else + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(1.0f); + } else + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] = + FL2FXCONST_DBL(-1.0f); } - } - } - } - - /* normFactorLdData = ld64(deltaPe/normFactorInt) */ - normFactorLdData = CalcLdData((FIXP_DBL)((deltaPe<0) ? (-deltaPe) : (deltaPe))) - CalcLdData((FIXP_DBL)normFactorInt); - - /* distribute the pe difference to the scalefactors - and calculate the according thresholds */ - for(elementId=elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; - peChanData = &qcElement[elementId]->peData.peChannelData[ch]; - - for(sfbGrp = 0;sfbGrp < psyOutChan->sfbCnt;sfbGrp+= psyOutChan->sfbPerGroup){ - for (sfb=0; sfb<psyOutChan->maxSfbPerGroup; sfb++) { - - if (peChanData->sfbNActiveLines[sfbGrp+sfb] > 0) { - - /* pe difference for this sfb */ - if ( (sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb]==FL2FXCONST_DBL(-1.0f)) || - (deltaPe==0) ) - { - thrFactorLdData = FL2FXCONST_DBL(0.f); - } - else { - /* new threshold */ - FIXP_DBL tmp = CalcInvLdData(sfbPeFactorsLdData[elementId][ch][sfbGrp+sfb] + normFactorLdData - sfbNActiveLinesLdData[elementId][ch][sfbGrp+sfb] - FL2FXCONST_DBL((float)LD_DATA_SHIFT/LD_DATA_SCALING)); - - /* limit thrFactor to 60dB */ - tmp = (deltaPe<0) ? tmp : (-tmp); - thrFactorLdData = FDKmin(tmp, FL2FXCONST_DBL(20.f/LD_DATA_SCALING)); - } - - /* new threshold */ - sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp+sfb]; - sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb]; - - if (thrFactorLdData < FL2FXCONST_DBL(0.f)) { - if( sfbThrLdData > (FL2FXCONST_DBL(-1.f)-thrFactorLdData) ) { - sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; - } - else { - sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); - } - } - else{ - sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; - } - - /* avoid hole */ - if ( (sfbThrReducedLdData - sfbEnLdData > qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) && - (ahFlag[elementId][ch][sfbGrp+sfb] == AH_INACTIVE) ) - { - /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ - if ( sfbEnLdData > (sfbThrLdData-qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]) ) { - sfbThrReducedLdData = qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] + sfbEnLdData; - } - else { - sfbThrReducedLdData = sfbThrLdData; - } - ahFlag[elementId][ch][sfbGrp+sfb] = AH_ACTIVE; - } - - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = sfbThrReducedLdData; + } + } + } + } + + /* normFactorLdData = ld64(deltaPe/normFactorInt) */ + normFactorLdData = + CalcLdData((FIXP_DBL)((deltaPe < 0) ? (-deltaPe) : (deltaPe))) - + CalcLdData((FIXP_DBL)normFactorInt); + + /* distribute the pe difference to the scalefactors + and calculate the according thresholds */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + qcOutChan = qcElement[elementId]->qcOutChannel[ch]; + psyOutChan = psyOutElement[elementId]->psyOutChannel[ch]; + peChanData = &qcElement[elementId]->peData.peChannelData[ch]; + + for (sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; + sfbGrp += psyOutChan->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChan->maxSfbPerGroup; sfb++) { + if (peChanData->sfbNActiveLines[sfbGrp + sfb] > 0) { + /* pe difference for this sfb */ + if ((sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] == + FL2FXCONST_DBL(-1.0f)) || + (deltaPe == 0)) { + thrFactorLdData = FL2FXCONST_DBL(0.f); + } else { + /* new threshold */ + FIXP_DBL tmp = CalcInvLdData( + sfbPeFactorsLdData[elementId][ch][sfbGrp + sfb] + + normFactorLdData - + sfbNActiveLinesLdData[elementId][ch][sfbGrp + sfb] - + FL2FXCONST_DBL((float)LD_DATA_SHIFT / LD_DATA_SCALING)); + + /* limit thrFactor to 60dB */ + tmp = (deltaPe < 0) ? tmp : (-tmp); + thrFactorLdData = + fMin(tmp, FL2FXCONST_DBL(20.f / LD_DATA_SCALING)); } + + /* new threshold */ + sfbThrLdData = qcOutChan->sfbThresholdLdData[sfbGrp + sfb]; + sfbEnLdData = qcOutChan->sfbWeightedEnergyLdData[sfbGrp + sfb]; + + if (thrFactorLdData < FL2FXCONST_DBL(0.f)) { + if (sfbThrLdData > (FL2FXCONST_DBL(-1.f) - thrFactorLdData)) { + sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; + } else { + sfbThrReducedLdData = FL2FXCONST_DBL(-1.f); + } + } else { + sfbThrReducedLdData = sfbThrLdData + thrFactorLdData; + } + + /* avoid hole */ + if ((sfbThrReducedLdData - sfbEnLdData > + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb]) && + (ahFlag[elementId][ch][sfbGrp + sfb] == AH_INACTIVE)) { + /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, + * sfbThr); */ + if (sfbEnLdData > + (sfbThrLdData - qcOutChan->sfbMinSnrLdData[sfbGrp + sfb])) { + sfbThrReducedLdData = + qcOutChan->sfbMinSnrLdData[sfbGrp + sfb] + sfbEnLdData; + } else { + sfbThrReducedLdData = sfbThrLdData; + } + ahFlag[elementId][ch][sfbGrp + sfb] = AH_ACTIVE; + } + + qcOutChan->sfbThresholdLdData[sfbGrp + sfb] = sfbThrReducedLdData; } } - } - } - } + } + } + } + } } /***************************************************************************** @@ -1333,628 +1521,688 @@ static void FDKaacEnc_correctThresh(CHANNEL_MAPPING* cm, description: if the desired pe can not be reached, reduce pe by reducing minSnr *****************************************************************************/ -void FDKaacEnc_reduceMinSnr(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - const INT desiredPe, - INT* redPeGlobal, - const INT processElements, - const INT elementOffset) +static void FDKaacEnc_reduceMinSnr( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe, + INT *const redPeGlobal, const INT processElements, const INT elementOffset) { - INT elementId; - INT nElements = elementOffset+processElements; - - INT newGlobalPe = *redPeGlobal; - - for(elementId=elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - INT ch; - INT maxSfbPerGroup[2]; - INT sfbCnt[2]; - INT sfbPerGroup[2]; - - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; - sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; - sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; - } + INT ch, elementId, globalMaxSfb = 0; + const INT nElements = elementOffset + processElements; + INT newGlobalPe = *redPeGlobal; - PE_DATA *peData = &qcElement[elementId]->peData; - - do - { - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - - INT sfb, sfbGrp; - QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch]; - INT noReduction = 1; - - if (maxSfbPerGroup[ch]>=0) { /* sfb in next channel */ - INT deltaPe = 0; - sfb = maxSfbPerGroup[ch]--; - noReduction = 0; - - for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { - - if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] < SnrLdFac) - { - /* increase threshold to new minSnr of 1dB */ - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] = SnrLdFac; - - /* sfbThrReduced = max(psyOutChan[ch]->sfbMinSnr[i] * sfbEn, sfbThr); */ - if ( qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] >= qcOutChan->sfbThresholdLdData[sfbGrp+sfb] - qcOutChan->sfbMinSnrLdData[sfbGrp+sfb] ) { - - qcOutChan->sfbThresholdLdData[sfbGrp+sfb] = qcOutChan->sfbWeightedEnergyLdData[sfbGrp+sfb] + qcOutChan->sfbMinSnrLdData[sfbGrp+sfb]; - - /* calc new pe */ - /* C2 + C3*ld(1/0.8) = 1.5 */ - deltaPe -= (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); - - /* sfbPe = 1.5 * sfbNLines */ - peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = (3*peData->peChannelData[ch].sfbNLines[sfbGrp+sfb]) << (PE_CONSTPART_SHIFT-1); - deltaPe += (peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT); - } - } - - } /* sfbGrp loop */ + if (newGlobalPe <= desiredPe) { + goto bail; + } - peData->pe += deltaPe; - peData->peChannelData[ch].pe += deltaPe; - newGlobalPe += deltaPe; + /* global maximum of maxSfbPerGroup */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + globalMaxSfb = + fMax(globalMaxSfb, + psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup); + } + } + } - /* stop if enough has been saved */ - if (peData->pe <= desiredPe) { - goto bail; + /* as long as globalPE is above desirePE reduce SNR to 1.0 dB, starting at + * highest SFB */ + while ((newGlobalPe > desiredPe) && (--globalMaxSfb >= 0)) { + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + PE_DATA *peData = &qcElement[elementId]->peData; + + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + QC_OUT_CHANNEL *qcOutChan = qcElement[elementId]->qcOutChannel[ch]; + PSY_OUT_CHANNEL *psyOutChan = + psyOutElement[elementId]->psyOutChannel[ch]; + + /* try to reduce SNR of channel's uppermost SFB(s) */ + if (globalMaxSfb < psyOutChan->maxSfbPerGroup) { + INT sfb, deltaPe = 0; + + for (sfb = globalMaxSfb; sfb < psyOutChan->sfbCnt; + sfb += psyOutChan->sfbPerGroup) { + if (ahFlag[elementId][ch][sfb] != NO_AH && + qcOutChan->sfbMinSnrLdData[sfb] < SnrLdFac && + (qcOutChan->sfbWeightedEnergyLdData[sfb] > + qcOutChan->sfbThresholdLdData[sfb] - SnrLdFac)) { + /* increase threshold to new minSnr of 1dB */ + qcOutChan->sfbMinSnrLdData[sfb] = SnrLdFac; + qcOutChan->sfbThresholdLdData[sfb] = + qcOutChan->sfbWeightedEnergyLdData[sfb] + SnrLdFac; + + /* calc new pe */ + /* C2 + C3*ld(1/0.8) = 1.5 */ + deltaPe -= peData->peChannelData[ch].sfbPe[sfb]; + + /* sfbPe = 1.5 * sfbNLines */ + peData->peChannelData[ch].sfbPe[sfb] = + (3 * peData->peChannelData[ch].sfbNLines[sfb]) + << (PE_CONSTPART_SHIFT - 1); + deltaPe += peData->peChannelData[ch].sfbPe[sfb]; } - } /* sfb > 0 */ - - if ( (ch==(cm->elInfo[elementId].nChannelsInEl-1)) && noReduction ) { - goto bail; - } + } /* sfb loop */ - } /* ch loop */ + deltaPe >>= PE_CONSTPART_SHIFT; + peData->pe += deltaPe; + peData->peChannelData[ch].pe += deltaPe; + newGlobalPe += deltaPe; - } while ( peData->pe > desiredPe); + } /* if globalMaxSfb < maxSfbPerGroup */ - } /* != ID_DSE */ - } /* element loop */ + /* stop if enough has been saved */ + if (newGlobalPe <= desiredPe) { + goto bail; + } + } /* ch loop */ + } /* != ID_DSE */ + } /* elementId loop */ + } /* while ( newGlobalPe > desiredPe) && (--globalMaxSfb >= 0) ) */ bail: - /* update global PE */ - *redPeGlobal = newGlobalPe; + /* update global PE */ + *redPeGlobal = newGlobalPe; } - /***************************************************************************** functionname: FDKaacEnc_allowMoreHoles description: if the desired pe can not be reached, some more scalefactor bands have to be quantized to zero *****************************************************************************/ -static void FDKaacEnc_allowMoreHoles(CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - ATS_ELEMENT* AdjThrStateElement[(8)], - UCHAR ahFlag[(8)][(2)][MAX_GROUPED_SFB], - const INT desiredPe, - const INT currentPe, - const int processElements, - const int elementOffset) -{ +static void FDKaacEnc_allowMoreHoles( + const CHANNEL_MAPPING *const cm, QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const ATS_ELEMENT *const AdjThrStateElement[((8))], + UCHAR ahFlag[((8))][(2)][MAX_GROUPED_SFB], const INT desiredPe, + const INT currentPe, const int processElements, const int elementOffset) { INT elementId; - INT nElements = elementOffset+processElements; + INT nElements = elementOffset + processElements; INT actPe = currentPe; if (actPe <= desiredPe) { return; /* nothing to do */ } - for (elementId = elementOffset;elementId<nElements;elementId++) { + for (elementId = elementOffset; elementId < nElements; elementId++) { if (cm->elInfo[elementId].elType != ID_DSE) { - INT ch, sfb, sfbGrp; PE_DATA *peData = &qcElement[elementId]->peData; const INT nChannels = cm->elInfo[elementId].nChannelsInEl; - QC_OUT_CHANNEL* qcOutChannel[(2)] = {NULL}; - PSY_OUT_CHANNEL* psyOutChannel[(2)] = {NULL}; - - for (ch=0; ch<nChannels; ch++) { + QC_OUT_CHANNEL *qcOutChannel[(2)] = {NULL}; + PSY_OUT_CHANNEL *psyOutChannel[(2)] = {NULL}; + for (ch = 0; ch < nChannels; ch++) { /* init pointers */ qcOutChannel[ch] = qcElement[elementId]->qcOutChannel[ch]; psyOutChannel[ch] = psyOutElement[elementId]->psyOutChannel[ch]; - for(sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+= psyOutChannel[ch]->sfbPerGroup) { - for (sfb=psyOutChannel[ch]->maxSfbPerGroup; sfb<psyOutChannel[ch]->sfbPerGroup; sfb++) { - peData->peChannelData[ch].sfbPe[sfbGrp+sfb] = 0; + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = psyOutChannel[ch]->maxSfbPerGroup; + sfb < psyOutChannel[ch]->sfbPerGroup; sfb++) { + peData->peChannelData[ch].sfbPe[sfbGrp + sfb] = 0; } } } /* for MS allow hole in the channel with less energy */ - if ( nChannels==2 && psyOutChannel[0]->lastWindowSequence==psyOutChannel[1]->lastWindowSequence ) { - - for (sfb=0; sfb<psyOutChannel[0]->maxSfbPerGroup; sfb++) { - for(sfbGrp=0; sfbGrp < psyOutChannel[0]->sfbCnt; sfbGrp+=psyOutChannel[0]->sfbPerGroup) { - if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp+sfb]) { - FIXP_DBL EnergyLd_L = qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp+sfb]; - FIXP_DBL EnergyLd_R = qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp+sfb]; + if (nChannels == 2 && psyOutChannel[0]->lastWindowSequence == + psyOutChannel[1]->lastWindowSequence) { + for (sfb = psyOutChannel[0]->maxSfbPerGroup - 1; sfb >= 0; sfb--) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[0]->sfbCnt; + sfbGrp += psyOutChannel[0]->sfbPerGroup) { + if (psyOutElement[elementId]->toolsInfo.msMask[sfbGrp + sfb]) { + FIXP_DBL EnergyLd_L = + qcOutChannel[0]->sfbWeightedEnergyLdData[sfbGrp + sfb]; + FIXP_DBL EnergyLd_R = + qcOutChannel[1]->sfbWeightedEnergyLdData[sfbGrp + sfb]; /* allow hole in side channel ? */ - if ( (ahFlag[elementId][1][sfbGrp+sfb] != NO_AH) && - (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) - > ((EnergyLd_R>>1) - (EnergyLd_L>>1))) ) - { - ahFlag[elementId][1][sfbGrp+sfb] = NO_AH; - qcOutChannel[1]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_R; - actPe -= peData->peChannelData[1].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + if ((ahFlag[elementId][1][sfbGrp + sfb] != NO_AH) && + (((FL2FXCONST_DBL(-0.02065512648f) >> 1) + + (qcOutChannel[0]->sfbMinSnrLdData[sfbGrp + sfb] >> 1)) > + ((EnergyLd_R >> 1) - (EnergyLd_L >> 1)))) { + ahFlag[elementId][1][sfbGrp + sfb] = NO_AH; + qcOutChannel[1]->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + EnergyLd_R; + actPe -= peData->peChannelData[1].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } /* allow hole in mid channel ? */ - else if ( (ahFlag[elementId][0][sfbGrp+sfb] != NO_AH) && - (((FL2FXCONST_DBL(-0.02065512648f)>>1) + (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp+sfb]>>1)) - > ((EnergyLd_L>>1) - (EnergyLd_R>>1))) ) - { - ahFlag[elementId][0][sfbGrp+sfb] = NO_AH; - qcOutChannel[0]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + EnergyLd_L; - actPe -= peData->peChannelData[0].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + else if ((ahFlag[elementId][0][sfbGrp + sfb] != NO_AH) && + (((FL2FXCONST_DBL(-0.02065512648f) >> 1) + + (qcOutChannel[1]->sfbMinSnrLdData[sfbGrp + sfb] >> + 1)) > ((EnergyLd_L >> 1) - (EnergyLd_R >> 1)))) { + ahFlag[elementId][0][sfbGrp + sfb] = NO_AH; + qcOutChannel[0]->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + EnergyLd_L; + actPe -= peData->peChannelData[0].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } /* if (ahFlag) */ - } /* if MS */ - } /* sfbGrp */ + } /* if MS */ + } /* sfbGrp */ if (actPe <= desiredPe) { return; /* stop if enough has been saved */ } } /* sfb */ - } /* MS possible ? */ - - /* more holes necessary? subsequently erase bands - starting with low energies */ - INT startSfb[2]; - FIXP_DBL avgEnLD64,minEnLD64; - INT ahCnt; - FIXP_DBL ahCntLD64; - INT enIdx; - FIXP_DBL enLD64[4]; - FIXP_DBL avgEn; - - /* do not go below startSfb */ - for (ch=0; ch<nChannels; ch++) { - if (psyOutChannel[ch]->lastWindowSequence != SHORT_WINDOW) - startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbL; - else - startSfb[ch] = AdjThrStateElement[elementId]->ahParam.startSfbS; - } - - /* calc avg and min energies of bands that avoid holes */ - avgEn = FL2FXCONST_DBL(0.0f); - minEnLD64 = FL2FXCONST_DBL(0.0f); - ahCnt = 0; + } /* MS possible ? */ - for (ch=0; ch<nChannels; ch++) { - - sfbGrp=0; - sfb=startSfb[ch]; + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ - do { - for (; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - if ((ahFlag[elementId][ch][sfbGrp+sfb]!=NO_AH) && - (qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb] > qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb])){ - minEnLD64 = fixMin(minEnLD64,qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb]); - avgEn += qcOutChannel[ch]->sfbEnergy[sfbGrp+sfb] >> 6; - ahCnt++; - } + if (actPe > desiredPe) { + /* more holes necessary? subsequently erase bands starting with low energies + */ + INT ch, sfb, sfbGrp; + INT minSfb, maxSfb; + INT enIdx, ahCnt, done; + INT startSfb[(8)]; + INT sfbCnt[(8)]; + INT sfbPerGroup[(8)]; + INT maxSfbPerGroup[(8)]; + FIXP_DBL avgEn; + FIXP_DBL minEnLD64; + FIXP_DBL avgEnLD64; + FIXP_DBL enLD64[NUM_NRG_LEVS]; + INT avgEn_e; + + /* get the scaling factor over all audio elements and channels */ + maxSfb = 0; + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + for (sfbGrp = 0; + sfbGrp < psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; + sfbGrp += + psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup) { + maxSfb += + psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup; } - - sfbGrp += psyOutChannel[ch]->sfbPerGroup; - sfb=0; - - } while (sfbGrp < psyOutChannel[ch]->sfbCnt); - } - - if ( (avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0) ) { - avgEnLD64 = FL2FXCONST_DBL(0.0f); - } - else { - avgEnLD64 = CalcLdData(avgEn); - ahCntLD64 = CalcLdInt(ahCnt); - avgEnLD64 = avgEnLD64 + FL2FXCONST_DBL(0.09375f) - ahCntLD64; /* compensate shift with 6 */ + } } + } + avgEn_e = + (DFRACT_BITS - fixnormz_D((LONG)fMax(0, maxSfb - 1))); /* ilog2() */ + + ahCnt = 0; + maxSfb = 0; + minSfb = MAX_SFB; + avgEn = FL2FXCONST_DBL(0.0f); + minEnLD64 = FL2FXCONST_DBL(0.0f); + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch]; + QC_OUT_CHANNEL *qcOutChannel = qcElement[elementId]->qcOutChannel[ch]; + PSY_OUT_CHANNEL *psyOutChannel = + psyOutElement[elementId]->psyOutChannel[ch]; + + maxSfbPerGroup[chIdx] = psyOutChannel->maxSfbPerGroup; + sfbCnt[chIdx] = psyOutChannel->sfbCnt; + sfbPerGroup[chIdx] = psyOutChannel->sfbPerGroup; + + maxSfb = fMax(maxSfb, psyOutChannel->maxSfbPerGroup); + + if (psyOutChannel->lastWindowSequence != SHORT_WINDOW) { + startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbL; + } else { + startSfb[chIdx] = AdjThrStateElement[elementId]->ahParam.startSfbS; + } - /* calc some energy borders between minEn and avgEn */ - /* for (enIdx=0; enIdx<4; enIdx++) */ - /* en[enIdx] = minEn * (float)FDKpow(avgEn/(minEn+FLT_MIN), (2*enIdx+1)/7.0f); */ - enLD64[0] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.14285714285f)); - enLD64[1] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.42857142857f)); - enLD64[2] = minEnLD64 + fMult((avgEnLD64-minEnLD64),FL2FXCONST_DBL(0.71428571428f)); - enLD64[3] = minEnLD64 + (avgEnLD64-minEnLD64); - - for (enIdx=0; enIdx<4; enIdx++) { - INT noReduction = 1; - - INT maxSfbPerGroup[2]; - INT sfbCnt[2]; - INT sfbPerGroup[2]; - - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { - maxSfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->maxSfbPerGroup-1; - sfbCnt[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbCnt; - sfbPerGroup[ch] = psyOutElement[elementId]->psyOutChannel[ch]->sfbPerGroup; - } + minSfb = fMin(minSfb, startSfb[chIdx]); - do { + sfbGrp = 0; + sfb = startSfb[chIdx]; - noReduction = 1; + do { + for (; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + if ((ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH) && + (qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb] > + qcOutChannel->sfbThresholdLdData[sfbGrp + sfb])) { + minEnLD64 = fixMin(minEnLD64, + qcOutChannel->sfbEnergyLdData[sfbGrp + sfb]); + avgEn += qcOutChannel->sfbEnergy[sfbGrp + sfb] >> avgEn_e; + ahCnt++; + } + } - for(ch=0; ch<cm->elInfo[elementId].nChannelsInEl; ch++) { + sfbGrp += psyOutChannel->sfbPerGroup; + sfb = startSfb[chIdx]; - INT sfb, sfbGrp; + } while (sfbGrp < psyOutChannel->sfbCnt); + } + } /* (cm->elInfo[elementId].elType != ID_DSE) */ + } /* (elementId = elementOffset;elementId<nElements;elementId++) */ - /* start with lowest energy border at highest sfb */ - if (maxSfbPerGroup[ch]>=startSfb[ch]) { /* sfb in next channel */ - sfb = maxSfbPerGroup[ch]--; - noReduction = 0; + if ((avgEn == FL2FXCONST_DBL(0.0f)) || (ahCnt == 0)) { + avgEnLD64 = FL2FXCONST_DBL(0.0f); + } else { + avgEnLD64 = CalcLdData(avgEn) + + (FIXP_DBL)(avgEn_e << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) - + CalcLdInt(ahCnt); + } - for (sfbGrp = 0; sfbGrp < sfbCnt[ch]; sfbGrp += sfbPerGroup[ch]) { + /* calc some energy borders between minEn and avgEn */ + + /* for (enIdx = 0; enIdx < NUM_NRG_LEVS; enIdx++) { + en[enIdx] = (2.0f*enIdx+1.0f)/(2.0f*NUM_NRG_LEVS-1.0f); + } */ + enLD64[0] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.06666667f)); + enLD64[1] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.20000000f)); + enLD64[2] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.33333334f)); + enLD64[3] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.46666667f)); + enLD64[4] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.60000002f)); + enLD64[5] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.73333335f)); + enLD64[6] = + minEnLD64 + fMult((avgEnLD64 - minEnLD64), FL2FXCONST_DBL(0.86666667f)); + enLD64[7] = minEnLD64 + (avgEnLD64 - minEnLD64); + + done = 0; + enIdx = 0; + sfb = maxSfb - 1; + + while (!done) { + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + PE_DATA *peData = &qcElement[elementId]->peData; + for (ch = 0; ch < cm->elInfo[elementId].nChannelsInEl; ch++) { + const INT chIdx = cm->elInfo[elementId].ChannelIndex[ch]; + QC_OUT_CHANNEL *qcOutChannel = + qcElement[elementId]->qcOutChannel[ch]; + if (sfb >= startSfb[chIdx] && sfb < maxSfbPerGroup[chIdx]) { + for (sfbGrp = 0; sfbGrp < sfbCnt[chIdx]; + sfbGrp += sfbPerGroup[chIdx]) { /* sfb energy below border ? */ - if (ahFlag[elementId][ch][sfbGrp+sfb] != NO_AH && qcOutChannel[ch]->sfbEnergyLdData[sfbGrp+sfb] < enLD64[enIdx]) { + if (ahFlag[elementId][ch][sfbGrp + sfb] != NO_AH && + qcOutChannel->sfbEnergyLdData[sfbGrp + sfb] < + enLD64[enIdx]) { /* allow hole */ - ahFlag[elementId][ch][sfbGrp+sfb] = NO_AH; - qcOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = FL2FXCONST_DBL(0.015625f) + qcOutChannel[ch]->sfbWeightedEnergyLdData[sfbGrp+sfb]; - actPe -= peData->peChannelData[ch].sfbPe[sfbGrp+sfb]>>PE_CONSTPART_SHIFT; + ahFlag[elementId][ch][sfbGrp + sfb] = NO_AH; + qcOutChannel->sfbThresholdLdData[sfbGrp + sfb] = + FL2FXCONST_DBL(0.015625f) + + qcOutChannel->sfbWeightedEnergyLdData[sfbGrp + sfb]; + actPe -= peData->peChannelData[ch].sfbPe[sfbGrp + sfb] >> + PE_CONSTPART_SHIFT; } - } /* sfbGrp */ - - if (actPe <= desiredPe) { - return; /* stop if enough has been saved */ - } - } /* sfb > 0 */ - } /* ch loop */ - - } while( (noReduction == 0) && (actPe > desiredPe) ); - - if (actPe <= desiredPe) { - return; /* stop if enough has been saved */ + if (actPe <= desiredPe) { + return; /* stop if enough has been saved */ + } + } /* sfbGrp */ + } /* sfb */ + } /* nChannelsInEl */ + } /* ID_DSE */ + } /* elementID */ + + sfb--; + if (sfb < minSfb) { + /* restart with next energy border */ + sfb = maxSfb; + enIdx++; + if (enIdx >= NUM_NRG_LEVS) { + done = 1; } - - } /* enIdx loop */ - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - + } + } /* done */ + } /* (actPe <= desiredPe) */ } /* reset avoid hole flags from AH_ACTIVE to AH_INACTIVE */ -static void FDKaacEnc_resetAHFlags( UCHAR ahFlag[(2)][MAX_GROUPED_SFB], - const int nChannels, - PSY_OUT_CHANNEL *psyOutChannel[(2)]) -{ +static void FDKaacEnc_resetAHFlags( + UCHAR ahFlag[(2)][MAX_GROUPED_SFB], const INT nChannels, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)]) { int ch, sfb, sfbGrp; - for(ch=0; ch<nChannels; ch++) { - for (sfbGrp=0; sfbGrp < psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - if ( ahFlag[ch][sfbGrp+sfb] == AH_ACTIVE) { - ahFlag[ch][sfbGrp+sfb] = AH_INACTIVE; + for (ch = 0; ch < nChannels; ch++) { + for (sfbGrp = 0; sfbGrp < psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel[ch]->maxSfbPerGroup; sfb++) { + if (ahFlag[ch][sfbGrp + sfb] == AH_ACTIVE) { + ahFlag[ch][sfbGrp + sfb] = AH_INACTIVE; } } } } } +static FIXP_DBL CalcRedValPower(FIXP_DBL num, FIXP_DBL denum, INT *scaling) { + FIXP_DBL value = FL2FXCONST_DBL(0.f); -static FIXP_DBL CalcRedValPower(FIXP_DBL num, - FIXP_DBL denum, - INT* scaling ) -{ - FIXP_DBL value = FL2FXCONST_DBL(0.f); - - if (num>=FL2FXCONST_DBL(0.f)) { - value = fDivNorm( num, denum, scaling); - } - else { - value = -fDivNorm( -num, denum, scaling); - } - value = f2Pow(value, *scaling, scaling); - *scaling = DFRACT_BITS-1-*scaling; + if (num >= FL2FXCONST_DBL(0.f)) { + value = fDivNorm(num, denum, scaling); + } else { + value = -fDivNorm(-num, denum, scaling); + } + value = f2Pow(value, *scaling, scaling); - return value; + return value; } - /***************************************************************************** functionname: FDKaacEnc_adaptThresholdsToPe -description: two guesses for the reduction value and one final correction of the thresholds +description: two guesses for the reduction value and one final correction of +the thresholds *****************************************************************************/ -static void FDKaacEnc_adaptThresholdsToPe(CHANNEL_MAPPING* cm, - ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - PSY_OUT_ELEMENT* psyOutElement[(8)], - const INT desiredPe, - const INT maxIter2ndGuess, - const INT processElements, - const INT elementOffset) -{ - FIXP_DBL redValue[(8)]; - SCHAR redValScaling[(8)]; - UCHAR pAhFlag[(8)][(2)][MAX_GROUPED_SFB]; - FIXP_DBL pThrExp[(8)][(2)][MAX_GROUPED_SFB]; - int iter; - - INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal; - constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0; - - int elementId; +static void FDKaacEnc_adaptThresholdsToPe( + const CHANNEL_MAPPING *const cm, + ATS_ELEMENT *const AdjThrStateElement[((8))], + QC_OUT_ELEMENT *const qcElement[((8))], + const PSY_OUT_ELEMENT *const psyOutElement[((8))], const INT desiredPe, + const INT maxIter2ndGuess, const INT processElements, + const INT elementOffset) { + FIXP_DBL reductionValue_m; + SCHAR reductionValue_e; + UCHAR(*pAhFlag)[(2)][MAX_GROUPED_SFB]; + FIXP_DBL(*pThrExp)[(2)][MAX_GROUPED_SFB]; + int iter; + + INT constPartGlobal, noRedPeGlobal, nActiveLinesGlobal, redPeGlobal; + constPartGlobal = noRedPeGlobal = nActiveLinesGlobal = redPeGlobal = 0; + + int elementId; + + int nElements = elementOffset + processElements; + if (nElements > cm->nElements) { + nElements = cm->nElements; + } - int nElements = elementOffset+processElements; - if(nElements > cm->nElements) { - nElements = cm->nElements; - } + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_Ah_Flag is sufficiently aligned, so the cast is safe + */ + pAhFlag = reinterpret_cast<UCHAR(*)[(2)][MAX_GROUPED_SFB]>( + reinterpret_cast<void *>(qcElement[0]->dynMem_Ah_Flag)); + /* The reinterpret_cast is used to suppress a compiler warning. We know that + * qcElement[0]->dynMem_Thr_Exp is sufficiently aligned, so the cast is safe + */ + pThrExp = reinterpret_cast<FIXP_DBL(*)[(2)][MAX_GROUPED_SFB]>( + reinterpret_cast<void *>(qcElement[0]->dynMem_Thr_Exp)); - /* ------------------------------------------------------- */ - /* Part I: Initialize data structures and variables... */ - /* ------------------------------------------------------- */ - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* thresholds to the power of redExp */ - FDKaacEnc_calcThreshExp(pThrExp[elementId], qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, nChannels); - - /* lower the minSnr requirements for low energies compared to the average - energy in this frame */ - FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, &AdjThrStateElement[elementId]->minSnrAdaptParam, nChannels); - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - FDKaacEnc_initAvoidHoleFlag(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], &psyOutElement[elementId]->toolsInfo, nChannels, peData, &AdjThrStateElement[elementId]->ahParam); + /* ------------------------------------------------------- */ + /* Part I: Initialize data structures and variables... */ + /* ------------------------------------------------------- */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; - /* sum up */ - constPartGlobal += peData->constPart; - noRedPeGlobal += peData->pe; - nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1); + /* thresholds to the power of redExp */ + FDKaacEnc_calcThreshExp( + pThrExp[elementId], qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, nChannels); + + /* lower the minSnr requirements for low energies compared to the average + energy in this frame */ + FDKaacEnc_adaptMinSnr(qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, + &AdjThrStateElement[elementId]->minSnrAdaptParam, + nChannels); + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + FDKaacEnc_initAvoidHoleFlag( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + &psyOutElement[elementId]->toolsInfo, nChannels, + &AdjThrStateElement[elementId]->ahParam); + + /* sum up */ + constPartGlobal += peData->constPart; + noRedPeGlobal += peData->pe; + nActiveLinesGlobal += fixMax((INT)peData->nActiveLines, 1); - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* + First guess of reduction value: + avgThrExp = (float)pow(2.0f, (constPartGlobal - noRedPeGlobal)/(4.0f * + nActiveLinesGlobal)); redVal = (float)pow(2.0f, (constPartGlobal - + desiredPe)/(4.0f * nActiveLinesGlobal)) - avgThrExp; redVal = max(0.f, + redVal); + */ + int redVal_e, avgThrExp_e, result_e; + FIXP_DBL redVal_m, avgThrExp_m; + + redVal_m = CalcRedValPower(constPartGlobal - desiredPe, + 4 * nActiveLinesGlobal, &redVal_e); + avgThrExp_m = CalcRedValPower(constPartGlobal - noRedPeGlobal, + 4 * nActiveLinesGlobal, &avgThrExp_e); + result_e = fMax(redVal_e, avgThrExp_e) + 1; + + reductionValue_m = fMax(FL2FXCONST_DBL(0.f), + scaleValue(redVal_m, redVal_e - result_e) - + scaleValue(avgThrExp_m, avgThrExp_e - result_e)); + reductionValue_e = result_e; + + /* ----------------------------------------------------------------------- */ + /* Part II: Calculate bit consumption of initial bit constraints setup */ + /* ----------------------------------------------------------------------- */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; - /* ----------------------------------------------------------------------- */ - /* Part II: Calculate bit consumption of initial bit constraints setup */ - /* ----------------------------------------------------------------------- */ - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - /* - redVal = ( 2 ^ ( (constPartGlobal-desiredPe) / (invRedExp*nActiveLinesGlobal) ) - - 2 ^ ( (constPartGlobal-noRedPeGlobal) / (invRedExp*nActiveLinesGlobal) ) ) - */ - - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* first guess of reduction value */ - int scale0=0, scale1=0; - FIXP_DBL tmp0 = CalcRedValPower( constPartGlobal-desiredPe, 4*nActiveLinesGlobal, &scale0 ); - FIXP_DBL tmp1 = CalcRedValPower( constPartGlobal-noRedPeGlobal, 4*nActiveLinesGlobal, &scale1 ); - - int scalMin = FDKmin(scale0, scale1)-1; - - redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); - redValScaling[elementId] = scalMin; - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); - - /* pe after first guess */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - - redPeGlobal += peData->pe; - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - /* -------------------------------------------------- */ - /* Part III: Iterate until bit constraints are met */ - /* -------------------------------------------------- */ - iter = 0; - while ((fixp_abs(redPeGlobal - desiredPe) > fMultI(FL2FXCONST_DBL(0.05f),desiredPe)) && (iter < maxIter2ndGuess)) { + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsCBR( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e); - INT desiredPeNoAHGlobal; - INT redPeNoAHGlobal = 0; - INT constPartNoAHGlobal = 0; - INT nActiveLinesNoAHGlobal = 0; + /* pe after first guess */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { + redPeGlobal += peData->pe; + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* -------------------------------------------------- */ + /* Part III: Iterate until bit constraints are met */ + /* -------------------------------------------------- */ + iter = 0; + while ((fixp_abs(redPeGlobal - desiredPe) > + fMultI(FL2FXCONST_DBL(0.05f), desiredPe)) && + (iter < maxIter2ndGuess)) { + INT desiredPeNoAHGlobal; + INT redPeNoAHGlobal = 0; + INT constPartNoAHGlobal = 0; + INT nActiveLinesNoAHGlobal = 0; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT redPeNoAH, constPartNoAH, nActiveLinesNoAH; + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* pe for bands where avoid hole is inactive */ + FDKaacEnc_FDKaacEnc_calcPeNoAH( + &redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, peData, + pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel, + nChannels); + + redPeNoAHGlobal += redPeNoAH; + constPartNoAHGlobal += constPartNoAH; + nActiveLinesNoAHGlobal += nActiveLinesNoAH; + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + /* Calculate new redVal ... */ + if (desiredPe < redPeGlobal) { + /* new desired pe without bands where avoid hole is active */ + desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal); + + /* limit desiredPeNoAH to positive values, as the PE can not become + * negative */ + desiredPeNoAHGlobal = fMax(0, desiredPeNoAHGlobal); + + /* second guess (only if there are bands left where avoid hole is + * inactive)*/ + if (nActiveLinesNoAHGlobal > 0) { + /* + avgThrExp = (float)pow(2.0f, (constPartNoAHGlobal - redPeNoAHGlobal) / + (4.0f * nActiveLinesNoAHGlobal)); redVal += (float)pow(2.0f, + (constPartNoAHGlobal - desiredPeNoAHGlobal) / (4.0f * + nActiveLinesNoAHGlobal)) - avgThrExp; redVal = max(0.0f, redVal); + */ + + redVal_m = CalcRedValPower(constPartNoAHGlobal - desiredPeNoAHGlobal, + 4 * nActiveLinesNoAHGlobal, &redVal_e); + avgThrExp_m = CalcRedValPower(constPartNoAHGlobal - redPeNoAHGlobal, + 4 * nActiveLinesNoAHGlobal, &avgThrExp_e); + result_e = fMax(reductionValue_e, fMax(redVal_e, avgThrExp_e) + 1) + 1; + + reductionValue_m = + fMax(FL2FXCONST_DBL(0.f), + scaleValue(reductionValue_m, reductionValue_e - result_e) + + scaleValue(redVal_m, redVal_e - result_e) - + scaleValue(avgThrExp_m, avgThrExp_e - result_e)); + reductionValue_e = result_e; + + } /* nActiveLinesNoAHGlobal > 0 */ + } else { + /* redVal *= redPeGlobal/desiredPe; */ + int sc0, sc1; + reductionValue_m = fMultNorm( + reductionValue_m, + fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &sc0), &sc1); + reductionValue_e += sc0 + sc1; + + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + FDKaacEnc_resetAHFlags(pAhFlag[elementId], + cm->elInfo[elementId].nChannelsInEl, + psyOutElement[elementId]->psyOutChannel); + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + } - INT redPeNoAH, constPartNoAH, nActiveLinesNoAH; - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* pe for bands where avoid hole is inactive */ - FDKaacEnc_FDKaacEnc_calcPeNoAH(&redPeNoAH, &constPartNoAH, &nActiveLinesNoAH, - peData, pAhFlag[elementId], psyOutElement[elementId]->psyOutChannel, nChannels); - - redPeNoAHGlobal += redPeNoAH; - constPartNoAHGlobal += constPartNoAH; - nActiveLinesNoAHGlobal += nActiveLinesNoAH; - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - /* Calculate new redVal ... */ - if(desiredPe < redPeGlobal) { - - /* new desired pe without bands where avoid hole is active */ - desiredPeNoAHGlobal = desiredPe - (redPeGlobal - redPeNoAHGlobal); - - /* limit desiredPeNoAH to positive values, as the PE can not become negative */ - desiredPeNoAHGlobal = FDKmax(0,desiredPeNoAHGlobal); - - /* second guess (only if there are bands left where avoid hole is inactive)*/ - if (nActiveLinesNoAHGlobal > 0) { - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - /* - redVal += ( 2 ^ ( (constPartNoAHGlobal-desiredPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) - - 2 ^ ( (constPartNoAHGlobal-redPeNoAHGlobal) / (invRedExp*nActiveLinesNoAHGlobal) ) ) - */ - int scale0 = 0; - int scale1 = 0; - - FIXP_DBL tmp0 = CalcRedValPower( constPartNoAHGlobal-desiredPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale0 ); - FIXP_DBL tmp1 = CalcRedValPower( constPartNoAHGlobal-redPeNoAHGlobal, 4*nActiveLinesNoAHGlobal, &scale1 ); - - int scalMin = FDKmin(scale0, scale1)-1; - - tmp0 = scaleValue(tmp0,(scalMin-scale0)) - scaleValue(tmp1,(scalMin-scale1)); - scale0 = scalMin; - - /* old reduction value */ - tmp1 = redValue[elementId]; - scale1 = redValScaling[elementId]; - - scalMin = fixMin(scale0,scale1)-1; - - /* sum up old and new reduction value */ - redValue[elementId] = scaleValue(tmp0,(scalMin-scale0)) + scaleValue(tmp1,(scalMin-scale1)); - redValScaling[elementId] = scalMin; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } /* nActiveLinesNoAHGlobal > 0 */ - } - else { - /* desiredPe >= redPeGlobal */ - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - INT redVal_scale = 0; - FIXP_DBL tmp = fDivNorm((FIXP_DBL)redPeGlobal, (FIXP_DBL)desiredPe, &redVal_scale); - - /* redVal *= redPeGlobal/desiredPe; */ - redValue[elementId] = fMult(redValue[elementId], tmp); - redValScaling[elementId] -= redVal_scale; - - FDKaacEnc_resetAHFlags(pAhFlag[elementId], cm->elInfo[elementId].nChannelsInEl, psyOutElement[elementId]->psyOutChannel); - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } - - redPeGlobal = 0; - /* Calculate new redVal's PE... */ - for (elementId = elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsCBR(qcElement[elementId]->qcOutChannel, psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], pThrExp[elementId], nChannels, redValue[elementId], redValScaling[elementId]); - - /* pe after second guess */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - redPeGlobal += peData->pe; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - - iter++; - } /* EOF while */ - - - /* ------------------------------------------------------- */ - /* Part IV: if still required, further reduce constraints */ - /* ------------------------------------------------------- */ - /* 1.0* 1.15* 1.20* - * desiredPe desiredPe desiredPe - * | | | - * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| | - * | | |XXXXXXXXXXX... - * | |XXXXXXXXXXX| - * --- A --- | --- B --- | --- C --- - * - * (X): redPeGlobal - * (A): FDKaacEnc_correctThresh() - * (B): FDKaacEnc_allowMoreHoles() - * (C): FDKaacEnc_reduceMinSnr() + redPeGlobal = 0; + /* Calculate new redVal's PE... */ + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsCBR( + qcElement[elementId]->qcOutChannel, + psyOutElement[elementId]->psyOutChannel, pAhFlag[elementId], + pThrExp[elementId], nChannels, reductionValue_m, reductionValue_e); + + /* pe after second guess */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); + redPeGlobal += peData->pe; + + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + + iter++; + } /* EOF while */ + + /* ------------------------------------------------------- */ + /* Part IV: if still required, further reduce constraints */ + /* ------------------------------------------------------- */ + /* 1.0* 1.15* 1.20* + * desiredPe desiredPe desiredPe + * | | | + * ...XXXXXXXXXXXXXXXXXXXXXXXXXXX| | + * | | |XXXXXXXXXXX... + * | |XXXXXXXXXXX| + * --- A --- | --- B --- | --- C --- + * + * (X): redPeGlobal + * (A): FDKaacEnc_correctThresh() + * (B): FDKaacEnc_allowMoreHoles() + * (C): FDKaacEnc_reduceMinSnr() */ - /* correct thresholds to get closer to the desired pe */ - if ( redPeGlobal > desiredPe ) { - FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp, redValue, redValScaling, - desiredPe - redPeGlobal, processElements, elementOffset); - - /* update PE */ - redPeGlobal = 0; - for(elementId=elementOffset;elementId<nElements;elementId++) { - if (cm->elInfo[elementId].elType != ID_DSE) { - - INT nChannels = cm->elInfo[elementId].nChannelsInEl; - PE_DATA *peData = &qcElement[elementId]->peData; - - /* pe after correctThresh */ - FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, qcElement[elementId]->qcOutChannel, peData, nChannels); - redPeGlobal += peData->pe; - - } /* EOF DSE-suppression */ - } /* EOF for all elements... */ - } - - if ( redPeGlobal > desiredPe ) { - /* reduce pe by reducing minSnr requirements */ - FDKaacEnc_reduceMinSnr(cm, qcElement, psyOutElement, pAhFlag, - (fMultI(FL2FXCONST_DBL(0.15f),desiredPe) + desiredPe), - &redPeGlobal, processElements, elementOffset); - - /* reduce pe by allowing additional spectral holes */ - FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement, pAhFlag, - desiredPe, redPeGlobal, processElements, elementOffset); - } + /* correct thresholds to get closer to the desired pe */ + if (redPeGlobal > desiredPe) { + FDKaacEnc_correctThresh(cm, qcElement, psyOutElement, pAhFlag, pThrExp, + reductionValue_m, reductionValue_e, + desiredPe - redPeGlobal, processElements, + elementOffset); + + /* update PE */ + redPeGlobal = 0; + for (elementId = elementOffset; elementId < nElements; elementId++) { + if (cm->elInfo[elementId].elType != ID_DSE) { + INT nChannels = cm->elInfo[elementId].nChannelsInEl; + PE_DATA *peData = &qcElement[elementId]->peData; + + /* pe after correctThresh */ + FDKaacEnc_calcPe(psyOutElement[elementId]->psyOutChannel, + qcElement[elementId]->qcOutChannel, peData, nChannels); + redPeGlobal += peData->pe; + + } /* EOF DSE-suppression */ + } /* EOF for all elements... */ + } + if (redPeGlobal > desiredPe) { + /* reduce pe by reducing minSnr requirements */ + FDKaacEnc_reduceMinSnr( + cm, qcElement, psyOutElement, pAhFlag, + (fMultI(FL2FXCONST_DBL(0.15f), desiredPe) + desiredPe), &redPeGlobal, + processElements, elementOffset); + + /* reduce pe by allowing additional spectral holes */ + FDKaacEnc_allowMoreHoles(cm, qcElement, psyOutElement, AdjThrStateElement, + pAhFlag, desiredPe, redPeGlobal, processElements, + elementOffset); + } } /* similar to FDKaacEnc_adaptThresholdsToPe(), for VBR-mode */ -void FDKaacEnc_AdaptThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], - PSY_OUT_CHANNEL* psyOutChannel[(2)], - ATS_ELEMENT* AdjThrStateElement, - struct TOOLSINFO *toolsInfo, - PE_DATA *peData, - const INT nChannels) -{ - UCHAR (*pAhFlag)[MAX_GROUPED_SFB]; - FIXP_DBL (*pThrExp)[MAX_GROUPED_SFB]; - - /* allocate scratch memory */ - C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) - C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) - pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag; - pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp; - - /* thresholds to the power of redExp */ - FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels); - - /* lower the minSnr requirements for low energies compared to the average - energy in this frame */ - FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel, &AdjThrStateElement->minSnrAdaptParam, nChannels); - - /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ - FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo, - nChannels, peData, &AdjThrStateElement->ahParam); - - /* reduce thresholds */ - FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp, nChannels, - AdjThrStateElement->vbrQualFactor, - &AdjThrStateElement->chaosMeasureOld); - - /* free scratch memory */ - C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2)*MAX_GROUPED_SFB) - C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2)*MAX_GROUPED_SFB) +static void FDKaacEnc_AdaptThresholdsVBR( + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + ATS_ELEMENT *const AdjThrStateElement, + const struct TOOLSINFO *const toolsInfo, const INT nChannels) { + UCHAR(*pAhFlag)[MAX_GROUPED_SFB]; + FIXP_DBL(*pThrExp)[MAX_GROUPED_SFB]; + + /* allocate scratch memory */ + C_ALLOC_SCRATCH_START(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB) + C_ALLOC_SCRATCH_START(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB) + pAhFlag = (UCHAR(*)[MAX_GROUPED_SFB])_pAhFlag; + pThrExp = (FIXP_DBL(*)[MAX_GROUPED_SFB])_pThrExp; + + /* thresholds to the power of redExp */ + FDKaacEnc_calcThreshExp(pThrExp, qcOutChannel, psyOutChannel, nChannels); + + /* lower the minSnr requirements for low energies compared to the average + energy in this frame */ + FDKaacEnc_adaptMinSnr(qcOutChannel, psyOutChannel, + &AdjThrStateElement->minSnrAdaptParam, nChannels); + + /* init ahFlag (0: no ah necessary, 1: ah possible, 2: ah active */ + FDKaacEnc_initAvoidHoleFlag(qcOutChannel, psyOutChannel, pAhFlag, toolsInfo, + nChannels, &AdjThrStateElement->ahParam); + + /* reduce thresholds */ + FDKaacEnc_reduceThresholdsVBR(qcOutChannel, psyOutChannel, pAhFlag, pThrExp, + nChannels, AdjThrStateElement->vbrQualFactor, + &AdjThrStateElement->chaosMeasureOld); + + /* free scratch memory */ + C_ALLOC_SCRATCH_END(_pThrExp, FIXP_DBL, (2) * MAX_GROUPED_SFB) + C_ALLOC_SCRATCH_END(_pAhFlag, UCHAR, (2) * MAX_GROUPED_SFB) } - /***************************************************************************** functionname: FDKaacEnc_calcBitSave @@ -1978,20 +2226,19 @@ void FDKaacEnc_AdaptThresholdsVBR(QC_OUT_CHANNEL* qcOutChannel[(2)], clipHigh maxBitres */ static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel, - const FIXP_DBL clipLow, - const FIXP_DBL clipHigh, - const FIXP_DBL minBitSave, - const FIXP_DBL maxBitSave, - const FIXP_DBL bitsave_slope) -{ - FIXP_DBL bitsave; + const FIXP_DBL clipLow, + const FIXP_DBL clipHigh, + const FIXP_DBL minBitSave, + const FIXP_DBL maxBitSave, + const FIXP_DBL bitsave_slope) { + FIXP_DBL bitsave; - fillLevel = fixMax(fillLevel, clipLow); - fillLevel = fixMin(fillLevel, clipHigh); + fillLevel = fixMax(fillLevel, clipLow); + fillLevel = fixMin(fillLevel, clipHigh); - bitsave = maxBitSave - fMult((fillLevel-clipLow), bitsave_slope); + bitsave = maxBitSave - fMult((fillLevel - clipLow), bitsave_slope); - return (bitsave); + return (bitsave); } /***************************************************************************** @@ -2017,23 +2264,21 @@ static FIXP_DBL FDKaacEnc_calcBitSave(FIXP_DBL fillLevel, clipLow */ static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel, - const FIXP_DBL clipLow, - const FIXP_DBL clipHigh, - const FIXP_DBL minBitSpend, - const FIXP_DBL maxBitSpend, - const FIXP_DBL bitspend_slope) -{ - FIXP_DBL bitspend; + const FIXP_DBL clipLow, + const FIXP_DBL clipHigh, + const FIXP_DBL minBitSpend, + const FIXP_DBL maxBitSpend, + const FIXP_DBL bitspend_slope) { + FIXP_DBL bitspend; - fillLevel = fixMax(fillLevel, clipLow); - fillLevel = fixMin(fillLevel, clipHigh); + fillLevel = fixMax(fillLevel, clipLow); + fillLevel = fixMin(fillLevel, clipHigh); - bitspend = minBitSpend + fMult(fillLevel-clipLow, bitspend_slope); + bitspend = minBitSpend + fMult(fillLevel - clipLow, bitspend_slope); - return (bitspend); + return (bitspend); } - /***************************************************************************** functionname: FDKaacEnc_adjustPeMinMax() @@ -2043,52 +2288,46 @@ static FIXP_DBL FDKaacEnc_calcBitSpend(FIXP_DBL fillLevel, output: adjusted peMin/peMax *****************************************************************************/ -static void FDKaacEnc_adjustPeMinMax(const INT currPe, - INT *peMin, - INT *peMax) -{ - FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL, minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f); - INT diff; - - INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe); - - if (currPe > *peMax) - { - diff = (currPe-*peMax) ; - *peMin += fMultI(minFacHi,diff); - *peMax += fMultI(maxFacHi,diff); - } - else if (currPe < *peMin) - { - diff = (*peMin-currPe) ; - *peMin -= fMultI(minFacLo,diff); - *peMax -= fMultI(maxFacLo,diff); - } - else - { - *peMin += fMultI(minFacHi, (currPe - *peMin)); - *peMax -= fMultI(maxFacLo, (*peMax - currPe)); - } +static void FDKaacEnc_adjustPeMinMax(const INT currPe, INT *peMin, INT *peMax) { + FIXP_DBL minFacHi = FL2FXCONST_DBL(0.3f), maxFacHi = (FIXP_DBL)MAXVAL_DBL, + minFacLo = FL2FXCONST_DBL(0.14f), maxFacLo = FL2FXCONST_DBL(0.07f); + INT diff; + + INT minDiff_fix = fMultI(FL2FXCONST_DBL(0.1666666667f), currPe); + + if (currPe > *peMax) { + diff = (currPe - *peMax); + *peMin += fMultI(minFacHi, diff); + *peMax += fMultI(maxFacHi, diff); + } else if (currPe < *peMin) { + diff = (*peMin - currPe); + *peMin -= fMultI(minFacLo, diff); + *peMax -= fMultI(maxFacLo, diff); + } else { + *peMin += fMultI(minFacHi, (currPe - *peMin)); + *peMax -= fMultI(maxFacLo, (*peMax - currPe)); + } - if ((*peMax - *peMin) < minDiff_fix) - { - INT peMax_fix = *peMax, peMin_fix = *peMin; - FIXP_DBL partLo_fix, partHi_fix; + if ((*peMax - *peMin) < minDiff_fix) { + INT peMax_fix = *peMax, peMin_fix = *peMin; + FIXP_DBL partLo_fix, partHi_fix; - partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix); - partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe); + partLo_fix = (FIXP_DBL)fixMax(0, currPe - peMin_fix); + partHi_fix = (FIXP_DBL)fixMax(0, peMax_fix - currPe); - peMax_fix = (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix+partHi_fix)), minDiff_fix)); - peMin_fix = (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix+partHi_fix)), minDiff_fix)); - peMin_fix = fixMax(0, peMin_fix); + peMax_fix = + (INT)(currPe + fMultI(fDivNorm(partHi_fix, (partLo_fix + partHi_fix)), + minDiff_fix)); + peMin_fix = + (INT)(currPe - fMultI(fDivNorm(partLo_fix, (partLo_fix + partHi_fix)), + minDiff_fix)); + peMin_fix = fixMax(0, peMin_fix); - *peMax = peMax_fix; - *peMin = peMin_fix; - } + *peMax = peMax_fix; + *peMin = peMin_fix; + } } - - /***************************************************************************** functionname: BitresCalcBitFac @@ -2115,206 +2354,223 @@ static void FDKaacEnc_adjustPeMinMax(const INT currPe, pemin */ -static FIXP_DBL FDKaacEnc_bitresCalcBitFac(const INT bitresBits, - const INT maxBitresBits, - const INT pe, - const INT lastWindowSequence, - const INT avgBits, - const FIXP_DBL maxBitFac, - ADJ_THR_STATE *AdjThr, - ATS_ELEMENT *adjThrChan) -{ - BRES_PARAM *bresParam; - INT pex; +void FDKaacEnc_bitresCalcBitFac(const INT bitresBits, const INT maxBitresBits, + const INT pe, const INT lastWindowSequence, + const INT avgBits, const FIXP_DBL maxBitFac, + const ADJ_THR_STATE *const AdjThr, + ATS_ELEMENT *const adjThrChan, + FIXP_DBL *const pBitresFac, + INT *const pBitresFac_e) { + const BRES_PARAM *bresParam; + INT pex; + FIXP_DBL fillLevel; + INT fillLevel_e = 0; + + FIXP_DBL bitresFac; + INT bitresFac_e; + + FIXP_DBL bitSave, bitSpend; + FIXP_DBL bitsave_slope, bitspend_slope; + FIXP_DBL fillLevel_fix = MAXVAL_DBL; + + FIXP_DBL slope = MAXVAL_DBL; + + if (lastWindowSequence != SHORT_WINDOW) { + bresParam = &(AdjThr->bresParamLong); + bitsave_slope = FL2FXCONST_DBL(0.466666666); + bitspend_slope = FL2FXCONST_DBL(0.666666666); + } else { + bresParam = &(AdjThr->bresParamShort); + bitsave_slope = (FIXP_DBL)0x2E8BA2E9; + bitspend_slope = (FIXP_DBL)0x7fffffff; + } + + // fillLevel = (float)(bitresBits+avgBits) / (float)(maxBitresBits + avgBits); + if (bitresBits < maxBitresBits) { + fillLevel_fix = fDivNorm(bitresBits, maxBitresBits); + } - INT qmin, qbr, qbres, qmbr; - FIXP_DBL bitSave, bitSpend; + pex = fMax(pe, adjThrChan->peMin); + pex = fMin(pex, adjThrChan->peMax); - FIXP_DBL bitresFac_fix, tmp_cst, tmp_fix; - FIXP_DBL pe_pers, bits_ratio, maxBrVal; - FIXP_DBL bitsave_slope, bitspend_slope, maxBitFac_tmp; - FIXP_DBL fillLevel_fix = (FIXP_DBL)0x7fffffff; - FIXP_DBL UNITY = (FIXP_DBL)0x7fffffff; - FIXP_DBL POINT7 = (FIXP_DBL)0x5999999A; + bitSave = FDKaacEnc_calcBitSave( + fillLevel_fix, bresParam->clipSaveLow, bresParam->clipSaveHigh, + bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope); - if (maxBitresBits > bitresBits) { - fillLevel_fix = fDivNorm(bitresBits, maxBitresBits); - } + bitSpend = FDKaacEnc_calcBitSpend( + fillLevel_fix, bresParam->clipSpendLow, bresParam->clipSpendHigh, + bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); - if (lastWindowSequence != SHORT_WINDOW) - { - bresParam = &(AdjThr->bresParamLong); - bitsave_slope = (FIXP_DBL)0x3BBBBBBC; - bitspend_slope = (FIXP_DBL)0x55555555; - } - else - { - bresParam = &(AdjThr->bresParamShort); - bitsave_slope = (FIXP_DBL)0x2E8BA2E9; - bitspend_slope = (FIXP_DBL)0x7fffffff; - } + slope = schur_div((pex - adjThrChan->peMin), + (adjThrChan->peMax - adjThrChan->peMin), 31); - pex = fixMax(pe, adjThrChan->peMin); - pex = fixMin(pex, adjThrChan->peMax); - - bitSave = FDKaacEnc_calcBitSave(fillLevel_fix, - bresParam->clipSaveLow, bresParam->clipSaveHigh, - bresParam->minBitSave, bresParam->maxBitSave, bitsave_slope); - - bitSpend = FDKaacEnc_calcBitSpend(fillLevel_fix, - bresParam->clipSpendLow, bresParam->clipSpendHigh, - bresParam->minBitSpend, bresParam->maxBitSpend, bitspend_slope); - - pe_pers = (pex > adjThrChan->peMin) ? fDivNorm(pex - adjThrChan->peMin, adjThrChan->peMax - adjThrChan->peMin) : 0; - tmp_fix = fMult(((FIXP_DBL)bitSpend + (FIXP_DBL)bitSave), pe_pers); - bitresFac_fix = (UNITY>>1) - ((FIXP_DBL)bitSave>>1) + (tmp_fix>>1); qbres = (DFRACT_BITS-2); - - /* (float)bitresBits/(float)avgBits */ - bits_ratio = fDivNorm(bitresBits, avgBits, &qbr); - qbr = DFRACT_BITS-1-qbr; - - /* Add 0.7 in q31 to bits_ratio in qbr */ - /* 0.7f + (float)bitresBits/(float)avgBits */ - qmin = fixMin(qbr, (DFRACT_BITS-1)); - bits_ratio = bits_ratio >> (qbr - qmin); - tmp_cst = POINT7 >> ((DFRACT_BITS-1) - qmin); - maxBrVal = (bits_ratio>>1) + (tmp_cst>>1); qmbr = qmin - 1; - - /* bitresFac_fix = fixMin(bitresFac_fix, 0.7 + bitresBits/avgBits); */ - bitresFac_fix = bitresFac_fix >> (qbres - qmbr); qbres = qmbr; - bitresFac_fix = fixMin(bitresFac_fix, maxBrVal); - - /* Compare with maxBitFac */ - qmin = fixMin(Q_BITFAC, qbres); - bitresFac_fix = bitresFac_fix >> (qbres - qmin); - maxBitFac_tmp = maxBitFac >> (Q_BITFAC - qmin); - if(maxBitFac_tmp < bitresFac_fix) - { - bitresFac_fix = maxBitFac; - } - else - { - if(qmin < Q_BITFAC) - { - bitresFac_fix = bitresFac_fix << (Q_BITFAC-qmin); - } - else - { - bitresFac_fix = bitresFac_fix >> (qmin-Q_BITFAC); - } - } + /* scale down by 1 bit because the result of the following addition can be + * bigger than 1 (though smaller than 2) */ + bitresFac = ((FIXP_DBL)(MAXVAL_DBL >> 1) - (bitSave >> 1)); + bitresFac_e = 1; /* exp=1 */ + bitresFac = fMultAddDiv2(bitresFac, slope, bitSpend + bitSave); /* exp=1 */ - FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax); + /*** limit bitresFac for small bitreservoir ***/ + fillLevel = fDivNorm(bitresBits, avgBits, &fillLevel_e); + if (fillLevel_e < 0) { + fillLevel = scaleValue(fillLevel, fillLevel_e); + fillLevel_e = 0; + } + /* shift down value by 1 because of summation, ... */ + fillLevel >>= 1; + fillLevel_e += 1; + /* ..., this summation: */ + fillLevel += scaleValue(FL2FXCONST_DBL(0.7f), -fillLevel_e); + /* set bitresfactor to same exponent as fillLevel */ + if (scaleValue(bitresFac, -fillLevel_e + 1) > fillLevel) { + bitresFac = fillLevel; + bitresFac_e = fillLevel_e; + } - return bitresFac_fix; -} + /* limit bitresFac for high bitrates */ + if (scaleValue(bitresFac, bitresFac_e - (DFRACT_BITS - 1 - 24)) > maxBitFac) { + bitresFac = maxBitFac; + bitresFac_e = (DFRACT_BITS - 1 - 24); + } + FDKaacEnc_adjustPeMinMax(pe, &adjThrChan->peMin, &adjThrChan->peMax); + + /* output values */ + *pBitresFac = bitresFac; + *pBitresFac_e = bitresFac_e; +} /***************************************************************************** functionname: FDKaacEnc_AdjThrNew description: allocate ADJ_THR_STATE *****************************************************************************/ -INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE** phAdjThr, - INT nElements) -{ - INT err = 0; - INT i; - ADJ_THR_STATE* hAdjThr = GetRam_aacEnc_AdjustThreshold(); - if (hAdjThr==NULL) { - err = 1; - goto bail; - } +INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements) { + INT err = 0; + INT i; + ADJ_THR_STATE *hAdjThr = GetRam_aacEnc_AdjustThreshold(); + if (hAdjThr == NULL) { + err = 1; + goto bail; + } - for (i=0; i<nElements; i++) { - hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i); - if (hAdjThr->adjThrStateElem[i]==NULL) { - err = 1; - goto bail; - } + for (i = 0; i < nElements; i++) { + hAdjThr->adjThrStateElem[i] = GetRam_aacEnc_AdjThrStateElement(i); + if (hAdjThr->adjThrStateElem[i] == NULL) { + err = 1; + goto bail; } + } bail: - *phAdjThr = hAdjThr; - return err; + *phAdjThr = hAdjThr; + return err; } - /***************************************************************************** functionname: FDKaacEnc_AdjThrInit description: initialize ADJ_THR_STATE *****************************************************************************/ void FDKaacEnc_AdjThrInit( - ADJ_THR_STATE *hAdjThr, - const INT meanPe, - ELEMENT_BITS *elBits[(8)], - INT invQuant, - INT nElements, - INT nChannelsEff, - INT sampleRate, - INT advancedBitsToPe, - FIXP_DBL vbrQualFactor, - const INT dZoneQuantEnable - ) -{ + ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant, + const CHANNEL_MAPPING *const channelMapping, const INT sampleRate, + const INT totalBitrate, const INT isLowDelay, + const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable, + const INT bitDistributionMode, const FIXP_DBL vbrQualFactor) { INT i; FIXP_DBL POINT8 = FL2FXCONST_DBL(0.8f); FIXP_DBL POINT6 = FL2FXCONST_DBL(0.6f); - /* Max number of iterations in second guess is 3 for lowdelay aot and for configurations with - multiple audio elements in general, otherwise iteration value is always 1. */ - hAdjThr->maxIter2ndGuess = (advancedBitsToPe!=0 || nElements>1) ? 3 : 1; + if (bitDistributionMode == 1) { + hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTRA_ELEMENT; + } else { + hAdjThr->bitDistributionMode = AACENC_BD_MODE_INTER_ELEMENT; + } + + /* Max number of iterations in second guess is 3 for lowdelay aot and for + configurations with multiple audio elements in general, otherwise iteration + value is always 1. */ + hAdjThr->maxIter2ndGuess = + (isLowDelay != 0 || channelMapping->nElements > 1) ? 3 : 1; /* common for all elements: */ /* parameters for bitres control */ - hAdjThr->bresParamLong.clipSaveLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamLong.clipSaveHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ - hAdjThr->bresParamLong.minBitSave = (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */ - hAdjThr->bresParamLong.maxBitSave = (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */ - hAdjThr->bresParamLong.clipSpendLow = (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamLong.clipSpendHigh = (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ - hAdjThr->bresParamLong.minBitSpend = (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */ - hAdjThr->bresParamLong.maxBitSpend = (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */ - - hAdjThr->bresParamShort.clipSaveLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSaveHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ - hAdjThr->bresParamShort.minBitSave = (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */ - hAdjThr->bresParamShort.maxBitSave = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSpendLow = (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ - hAdjThr->bresParamShort.clipSpendHigh = (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ - hAdjThr->bresParamShort.minBitSpend = (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */ - hAdjThr->bresParamShort.maxBitSpend = (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */ + hAdjThr->bresParamLong.clipSaveLow = + (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamLong.clipSaveHigh = + (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ + hAdjThr->bresParamLong.minBitSave = + (FIXP_DBL)0xf999999a; /* FL2FXCONST_DBL(-0.05f); */ + hAdjThr->bresParamLong.maxBitSave = + (FIXP_DBL)0x26666666; /* FL2FXCONST_DBL(0.3f); */ + hAdjThr->bresParamLong.clipSpendLow = + (FIXP_DBL)0x1999999a; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamLong.clipSpendHigh = + (FIXP_DBL)0x7999999a; /* FL2FXCONST_DBL(0.95f); */ + hAdjThr->bresParamLong.minBitSpend = + (FIXP_DBL)0xf3333333; /* FL2FXCONST_DBL(-0.10f); */ + hAdjThr->bresParamLong.maxBitSpend = + (FIXP_DBL)0x33333333; /* FL2FXCONST_DBL(0.4f); */ + + hAdjThr->bresParamShort.clipSaveLow = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSaveHigh = + (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ + hAdjThr->bresParamShort.minBitSave = + (FIXP_DBL)0x00000000; /* FL2FXCONST_DBL(0.0f); */ + hAdjThr->bresParamShort.maxBitSave = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSpendLow = + (FIXP_DBL)0x199999a0; /* FL2FXCONST_DBL(0.2f); */ + hAdjThr->bresParamShort.clipSpendHigh = + (FIXP_DBL)0x5fffffff; /* FL2FXCONST_DBL(0.75f); */ + hAdjThr->bresParamShort.minBitSpend = + (FIXP_DBL)0xf9999998; /* FL2FXCONST_DBL(-0.05f); */ + hAdjThr->bresParamShort.maxBitSpend = + (FIXP_DBL)0x40000000; /* FL2FXCONST_DBL(0.5f); */ /* specific for each element: */ - for (i=0; i<nElements; i++) { - ATS_ELEMENT* atsElem = hAdjThr->adjThrStateElem[i]; + for (i = 0; i < channelMapping->nElements; i++) { + const FIXP_DBL relativeBits = channelMapping->elInfo[i].relativeBits; + const INT nChannelsInElement = channelMapping->elInfo[i].nChannelsInEl; + const INT bitrateInElement = + (relativeBits != (FIXP_DBL)MAXVAL_DBL) + ? (INT)fMultNorm(relativeBits, (FIXP_DBL)totalBitrate) + : totalBitrate; + const INT chBitrate = bitrateInElement >> (nChannelsInElement == 1 ? 0 : 1); + + ATS_ELEMENT *atsElem = hAdjThr->adjThrStateElem[i]; MINSNR_ADAPT_PARAM *msaParam = &atsElem->minSnrAdaptParam; - INT chBitrate = elBits[i]->chBitrateEl; /* parameters for bitres control */ - atsElem->peMin = fMultI(POINT8, meanPe) >> 1; - atsElem->peMax = fMultI(POINT6, meanPe); + if (isLowDelay) { + atsElem->peMin = fMultI(POINT8, meanPe); + atsElem->peMax = fMultI(POINT6, meanPe) << 1; + } else { + atsElem->peMin = fMultI(POINT8, meanPe) >> 1; + atsElem->peMax = fMultI(POINT6, meanPe); + } /* for use in FDKaacEnc_reduceThresholdsVBR */ atsElem->chaosMeasureOld = FL2FXCONST_DBL(0.3f); /* additional pe offset to correct pe2bits for low bitrates */ + /* ---- no longer necessary, set by table ----- */ atsElem->peOffset = 0; /* vbr initialisation */ atsElem->vbrQualFactor = vbrQualFactor; - if (chBitrate < 32000) - { - atsElem->peOffset = fixMax(50, 100-fMultI((FIXP_DBL)0x666667, chBitrate)); + if (chBitrate < 32000) { + atsElem->peOffset = + fixMax(50, 100 - fMultI((FIXP_DBL)0x666667, chBitrate)); } /* avoid hole parameters */ - if (chBitrate > 20000) { + if (chBitrate >= 20000) { atsElem->ahParam.modifyMinSnr = TRUE; atsElem->ahParam.startSfbL = 15; atsElem->ahParam.startSfbS = 3; - } - else { + } else { atsElem->ahParam.modifyMinSnr = FALSE; atsElem->ahParam.startSfbL = 0; atsElem->ahParam.startSfbS = 0; @@ -2327,9 +2583,11 @@ void FDKaacEnc_AdjThrInit( /* maximum minSnr reduction to minSnr^maxRed is reached for avgEn/sfbEn >= maxRatio */ /* msaParam->maxRatio = 1000.0f; */ - /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) / ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/ + /*msaParam->redRatioFac = ((float)1.0f - msaParam->maxRed) / + * ((float)10.0f*log10(msaParam->startRatio/msaParam->maxRatio)/log10(2.0f)*(float)0.3010299956f);*/ msaParam->redRatioFac = FL2FXCONST_DBL(-0.375f); /* -0.0375f * 10.0f */ - /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/ + /*msaParam->redOffs = (float)1.0f - msaParam->redRatioFac * (float)10.0f * + * log10(msaParam->startRatio)/log10(2.0f) * (float)0.3010299956f;*/ msaParam->redOffs = FL2FXCONST_DBL(0.021484375); /* 1.375f/64.0f */ /* init pe correction */ @@ -2343,324 +2601,324 @@ void FDKaacEnc_AdjThrInit( /* init bits2PeFactor */ FDKaacEnc_InitBits2PeFactor( - &atsElem->bits2PeFactor_m, - &atsElem->bits2PeFactor_e, - chBitrate*nChannelsEff, /* overall bitrate */ - nChannelsEff, /* number of channels */ - sampleRate, - advancedBitsToPe, - dZoneQuantEnable, - invQuant - ); + &atsElem->bits2PeFactor_m, &atsElem->bits2PeFactor_e, bitrateInElement, + nChannelsInElement, sampleRate, isLowDelay, dZoneQuantEnable, invQuant); } /* for nElements */ - } - /***************************************************************************** functionname: FDKaacEnc_FDKaacEnc_calcPeCorrection description: calc desired pe *****************************************************************************/ static void FDKaacEnc_FDKaacEnc_calcPeCorrection( - FIXP_DBL *const correctionFac_m, - INT *const correctionFac_e, - const INT peAct, - const INT peLast, - const INT bitsLast, - const FIXP_DBL bits2PeFactor_m, - const INT bits2PeFactor_e - ) -{ - if ( (bitsLast > 0) && (peAct < 1.5f*peLast) && (peAct > 0.7f*peLast) && - (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(1.2f/2.f), bits2PeFactor_m), bits2PeFactor_e+1) > peLast) && - (FDKaacEnc_bits2pe2(bitsLast, fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m), bits2PeFactor_e ) < peLast) ) - { + FIXP_DBL *const correctionFac_m, INT *const correctionFac_e, + const INT peAct, const INT peLast, const INT bitsLast, + const FIXP_DBL bits2PeFactor_m, const INT bits2PeFactor_e) { + if ((bitsLast > 0) && (peAct < 1.5f * peLast) && (peAct > 0.7f * peLast) && + (FDKaacEnc_bits2pe2(bitsLast, + fMult(FL2FXCONST_DBL(1.2f / 2.f), bits2PeFactor_m), + bits2PeFactor_e + 1) > peLast) && + (FDKaacEnc_bits2pe2(bitsLast, + fMult(FL2FXCONST_DBL(0.65f), bits2PeFactor_m), + bits2PeFactor_e) < peLast)) { FIXP_DBL corrFac = *correctionFac_m; int scaling = 0; - FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e); + FIXP_DBL denum = (FIXP_DBL)FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, + bits2PeFactor_e); FIXP_DBL newFac = fDivNorm((FIXP_DBL)peLast, denum, &scaling); /* dead zone, newFac and corrFac are scaled by 0.5 */ if ((FIXP_DBL)peLast <= denum) { /* ratio <= 1.f */ - newFac = fixMax(scaleValue(fixMin( fMult(FL2FXCONST_DBL(1.1f/2.f), newFac), scaleValue(FL2FXCONST_DBL( 1.f/2.f), -scaling)), scaling), FL2FXCONST_DBL(0.85f/2.f) ); - } - else { /* ratio < 1.f */ - newFac = fixMax( fixMin( scaleValue(fMult(FL2FXCONST_DBL(0.9f/2.f), newFac), scaling), FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL( 1.f/2.f) ); + newFac = fixMax( + scaleValue(fixMin(fMult(FL2FXCONST_DBL(1.1f / 2.f), newFac), + scaleValue(FL2FXCONST_DBL(1.f / 2.f), -scaling)), + scaling), + FL2FXCONST_DBL(0.85f / 2.f)); + } else { /* ratio < 1.f */ + newFac = fixMax( + fixMin(scaleValue(fMult(FL2FXCONST_DBL(0.9f / 2.f), newFac), scaling), + FL2FXCONST_DBL(1.15f / 2.f)), + FL2FXCONST_DBL(1.f / 2.f)); } - if ( ((newFac > FL2FXCONST_DBL(1.f/2.f)) && (corrFac < FL2FXCONST_DBL(1.f/2.f))) - || ((newFac < FL2FXCONST_DBL(1.f/2.f)) && (corrFac > FL2FXCONST_DBL(1.f/2.f)))) - { - corrFac = FL2FXCONST_DBL(1.f/2.f); + if (((newFac > FL2FXCONST_DBL(1.f / 2.f)) && + (corrFac < FL2FXCONST_DBL(1.f / 2.f))) || + ((newFac < FL2FXCONST_DBL(1.f / 2.f)) && + (corrFac > FL2FXCONST_DBL(1.f / 2.f)))) { + corrFac = FL2FXCONST_DBL(1.f / 2.f); } /* faster adaptation towards 1.0, slower in the other direction */ - if ( (corrFac < FL2FXCONST_DBL(1.f/2.f) && newFac < corrFac) - || (corrFac > FL2FXCONST_DBL(1.f/2.f) && newFac > corrFac) ) - { - corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) + fMult(FL2FXCONST_DBL(0.15f), newFac); - } - else { - corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) + fMult(FL2FXCONST_DBL(0.3f), newFac); + if ((corrFac < FL2FXCONST_DBL(1.f / 2.f) && newFac < corrFac) || + (corrFac > FL2FXCONST_DBL(1.f / 2.f) && newFac > corrFac)) { + corrFac = fMult(FL2FXCONST_DBL(0.85f), corrFac) + + fMult(FL2FXCONST_DBL(0.15f), newFac); + } else { + corrFac = fMult(FL2FXCONST_DBL(0.7f), corrFac) + + fMult(FL2FXCONST_DBL(0.3f), newFac); } - corrFac = fixMax( fixMin( corrFac, FL2FXCONST_DBL(1.15f/2.f) ), FL2FXCONST_DBL(0.85/2.f) ); + corrFac = fixMax(fixMin(corrFac, FL2FXCONST_DBL(1.15f / 2.f)), + FL2FXCONST_DBL(0.85 / 2.f)); *correctionFac_m = corrFac; *correctionFac_e = 1; - } - else { - *correctionFac_m = FL2FXCONST_DBL(1.f/2.f); + } else { + *correctionFac_m = FL2FXCONST_DBL(1.f / 2.f); *correctionFac_e = 1; } } - static void FDKaacEnc_calcPeCorrectionLowBitRes( - FIXP_DBL *const correctionFac_m, - INT *const correctionFac_e, - const INT peLast, - const INT bitsLast, - const INT bitresLevel, - const INT nChannels, - const FIXP_DBL bits2PeFactor_m, - const INT bits2PeFactor_e - ) -{ + FIXP_DBL *const correctionFac_m, INT *const correctionFac_e, + const INT peLast, const INT bitsLast, const INT bitresLevel, + const INT nChannels, const FIXP_DBL bits2PeFactor_m, + const INT bits2PeFactor_e) { /* tuning params */ - const FIXP_DBL amp = FL2FXCONST_DBL(0.005); + const FIXP_DBL amp = FL2FXCONST_DBL(0.005); const FIXP_DBL maxDiff = FL2FXCONST_DBL(0.25f); if (bitsLast > 0) { - - /* Estimate deviation of granted and used dynamic bits in previous frame, in PE units */ - const int bitsBalLast = peLast - FDKaacEnc_bits2pe2( - bitsLast, - bits2PeFactor_m, - bits2PeFactor_e); + /* Estimate deviation of granted and used dynamic bits in previous frame, in + * PE units */ + const int bitsBalLast = + peLast - FDKaacEnc_bits2pe2(bitsLast, bits2PeFactor_m, bits2PeFactor_e); /* reserve n bits per channel */ - int headroom = (bitresLevel>=50*nChannels) ? 0 : (100*nChannels); + int headroom = (bitresLevel >= 50 * nChannels) ? 0 : (100 * nChannels); /* in PE units */ - headroom = FDKaacEnc_bits2pe2( - headroom, - bits2PeFactor_m, - bits2PeFactor_e); + headroom = FDKaacEnc_bits2pe2(headroom, bits2PeFactor_m, bits2PeFactor_e); /* * diff = amp * ((bitsBalLast - headroom) / (bitresLevel + headroom) * diff = max ( min ( diff, maxDiff, -maxDiff)) / 2 */ - FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2(bitresLevel, bits2PeFactor_m, bits2PeFactor_e) + (FIXP_DBL)headroom; + FIXP_DBL denominator = (FIXP_DBL)FDKaacEnc_bits2pe2( + bitresLevel, bits2PeFactor_m, bits2PeFactor_e) + + (FIXP_DBL)headroom; int scaling = 0; - FIXP_DBL diff = (bitsBalLast>=headroom) - ? fMult(amp, fDivNorm( (FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) - : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom), denominator, &scaling)) ; + FIXP_DBL diff = + (bitsBalLast >= headroom) + ? fMult(amp, fDivNorm((FIXP_DBL)(bitsBalLast - headroom), + denominator, &scaling)) + : -fMult(amp, fDivNorm(-(FIXP_DBL)(bitsBalLast - headroom), + denominator, &scaling)); scaling -= 1; /* divide by 2 */ - diff = (scaling<=0) ? FDKmax( FDKmin (diff>>(-scaling), maxDiff>>1), -maxDiff>>1) - : FDKmax( FDKmin (diff, maxDiff>>(1+scaling)), -maxDiff>>(1+scaling)) << scaling; + diff = (scaling <= 0) + ? fMax(fMin(diff >> (-scaling), maxDiff >> 1), -maxDiff >> 1) + : fMax(fMin(diff, maxDiff >> (1 + scaling)), + -maxDiff >> (1 + scaling)) + << scaling; /* * corrFac += diff * corrFac = max ( min ( corrFac/2.f, 1.f/2.f, 0.75f/2.f ) ) */ - *correctionFac_m = FDKmax(FDKmin((*correctionFac_m)+diff, FL2FXCONST_DBL(1.0f/2.f)), FL2FXCONST_DBL(0.75f/2.f)) ; + *correctionFac_m = + fMax(fMin((*correctionFac_m) + diff, FL2FXCONST_DBL(1.0f / 2.f)), + FL2FXCONST_DBL(0.75f / 2.f)); *correctionFac_e = 1; - } - else { - *correctionFac_m = FL2FXCONST_DBL(0.75/2.f); + } else { + *correctionFac_m = FL2FXCONST_DBL(0.75 / 2.f); *correctionFac_e = 1; } } -void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, - ATS_ELEMENT *AdjThrStateElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - PE_DATA *peData, - INT *grantedPe, - INT *grantedPeCorr, - const INT nChannels, - const INT commonWindow, - const INT grantedDynBits, - const INT bitresBits, - const INT maxBitresBits, - const FIXP_DBL maxBitFac, - const INT bitDistributionMode) -{ +void FDKaacEnc_DistributeBits( + ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe, + INT *grantedPeCorr, const INT nChannels, const INT commonWindow, + const INT grantedDynBits, const INT bitresBits, const INT maxBitresBits, + const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode) { FIXP_DBL bitFactor; + INT bitFactor_e; INT noRedPe = peData->pe; /* prefer short windows for calculation of bitFactor */ INT curWindowSequence = LONG_WINDOW; - if (nChannels==2) { + if (nChannels == 2) { if ((psyOutChannel[0]->lastWindowSequence == SHORT_WINDOW) || (psyOutChannel[1]->lastWindowSequence == SHORT_WINDOW)) { - curWindowSequence = SHORT_WINDOW; + curWindowSequence = SHORT_WINDOW; } - } - else { + } else { curWindowSequence = psyOutChannel[0]->lastWindowSequence; } if (grantedDynBits >= 1) { - if (bitDistributionMode!=0) { - *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, AdjThrStateElement->bits2PeFactor_m, AdjThrStateElement->bits2PeFactor_e); - } - else - { - /* factor dependend on current fill level and pe */ - bitFactor = FDKaacEnc_bitresCalcBitFac(bitresBits, maxBitresBits, noRedPe, - curWindowSequence, grantedDynBits, maxBitFac, - adjThrState, - AdjThrStateElement - ); - - /* desired pe for actual frame */ - /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */ - *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, - fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m), AdjThrStateElement->bits2PeFactor_e+(DFRACT_BITS-1-Q_BITFAC) - ); + if (bitResMode != AACENC_BR_MODE_FULL) { + /* small or disabled bitreservoir */ + *grantedPe = FDKaacEnc_bits2pe2(grantedDynBits, + AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + } else { + /* factor dependend on current fill level and pe */ + FDKaacEnc_bitresCalcBitFac( + bitresBits, maxBitresBits, noRedPe, curWindowSequence, grantedDynBits, + maxBitFac, adjThrState, AdjThrStateElement, &bitFactor, &bitFactor_e); + + /* desired pe for actual frame */ + /* Worst case max of grantedDynBits is = 1024 * 5.27 * 2 */ + *grantedPe = FDKaacEnc_bits2pe2( + grantedDynBits, fMult(bitFactor, AdjThrStateElement->bits2PeFactor_m), + AdjThrStateElement->bits2PeFactor_e + bitFactor_e); } - } - else { + } else { *grantedPe = 0; /* prevent divsion by 0 */ } /* correction of pe value */ - switch (bitDistributionMode) { - case 2: - case 1: - FDKaacEnc_calcPeCorrectionLowBitRes( - &AdjThrStateElement->peCorrectionFactor_m, - &AdjThrStateElement->peCorrectionFactor_e, - AdjThrStateElement->peLast, - AdjThrStateElement->dynBitsLast, - bitresBits, - nChannels, - AdjThrStateElement->bits2PeFactor_m, - AdjThrStateElement->bits2PeFactor_e - ); - break; - case 0: - default: + switch (bitResMode) { + case AACENC_BR_MODE_DISABLED: + case AACENC_BR_MODE_REDUCED: + /* correction of pe value for low bitres */ + FDKaacEnc_calcPeCorrectionLowBitRes( + &AdjThrStateElement->peCorrectionFactor_m, + &AdjThrStateElement->peCorrectionFactor_e, AdjThrStateElement->peLast, + AdjThrStateElement->dynBitsLast, bitresBits, nChannels, + AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + break; + case AACENC_BR_MODE_FULL: + default: + /* correction of pe value for high bitres */ FDKaacEnc_FDKaacEnc_calcPeCorrection( - &AdjThrStateElement->peCorrectionFactor_m, - &AdjThrStateElement->peCorrectionFactor_e, - fixMin(*grantedPe, noRedPe), - AdjThrStateElement->peLast, - AdjThrStateElement->dynBitsLast, - AdjThrStateElement->bits2PeFactor_m, - AdjThrStateElement->bits2PeFactor_e - ); - break; + &AdjThrStateElement->peCorrectionFactor_m, + &AdjThrStateElement->peCorrectionFactor_e, + fixMin(*grantedPe, noRedPe), AdjThrStateElement->peLast, + AdjThrStateElement->dynBitsLast, AdjThrStateElement->bits2PeFactor_m, + AdjThrStateElement->bits2PeFactor_e); + break; } - *grantedPeCorr = (INT)(fMult((FIXP_DBL)(*grantedPe<<Q_AVGBITS), AdjThrStateElement->peCorrectionFactor_m) >> (Q_AVGBITS-AdjThrStateElement->peCorrectionFactor_e)); + *grantedPeCorr = + (INT)(fMult((FIXP_DBL)(*grantedPe << Q_AVGBITS), + AdjThrStateElement->peCorrectionFactor_m) >> + (Q_AVGBITS - AdjThrStateElement->peCorrectionFactor_e)); /* update last pe */ AdjThrStateElement->peLast = *grantedPe; AdjThrStateElement->dynBitsLast = -1; - } /***************************************************************************** functionname: FDKaacEnc_AdjustThresholds description: adjust thresholds *****************************************************************************/ -void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - QC_OUT* qcOut, - PSY_OUT_ELEMENT* psyOutElement[(8)], - INT CBRbitrateMode, - INT maxIter2ndGuess, - CHANNEL_MAPPING* cm) -{ - int i; - if (CBRbitrateMode) - { - /* In case, no bits must be shifted between different elements, */ - /* an element-wise execution of the pe-dependent threshold- */ - /* adaption becomes necessary... */ - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging */ - //if (totalGrantedPeCorr < totalNoRedPe) { - if (qcElement[i]->grantedPe < qcElement[i]->peData.pe) - { - /* calc threshold necessary for desired pe */ - FDKaacEnc_adaptThresholdsToPe(cm, - AdjThrStateElement, - qcElement, - psyOutElement, - qcElement[i]->grantedPeCorr, - maxIter2ndGuess, - 1, /* Process only 1 element */ - i); /* Process exactly THIS element */ - - } - - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - } - else { - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for VBR-mode */ - FDKaacEnc_AdaptThresholdsVBR(qcElement[i]->qcOutChannel, - psyOutElement[i]->psyOutChannel, - AdjThrStateElement[i], - &psyOutElement[i]->toolsInfo, - &qcElement[i]->peData, - cm->elInfo[i].nChannelsInEl); - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - } - for (i=0; i<cm->nElements; i++) { - int ch,sfb,sfbGrp; - /* no weighting of threholds and energies for mlout */ - /* weight energies and thresholds */ - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { - QC_OUT_CHANNEL* pQcOutCh = qcElement[i]->qcOutChannel[ch]; - for (sfbGrp = 0;sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt; sfbGrp+=psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) { - for (sfb=0; sfb<psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup; sfb++) { - pQcOutCh->sfbThresholdLdData[sfb+sfbGrp] += pQcOutCh->sfbEnFacLd[sfb+sfbGrp]; - } +void FDKaacEnc_AdjustThresholds( + ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))], + QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm) { + int i; + + if (CBRbitrateMode) { + /* In case, no bits must be shifted between different elements, */ + /* an element-wise execution of the pe-dependent threshold- */ + /* adaption becomes necessary... */ + if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTRA_ELEMENT) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* qcElement[i]->grantedPe = 2000; */ /* Use this only for debugging + */ + // if (totalGrantedPeCorr < totalNoRedPe) { + if (qcElement[i]->grantedPeCorr < qcElement[i]->peData.pe) { + /* calc threshold necessary for desired pe */ + FDKaacEnc_adaptThresholdsToPe( + cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement, + qcElement[i]->grantedPeCorr, hAdjThr->maxIter2ndGuess, + 1, /* Process only 1 element */ + i /* Process exactly THIS element */ + ); + } + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + } /* -end- element loop */ + } /* AACENC_BD_MODE_INTRA_ELEMENT */ + else if (hAdjThr->bitDistributionMode == AACENC_BD_MODE_INTER_ELEMENT) { + /* Use global Pe to obtain the thresholds? */ + if (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) { + /* add equal loadness quantization noise to match the */ + /* desired pe calc threshold necessary for desired pe */ + /* Now carried out globally to cover all(!) channels. */ + FDKaacEnc_adaptThresholdsToPe(cm, hAdjThr->adjThrStateElem, qcElement, + psyOutElement, qcOut->totalGrantedPeCorr, + hAdjThr->maxIter2ndGuess, + cm->nElements, /* Process all elements */ + 0); /* Process exactly THIS element */ + } else { + /* In case global pe doesn't need to be reduced check each element to + hold estimated bitrate below maximum element bitrate. */ + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + /* Element pe applies to dynamic bits of maximum element bitrate. */ + const int maxElementPe = FDKaacEnc_bits2pe2( + (cm->elInfo[i].nChannelsInEl * MIN_BUFSIZE_PER_EFF_CHAN) - + qcElement[i]->staticBitsUsed - qcElement[i]->extBitsUsed, + hAdjThr->adjThrStateElem[i]->bits2PeFactor_m, + hAdjThr->adjThrStateElem[i]->bits2PeFactor_e); + + if (maxElementPe < qcElement[i]->peData.pe) { + FDKaacEnc_adaptThresholdsToPe( + cm, hAdjThr->adjThrStateElem, qcElement, psyOutElement, + maxElementPe, hAdjThr->maxIter2ndGuess, 1, i); } + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + } /* -end- element loop */ + } /* (qcOut->totalGrantedPeCorr < qcOut->totalNoRedPe) */ + } /* AACENC_BD_MODE_INTER_ELEMENT */ + } else { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for VBR-mode */ + FDKaacEnc_AdaptThresholdsVBR( + qcElement[i]->qcOutChannel, psyOutElement[i]->psyOutChannel, + hAdjThr->adjThrStateElem[i], &psyOutElement[i]->toolsInfo, + cm->elInfo[i].nChannelsInEl); + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + + } /* -end- element loop */ + } + for (i = 0; i < cm->nElements; i++) { + int ch, sfb, sfbGrp; + /* no weighting of threholds and energies for mlout */ + /* weight energies and thresholds */ + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + QC_OUT_CHANNEL *pQcOutCh = qcElement[i]->qcOutChannel[ch]; + for (sfbGrp = 0; sfbGrp < psyOutElement[i]->psyOutChannel[ch]->sfbCnt; + sfbGrp += psyOutElement[i]->psyOutChannel[ch]->sfbPerGroup) { + for (sfb = 0; sfb < psyOutElement[i]->psyOutChannel[ch]->maxSfbPerGroup; + sfb++) { + pQcOutCh->sfbThresholdLdData[sfb + sfbGrp] += + pQcOutCh->sfbEnFacLd[sfb + sfbGrp]; } + } } + } } -void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** phAdjThr) -{ - INT i; - ADJ_THR_STATE* hAdjThr = *phAdjThr; +void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **phAdjThr) { + INT i; + ADJ_THR_STATE *hAdjThr = *phAdjThr; - if (hAdjThr!=NULL) { - for (i=0; i<(8); i++) { - if (hAdjThr->adjThrStateElem[i]!=NULL) { - FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]); - } + if (hAdjThr != NULL) { + for (i = 0; i < ((8)); i++) { + if (hAdjThr->adjThrStateElem[i] != NULL) { + FreeRam_aacEnc_AdjThrStateElement(&hAdjThr->adjThrStateElem[i]); } - FreeRam_aacEnc_AdjustThreshold(phAdjThr); } + FreeRam_aacEnc_AdjustThreshold(phAdjThr); + } } - diff --git a/libAACenc/src/adj_thr.h b/libAACenc/src/adj_thr.h index be68c6e..1f5f998 100644 --- a/libAACenc/src/adj_thr.h +++ b/libAACenc/src/adj_thr.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,71 +90,77 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Threshold compensation + Author(s): M. Werner -******************************************************************************/ + Description: Threshold compensation -#ifndef __ADJ_THR_H -#define __ADJ_THR_H +*******************************************************************************/ +#ifndef ADJ_THR_H +#define ADJ_THR_H +#include "common_fix.h" #include "adj_thr_data.h" #include "qc_data.h" #include "line_pe.h" #include "interface.h" - -void FDKaacEnc_peCalculation( - PE_DATA *peData, - PSY_OUT_CHANNEL* psyOutChannel[(2)], - QC_OUT_CHANNEL* qcOutChannel[(2)], - struct TOOLSINFO *toolsInfo, - ATS_ELEMENT* adjThrStateElement, - const INT nChannels - ); - -INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE** phAdjThr, - INT nElements); - -void FDKaacEnc_AdjThrInit(ADJ_THR_STATE *hAdjThr, - const INT peMean, - ELEMENT_BITS* elBits[(8)], - INT invQuant, - INT nElements, - INT nChannelsEff, - INT sampleRate, - INT advancedBitsToPe, - FIXP_DBL vbrQualFactor, - const INT dZoneQuantEnable); - - -void FDKaacEnc_DistributeBits(ADJ_THR_STATE *adjThrState, - ATS_ELEMENT *AdjThrStateElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - PE_DATA *peData, - INT *grantedPe, - INT *grantedPeCorr, - const INT nChannels, - const INT commonWindow, - const INT avgBits, - const INT bitresBits, - const INT maxBitresBits, - const FIXP_DBL maxBitFac, - const INT bitDistributionMode); - -void FDKaacEnc_AdjustThresholds(ATS_ELEMENT* AdjThrStateElement[(8)], - QC_OUT_ELEMENT* qcElement[(8)], - QC_OUT* qcOut, - PSY_OUT_ELEMENT* psyOutElement[(8)], - INT CBRbitrateMode, - INT maxIter2ndGuess, - CHANNEL_MAPPING* cm); - -void FDKaacEnc_AdjThrClose(ADJ_THR_STATE** hAdjThr); +/***************************************************************************** + functionname: FDKaacEnc_peCalculation + description: +*****************************************************************************/ +void FDKaacEnc_peCalculation(PE_DATA *const peData, + const PSY_OUT_CHANNEL *const psyOutChannel[(2)], + QC_OUT_CHANNEL *const qcOutChannel[(2)], + const struct TOOLSINFO *const toolsInfo, + ATS_ELEMENT *const adjThrStateElement, + const INT nChannels); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrNew +description: allocate ADJ_THR_STATE +*****************************************************************************/ +INT FDKaacEnc_AdjThrNew(ADJ_THR_STATE **phAdjThr, INT nElements); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrInit +description: initialize ADJ_THR_STATE +*****************************************************************************/ +void FDKaacEnc_AdjThrInit( + ADJ_THR_STATE *const hAdjThr, const INT meanPe, const INT invQuant, + const CHANNEL_MAPPING *const channelMapping, const INT sampleRate, + const INT totalBitrate, const INT isLowDelay, + const AACENC_BITRES_MODE bitResMode, const INT dZoneQuantEnable, + const INT bitDistributionMode, const FIXP_DBL vbrQualFactor); + +/***************************************************************************** +functionname: FDKaacEnc_DistributeBits +description: +*****************************************************************************/ +void FDKaacEnc_DistributeBits( + ADJ_THR_STATE *adjThrState, ATS_ELEMENT *AdjThrStateElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], PE_DATA *peData, INT *grantedPe, + INT *grantedPeCorr, const INT nChannels, const INT commonWindow, + const INT avgBits, const INT bitresBits, const INT maxBitresBits, + const FIXP_DBL maxBitFac, const AACENC_BITRES_MODE bitResMode); + +/***************************************************************************** +functionname: FDKaacEnc_AdjustThresholds +description: adjust thresholds +*****************************************************************************/ +void FDKaacEnc_AdjustThresholds( + ADJ_THR_STATE *const hAdjThr, QC_OUT_ELEMENT *const qcElement[((8))], + QC_OUT *const qcOut, const PSY_OUT_ELEMENT *const psyOutElement[((8))], + const INT CBRbitrateMode, const CHANNEL_MAPPING *const cm); + +/***************************************************************************** +functionname: FDKaacEnc_AdjThrClose +description: +*****************************************************************************/ +void FDKaacEnc_AdjThrClose(ADJ_THR_STATE **hAdjThr); #endif diff --git a/libAACenc/src/adj_thr_data.h b/libAACenc/src/adj_thr_data.h index 7c3a191..4cd1299 100644 --- a/libAACenc/src/adj_thr_data.h +++ b/libAACenc/src/adj_thr_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,31 +90,42 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: M. Schug / A. Groeschel - contents/description: threshold calculations + Author(s): M. Schug / A. Groeschel -******************************************************************************/ + Description: threshold calculations -#ifndef __ADJ_THR_DATA_H -#define __ADJ_THR_DATA_H +*******************************************************************************/ +#ifndef ADJ_THR_DATA_H +#define ADJ_THR_DATA_H #include "psy_const.h" +typedef enum { + AACENC_BD_MODE_INTER_ELEMENT = 0, + AACENC_BD_MODE_INTRA_ELEMENT = 1 +} AACENC_BIT_DISTRIBUTION_MODE; + +typedef enum { + AACENC_BR_MODE_FULL = 0, + AACENC_BR_MODE_REDUCED = 1, + AACENC_BR_MODE_DISABLED = 2 +} AACENC_BITRES_MODE; + typedef struct { - FIXP_DBL clipSaveLow, clipSaveHigh; - FIXP_DBL minBitSave, maxBitSave; - FIXP_DBL clipSpendLow, clipSpendHigh; - FIXP_DBL minBitSpend, maxBitSpend; + FIXP_DBL clipSaveLow, clipSaveHigh; + FIXP_DBL minBitSave, maxBitSave; + FIXP_DBL clipSpendLow, clipSpendHigh; + FIXP_DBL minBitSpend, maxBitSpend; } BRES_PARAM; typedef struct { - INT modifyMinSnr; - INT startSfbL, startSfbS; + INT modifyMinSnr; + INT startSfbL, startSfbS; } AH_PARAM; typedef struct { @@ -118,19 +140,20 @@ typedef struct { /* parameters for bitreservoir control */ INT peMin, peMax; /* constant offset to pe */ - INT peOffset; + INT peOffset; /* constant PeFactor */ FIXP_DBL bits2PeFactor_m; - INT bits2PeFactor_e; + INT bits2PeFactor_e; /* avoid hole parameters */ AH_PARAM ahParam; - /* values for correction of pe */ - /* paramters for adaptation of minSnr */ + /* parameters for adaptation of minSnr */ MINSNR_ADAPT_PARAM minSnrAdaptParam; + + /* values for correction of pe */ INT peLast; INT dynBitsLast; FIXP_DBL peCorrectionFactor_m; - INT peCorrectionFactor_e; + INT peCorrectionFactor_e; /* vbr encoding */ FIXP_DBL vbrQualFactor; @@ -138,13 +161,14 @@ typedef struct { /* threshold weighting */ FIXP_DBL chaosMeasureEnFac[(2)]; - INT lastEnFacPatch[(2)]; + INT lastEnFacPatch[(2)]; } ATS_ELEMENT; typedef struct { BRES_PARAM bresParamLong, bresParamShort; - ATS_ELEMENT* adjThrStateElem[(8)]; + ATS_ELEMENT* adjThrStateElem[((8))]; + AACENC_BIT_DISTRIBUTION_MODE bitDistributionMode; INT maxIter2ndGuess; } ADJ_THR_STATE; diff --git a/libAACenc/src/band_nrg.cpp b/libAACenc/src/band_nrg.cpp index 861f7a8..fb22dbb 100644 --- a/libAACenc/src/band_nrg.cpp +++ b/libAACenc/src/band_nrg.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,17 +90,17 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Band/Line energy calculations + Author(s): M. Werner -******************************************************************************/ + Description: Band/Line energy calculations -#include "band_nrg.h" +*******************************************************************************/ +#include "band_nrg.h" /***************************************************************************** functionname: FDKaacEnc_CalcSfbMaxScaleSpec @@ -97,23 +108,26 @@ amm-info@iis.fraunhofer.de input: output: *****************************************************************************/ -void -FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, - const INT *RESTRICT bandOffset, - INT *RESTRICT sfbMaxScaleSpec, - const INT numBands) -{ - INT i,j; +void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, + const INT *RESTRICT bandOffset, + INT *RESTRICT sfbMaxScaleSpec, + const INT numBands) { + INT i, j; FIXP_DBL maxSpc, tmp; - for(i=0; i<numBands; i++) { + for (i = 0; i < numBands; i++) { maxSpc = (FIXP_DBL)0; - for (j=bandOffset[i]; j<bandOffset[i+1]; j++) { + + DWORD_ALIGNED(mdctSpectrum); + + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { tmp = fixp_abs(mdctSpectrum[j]); maxSpc = fixMax(maxSpc, tmp); } - sfbMaxScaleSpec[i] = (maxSpc==(FIXP_DBL)0) ? (DFRACT_BITS-2) : CntLeadingZeros(maxSpc)-1; - /* CountLeadingBits() is not necessary here since test value is always > 0 */ + j = CntLeadingZeros(maxSpc) - 1; + sfbMaxScaleSpec[i] = fixMin((DFRACT_BITS - 2), j); + /* CountLeadingBits() is not necessary here since test value is always > 0 + */ } } @@ -124,43 +138,45 @@ FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *RESTRICT mdctSpectrum, output: *****************************************************************************/ FIXP_DBL -FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy, - FIXP_DBL *RESTRICT bandEnergyLdData, - INT minSpecShift) -{ +FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum, + const INT *const RESTRICT sfbMaxScaleSpec, + const INT *const RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData, + const INT minSpecShift) { INT i, j, scale, nr = 0; FIXP_DBL maxNrgLd = FL2FXCONST_DBL(-1.0f); FIXP_DBL maxNrg = 0; FIXP_DBL spec; - for(i=0; i<numBands; i++) { - scale = fixMax(0, sfbMaxScaleSpec[i]-4); + for (i = 0; i < numBands; i++) { + scale = fixMax(0, sfbMaxScaleSpec[i] - 4); FIXP_DBL tmp = 0; - for (j=bandOffset[i]; j<bandOffset[i+1]; j++){ - spec = mdctSpectrum[j]<<scale; - tmp = fPow2AddDiv2(tmp, spec); + + DWORD_ALIGNED(mdctSpectrum); + + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + spec = mdctSpectrum[j] << scale; + tmp = fPow2AddDiv2(tmp, spec); } - bandEnergy[i] = tmp<<1; + bandEnergy[i] = tmp << 1; /* calculate ld of bandNrg, subtract scaling */ bandEnergyLdData[i] = CalcLdData(bandEnergy[i]); if (bandEnergyLdData[i] != FL2FXCONST_DBL(-1.0f)) { - bandEnergyLdData[i] -= scale*FL2FXCONST_DBL(2.0/64); + bandEnergyLdData[i] -= scale * FL2FXCONST_DBL(2.0 / 64); } /* find index of maxNrg */ if (bandEnergyLdData[i] > maxNrgLd) { - maxNrgLd = bandEnergyLdData[i]; - nr = i; + maxNrgLd = bandEnergyLdData[i]; + nr = i; } } /* return unscaled maxNrg*/ - scale = fixMax(0,sfbMaxScaleSpec[nr]-4); - scale = fixMax(2*(minSpecShift-scale),-(DFRACT_BITS-1)); + scale = fixMax(0, sfbMaxScaleSpec[nr] - 4); + scale = fixMax(2 * (minSpecShift - scale), -(DFRACT_BITS - 1)); maxNrg = scaleValue(bandEnergy[nr], scale); @@ -173,187 +189,173 @@ FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *RESTRICT mdctSpectrum, input: output: *****************************************************************************/ -INT -FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy, - FIXP_DBL *RESTRICT bandEnergyLdData) -{ +INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, + const INT *RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData) { INT i, j, shiftBits = 0; FIXP_DBL maxNrgLd = FL2FXCONST_DBL(0.0f); FIXP_DBL spec; - for(i=0; i<numBands; i++) { - INT leadingBits = sfbMaxScaleSpec[i]-4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */ - FIXP_DBL tmp = FL2FXCONST_DBL(0.0); - /* don't use scaleValue() here, it increases workload quite sufficiently... */ - if (leadingBits>=0) { - for (j=bandOffset[i];j<bandOffset[i+1];j++) { - spec = mdctSpectrum[j]<<leadingBits; - tmp = fPow2AddDiv2(tmp, spec); - } - } else { - INT shift = -leadingBits; - for (j=bandOffset[i];j<bandOffset[i+1];j++){ - spec = mdctSpectrum[j]>>shift; - tmp = fPow2AddDiv2(tmp, spec); - } - } - bandEnergy[i] = tmp<<1; + for (i = 0; i < numBands; i++) { + INT leadingBits = sfbMaxScaleSpec[i] - + 4; /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */ + FIXP_DBL tmp = FL2FXCONST_DBL(0.0); + /* don't use scaleValue() here, it increases workload quite sufficiently... + */ + if (leadingBits >= 0) { + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + spec = mdctSpectrum[j] << leadingBits; + tmp = fPow2AddDiv2(tmp, spec); + } + } else { + INT shift = -leadingBits; + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + spec = mdctSpectrum[j] >> shift; + tmp = fPow2AddDiv2(tmp, spec); + } + } + bandEnergy[i] = tmp << 1; } /* calculate ld of bandNrg, subtract scaling */ LdDataVector(bandEnergy, bandEnergyLdData, numBands); - for(i=numBands; i--!=0; ) { - FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i]-4)*FL2FXCONST_DBL(2.0/64); - - bandEnergyLdData[i] = (bandEnergyLdData[i] >= ((FL2FXCONST_DBL(-1.f)>>1) + (scaleDiff>>1))) - ? bandEnergyLdData[i]-scaleDiff : FL2FXCONST_DBL(-1.f); - /* find maxNrgLd */ - maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]); + for (i = numBands; i-- != 0;) { + FIXP_DBL scaleDiff = (sfbMaxScaleSpec[i] - 4) * FL2FXCONST_DBL(2.0 / 64); + + bandEnergyLdData[i] = (bandEnergyLdData[i] >= + ((FL2FXCONST_DBL(-1.f) >> 1) + (scaleDiff >> 1))) + ? bandEnergyLdData[i] - scaleDiff + : FL2FXCONST_DBL(-1.f); + /* find maxNrgLd */ + maxNrgLd = fixMax(maxNrgLd, bandEnergyLdData[i]); } - if (maxNrgLd<=(FIXP_DBL)0) - { - for(i=numBands; i--!=0; ) - { - INT scale = fixMin((sfbMaxScaleSpec[i]-4)<<1,(DFRACT_BITS-1)); - bandEnergy[i] = scaleValue(bandEnergy[i], -scale); - } - return 0; - } - else - { /* scale down NRGs */ - while (maxNrgLd>FL2FXCONST_DBL(0.0f)) - { - maxNrgLd -= FL2FXCONST_DBL(2.0/64); - shiftBits++; - } - for(i=numBands; i--!=0; ) - { - INT scale = fixMin( ((sfbMaxScaleSpec[i]-4)+shiftBits)<<1, (DFRACT_BITS-1)); - bandEnergyLdData[i] -= shiftBits*FL2FXCONST_DBL(2.0/64); - bandEnergy[i] = scaleValue(bandEnergy[i], -scale); - } - return shiftBits; + if (maxNrgLd <= (FIXP_DBL)0) { + for (i = numBands; i-- != 0;) { + INT scale = fixMin((sfbMaxScaleSpec[i] - 4) << 1, (DFRACT_BITS - 1)); + bandEnergy[i] = scaleValue(bandEnergy[i], -scale); + } + return 0; + } else { /* scale down NRGs */ + while (maxNrgLd > FL2FXCONST_DBL(0.0f)) { + maxNrgLd -= FL2FXCONST_DBL(2.0 / 64); + shiftBits++; + } + for (i = numBands; i-- != 0;) { + INT scale = fixMin(((sfbMaxScaleSpec[i] - 4) + shiftBits) << 1, + (DFRACT_BITS - 1)); + bandEnergyLdData[i] -= shiftBits * FL2FXCONST_DBL(2.0 / 64); + bandEnergy[i] = scaleValue(bandEnergy[i], -scale); + } + return shiftBits; } } - /***************************************************************************** functionname: FDKaacEnc_CalcBandEnergyOptimShort description: input: output: *****************************************************************************/ -void -FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergy) -{ +void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, + const INT *RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy) { INT i, j; - for(i=0; i<numBands; i++) - { - int leadingBits = sfbMaxScaleSpec[i]-3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ + for (i = 0; i < numBands; i++) { + int leadingBits = sfbMaxScaleSpec[i] - + 3; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ FIXP_DBL tmp = FL2FXCONST_DBL(0.0); - for (j=bandOffset[i];j<bandOffset[i+1];j++) - { - FIXP_DBL spec = scaleValue(mdctSpectrum[j],leadingBits); - tmp = fPow2AddDiv2(tmp, spec); + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + FIXP_DBL spec = scaleValue(mdctSpectrum[j], leadingBits); + tmp = fPow2AddDiv2(tmp, spec); } bandEnergy[i] = tmp; } - for(i=0; i<numBands; i++) - { - INT scale = (2*(sfbMaxScaleSpec[i]-3))-1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ - scale = fixMax(fixMin(scale,(DFRACT_BITS-1)),-(DFRACT_BITS-1)); - bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale); + for (i = 0; i < numBands; i++) { + INT scale = (2 * (sfbMaxScaleSpec[i] - 3)) - + 1; /* max sfbWidth = 36 ; 2^6=64 => 6/2 = 3 (spc*spc) */ + scale = fixMax(fixMin(scale, (DFRACT_BITS - 1)), -(DFRACT_BITS - 1)); + bandEnergy[i] = scaleValueSaturate(bandEnergy[i], -scale); } } - /***************************************************************************** functionname: FDKaacEnc_CalcBandNrgMSOpt description: input: output: *****************************************************************************/ -void FDKaacEnc_CalcBandNrgMSOpt(const FIXP_DBL *RESTRICT mdctSpectrumLeft, - const FIXP_DBL *RESTRICT mdctSpectrumRight, - INT *RESTRICT sfbMaxScaleSpecLeft, - INT *RESTRICT sfbMaxScaleSpecRight, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergyMid, - FIXP_DBL *RESTRICT bandEnergySide, - INT calcLdData, - FIXP_DBL *RESTRICT bandEnergyMidLdData, - FIXP_DBL *RESTRICT bandEnergySideLdData) -{ +void FDKaacEnc_CalcBandNrgMSOpt( + const FIXP_DBL *RESTRICT mdctSpectrumLeft, + const FIXP_DBL *RESTRICT mdctSpectrumRight, + INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight, + const INT *RESTRICT bandOffset, const INT numBands, + FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide, + INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData, + FIXP_DBL *RESTRICT bandEnergySideLdData) { INT i, j, minScale; FIXP_DBL NrgMid, NrgSide, specm, specs; - for (i=0; i<numBands; i++) { - + for (i = 0; i < numBands; i++) { NrgMid = NrgSide = FL2FXCONST_DBL(0.0); - minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i])-4; + minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]) - 4; minScale = fixMax(0, minScale); if (minScale > 0) { - for (j=bandOffset[i];j<bandOffset[i+1];j++) { - FIXP_DBL specL = mdctSpectrumLeft[j]<<(minScale-1); - FIXP_DBL specR = mdctSpectrumRight[j]<<(minScale-1); - specm = specL + specR; - specs = specL - specR; - NrgMid = fPow2AddDiv2(NrgMid, specm); - NrgSide = fPow2AddDiv2(NrgSide, specs); + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + FIXP_DBL specL = mdctSpectrumLeft[j] << (minScale - 1); + FIXP_DBL specR = mdctSpectrumRight[j] << (minScale - 1); + specm = specL + specR; + specs = specL - specR; + NrgMid = fPow2AddDiv2(NrgMid, specm); + NrgSide = fPow2AddDiv2(NrgSide, specs); } } else { - for (j=bandOffset[i];j<bandOffset[i+1];j++) { - FIXP_DBL specL = mdctSpectrumLeft[j]>>1; - FIXP_DBL specR = mdctSpectrumRight[j]>>1; - specm = specL + specR; - specs = specL - specR; - NrgMid = fPow2AddDiv2(NrgMid, specm); - NrgSide = fPow2AddDiv2(NrgSide, specs); + for (j = bandOffset[i]; j < bandOffset[i + 1]; j++) { + FIXP_DBL specL = mdctSpectrumLeft[j] >> 1; + FIXP_DBL specR = mdctSpectrumRight[j] >> 1; + specm = specL + specR; + specs = specL - specR; + NrgMid = fPow2AddDiv2(NrgMid, specm); + NrgSide = fPow2AddDiv2(NrgSide, specs); } } - bandEnergyMid[i] = NrgMid<<1; - bandEnergySide[i] = NrgSide<<1; + bandEnergyMid[i] = fMin(NrgMid, (FIXP_DBL)MAXVAL_DBL >> 1) << 1; + bandEnergySide[i] = fMin(NrgSide, (FIXP_DBL)MAXVAL_DBL >> 1) << 1; } - if(calcLdData) { + if (calcLdData) { LdDataVector(bandEnergyMid, bandEnergyMidLdData, numBands); LdDataVector(bandEnergySide, bandEnergySideLdData, numBands); } - for (i=0; i<numBands; i++) - { - INT minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]); - INT scale = fixMax(0, 2*(minScale-4)); + for (i = 0; i < numBands; i++) { + minScale = fixMin(sfbMaxScaleSpecLeft[i], sfbMaxScaleSpecRight[i]); + INT scale = fixMax(0, 2 * (minScale - 4)); - if (calcLdData) - { - /* using the minimal scaling of left and right channel can cause very small energies; - check ldNrg before subtract scaling multiplication: fract*INT we don't need fMult */ + if (calcLdData) { + /* using the minimal scaling of left and right channel can cause very + small energies; check ldNrg before subtract scaling multiplication: + fract*INT we don't need fMult */ - int minus = scale*FL2FXCONST_DBL(1.0/64); + int minus = scale * FL2FXCONST_DBL(1.0 / 64); - if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f)) - bandEnergyMidLdData[i] -= minus; + if (bandEnergyMidLdData[i] != FL2FXCONST_DBL(-1.0f)) + bandEnergyMidLdData[i] -= minus; - if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f)) - bandEnergySideLdData[i] -= minus; + if (bandEnergySideLdData[i] != FL2FXCONST_DBL(-1.0f)) + bandEnergySideLdData[i] -= minus; } - scale = fixMin(scale, (DFRACT_BITS-1)); - bandEnergyMid[i] >>= scale; + scale = fixMin(scale, (DFRACT_BITS - 1)); + bandEnergyMid[i] >>= scale; bandEnergySide[i] >>= scale; } } diff --git a/libAACenc/src/band_nrg.h b/libAACenc/src/band_nrg.h index 540a8ef..4137565 100644 --- a/libAACenc/src/band_nrg.h +++ b/libAACenc/src/band_nrg.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,71 +90,53 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner + Description: Band/Line energy calculation -******************************************************************************/ +*******************************************************************************/ -#ifndef _BAND_NRG_H -#define _BAND_NRG_H +#ifndef BAND_NRG_H +#define BAND_NRG_H #include "common_fix.h" - -void -FDKaacEnc_CalcSfbMaxScaleSpec( - const FIXP_DBL *mdctSpectrum, - const INT *bandOffset, - INT *sfbMaxScaleSpec, - const INT numBands - ); +void FDKaacEnc_CalcSfbMaxScaleSpec(const FIXP_DBL *mdctSpectrum, + const INT *bandOffset, INT *sfbMaxScaleSpec, + const INT numBands); FIXP_DBL -FDKaacEnc_CheckBandEnergyOptim( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy, - FIXP_DBL *bandEnergyLdData, - INT minSpecShift - ); - -INT -FDKaacEnc_CalcBandEnergyOptimLong( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy, - FIXP_DBL *bandEnergyLdData - ); - -void -FDKaacEnc_CalcBandEnergyOptimShort( - const FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - const INT *bandOffset, - const INT numBands, - FIXP_DBL *bandEnergy - ); - +FDKaacEnc_CheckBandEnergyOptim(const FIXP_DBL *const RESTRICT mdctSpectrum, + const INT *const RESTRICT sfbMaxScaleSpec, + const INT *const RESTRICT bandOffset, + const INT numBands, + FIXP_DBL *RESTRICT bandEnergy, + FIXP_DBL *RESTRICT bandEnergyLdData, + const INT minSpecShift); + +INT FDKaacEnc_CalcBandEnergyOptimLong(const FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, + const INT *bandOffset, const INT numBands, + FIXP_DBL *bandEnergy, + FIXP_DBL *bandEnergyLdData); + +void FDKaacEnc_CalcBandEnergyOptimShort(const FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, + const INT *bandOffset, + const INT numBands, + FIXP_DBL *bandEnergy); void FDKaacEnc_CalcBandNrgMSOpt( - const FIXP_DBL *RESTRICT mdctSpectrumLeft, - const FIXP_DBL *RESTRICT mdctSpectrumRight, - INT *RESTRICT sfbMaxScaleSpecLeft, - INT *RESTRICT sfbMaxScaleSpecRight, - const INT *RESTRICT bandOffset, - const INT numBands, - FIXP_DBL *RESTRICT bandEnergyMid, - FIXP_DBL *RESTRICT bandEnergySide, - INT calcLdData, - FIXP_DBL *RESTRICT bandEnergyMidLdData, - FIXP_DBL *RESTRICT bandEnergySideLdData); + const FIXP_DBL *RESTRICT mdctSpectrumLeft, + const FIXP_DBL *RESTRICT mdctSpectrumRight, + INT *RESTRICT sfbMaxScaleSpecLeft, INT *RESTRICT sfbMaxScaleSpecRight, + const INT *RESTRICT bandOffset, const INT numBands, + FIXP_DBL *RESTRICT bandEnergyMid, FIXP_DBL *RESTRICT bandEnergySide, + INT calcLdData, FIXP_DBL *RESTRICT bandEnergyMidLdData, + FIXP_DBL *RESTRICT bandEnergySideLdData); #endif diff --git a/libAACenc/src/bandwidth.cpp b/libAACenc/src/bandwidth.cpp index 6937362..36cd64d 100644 --- a/libAACenc/src/bandwidth.cpp +++ b/libAACenc/src/bandwidth.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,20 +90,21 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): M. Schug / A. Groeschel - Initial author: M. Schug / A. Groeschel - contents/description: bandwidth expert + Description: bandwidth expert -******************************************************************************/ +*******************************************************************************/ #include "channel_map.h" #include "bandwidth.h" #include "aacEnc_ram.h" -typedef struct{ +typedef struct { INT chanBitRate; INT bandWidthMono; INT bandWidth2AndMoreChan; @@ -100,114 +112,71 @@ typedef struct{ } BANDWIDTH_TAB; static const BANDWIDTH_TAB bandWidthTable[] = { - {0, 3700, 5000}, - {12000, 5000, 6400}, - {20000, 6900, 9640}, - {28000, 9600, 13050}, - {40000, 12060, 14260}, - {56000, 13950, 15500}, - {72000, 14200, 16120}, - {96000, 17000, 17000}, - {576001,17000, 17000} -}; - + {0, 3700, 5000}, {12000, 5000, 6400}, {20000, 6900, 9640}, + {28000, 9600, 13050}, {40000, 12060, 14260}, {56000, 13950, 15500}, + {72000, 14200, 16120}, {96000, 17000, 17000}, {576001, 17000, 17000}}; static const BANDWIDTH_TAB bandWidthTable_LD_22050[] = { - { 8000, 2000, 2400}, - {12000, 2500, 2700}, - {16000, 3300, 3100}, - {24000, 6250, 7200}, - {32000, 9200, 10500}, - {40000, 16000, 16000}, - {48000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2400}, {12000, 2500, 2700}, {16000, 3300, 3100}, + {24000, 6250, 7200}, {32000, 9200, 10500}, {40000, 16000, 16000}, + {48000, 16000, 16000}, {282241, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_24000[] = { - { 8000, 2000, 2000}, - {12000, 2000, 2300}, - {16000, 2200, 2500}, - {24000, 5650, 7200}, - {32000, 11600, 12000}, - {40000, 12000, 16000}, - {48000, 16000, 16000}, - {64000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {12000, 2000, 2300}, {16000, 2200, 2500}, + {24000, 5650, 7200}, {32000, 11600, 12000}, {40000, 12000, 16000}, + {48000, 16000, 16000}, {64000, 16000, 16000}, {307201, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_32000[] = { - { 8000, 2000, 2000}, - {12000, 2000, 2000}, - {24000, 4250, 7200}, - {32000, 8400, 9000}, - {40000, 9400, 11300}, - {48000, 11900, 14700}, - {64000, 14800, 16000}, - {76000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {12000, 2000, 2000}, {24000, 4250, 7200}, + {32000, 8400, 9000}, {40000, 9400, 11300}, {48000, 11900, 14700}, + {64000, 14800, 16000}, {76000, 16000, 16000}, {409601, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_44100[] = { - { 8000, 2000, 2000}, - {24000, 2000, 2000}, - {32000, 4400, 5700}, - {40000, 7400, 8800}, - {48000, 9000, 10700}, - {56000, 11000, 12900}, - {64000, 14400, 15500}, - {80000, 16000, 16200}, - {96000, 16500, 16000}, - {128000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700}, + {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12900}, + {64000, 14400, 15500}, {80000, 16000, 16200}, {96000, 16500, 16000}, + {128000, 16000, 16000}, {564481, 16000, 16000}}; static const BANDWIDTH_TAB bandWidthTable_LD_48000[] = { - { 8000, 2000, 2000}, - {24000, 2000, 2000}, - {32000, 4400, 5700}, - {40000, 7400, 8800}, - {48000, 9000, 10700}, - {56000, 11000, 12800}, - {64000, 14300, 15400}, - {80000, 16000, 16200}, - {96000, 16500, 16000}, - {128000, 16000, 16000}, - {360001, 16000, 16000} -}; + {8000, 2000, 2000}, {24000, 2000, 2000}, {32000, 4400, 5700}, + {40000, 7400, 8800}, {48000, 9000, 10700}, {56000, 11000, 12800}, + {64000, 14300, 15400}, {80000, 16000, 16200}, {96000, 16500, 16000}, + {128000, 16000, 16000}, {614401, 16000, 16000}}; -typedef struct{ +typedef struct { AACENC_BITRATE_MODE bitrateMode; int bandWidthMono; int bandWidth2AndMoreChan; } BANDWIDTH_TAB_VBR; -static const BANDWIDTH_TAB_VBR bandWidthTableVBR[]= { - {AACENC_BR_MODE_CBR, 0, 0}, - {AACENC_BR_MODE_VBR_1, 13050, 13050}, - {AACENC_BR_MODE_VBR_2, 13050, 13050}, - {AACENC_BR_MODE_VBR_3, 14260, 14260}, - {AACENC_BR_MODE_VBR_4, 15500, 15500}, - {AACENC_BR_MODE_VBR_5, 48000, 48000}, - {AACENC_BR_MODE_SFR, 0, 0}, - {AACENC_BR_MODE_FF, 0, 0} +static const BANDWIDTH_TAB_VBR bandWidthTableVBR[] = { + {AACENC_BR_MODE_CBR, 0, 0}, + {AACENC_BR_MODE_VBR_1, 13050, 13050}, + {AACENC_BR_MODE_VBR_2, 13050, 13050}, + {AACENC_BR_MODE_VBR_3, 14260, 14260}, + {AACENC_BR_MODE_VBR_4, 15500, 15500}, + {AACENC_BR_MODE_VBR_5, 48000, 48000}, + {AACENC_BR_MODE_SFR, 0, 0}, + {AACENC_BR_MODE_FF, 0, 0} }; -static INT GetBandwidthEntry( - const INT frameLength, - const INT sampleRate, - const INT chanBitRate, - const INT entryNo) -{ +static INT GetBandwidthEntry(const INT frameLength, const INT sampleRate, + const INT chanBitRate, const INT entryNo) { INT bandwidth = -1; const BANDWIDTH_TAB *pBwTab = NULL; INT bwTabSize = 0; switch (frameLength) { + case 960: case 1024: pBwTab = bandWidthTable; - bwTabSize = sizeof(bandWidthTable)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable) / sizeof(BANDWIDTH_TAB); break; + case 120: + case 128: + case 240: + case 256: case 480: case 512: switch (sampleRate) { @@ -217,26 +186,26 @@ static INT GetBandwidthEntry( case 16000: case 22050: pBwTab = bandWidthTable_LD_22050; - bwTabSize = sizeof(bandWidthTable_LD_22050)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_22050) / sizeof(BANDWIDTH_TAB); break; case 24000: pBwTab = bandWidthTable_LD_24000; - bwTabSize = sizeof(bandWidthTable_LD_24000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_24000) / sizeof(BANDWIDTH_TAB); break; case 32000: pBwTab = bandWidthTable_LD_32000; - bwTabSize = sizeof(bandWidthTable_LD_32000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_32000) / sizeof(BANDWIDTH_TAB); break; - case (44100): + case 44100: pBwTab = bandWidthTable_LD_44100; - bwTabSize = sizeof(bandWidthTable_LD_44100)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_44100) / sizeof(BANDWIDTH_TAB); break; case 48000: case 64000: case 88200: case 96000: pBwTab = bandWidthTable_LD_48000; - bwTabSize = sizeof(bandWidthTable_LD_48000)/sizeof(BANDWIDTH_TAB); + bwTabSize = sizeof(bandWidthTable_LD_48000) / sizeof(BANDWIDTH_TAB); break; } break; @@ -245,31 +214,38 @@ static INT GetBandwidthEntry( bwTabSize = 0; } - if (pBwTab!=NULL) { + if (pBwTab != NULL) { int i; - for (i=0; i<bwTabSize-1; i++) { + for (i = 0; i < bwTabSize - 1; i++) { if (chanBitRate >= pBwTab[i].chanBitRate && - chanBitRate < pBwTab[i+1].chanBitRate) - { + chanBitRate < pBwTab[i + 1].chanBitRate) { switch (frameLength) { + case 960: case 1024: - bandwidth = (entryNo==0) - ? pBwTab[i].bandWidthMono - : pBwTab[i].bandWidth2AndMoreChan; + bandwidth = (entryNo == 0) ? pBwTab[i].bandWidthMono + : pBwTab[i].bandWidth2AndMoreChan; break; + case 120: + case 128: + case 240: + case 256: case 480: - case 512: - { - INT q_res = 0; - INT startBw = (entryNo==0) ? pBwTab[i ].bandWidthMono : pBwTab[i ].bandWidth2AndMoreChan; - INT endBw = (entryNo==0) ? pBwTab[i+1].bandWidthMono : pBwTab[i+1].bandWidth2AndMoreChan; - INT startBr = pBwTab[i].chanBitRate; - INT endBr = pBwTab[i+1].chanBitRate; - - FIXP_DBL bwFac_fix = fDivNorm(chanBitRate-startBr, endBr-startBr, &q_res); - bandwidth = (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw-startBw)),q_res) + startBw; - } - break; + case 512: { + INT q_res = 0; + INT startBw = (entryNo == 0) ? pBwTab[i].bandWidthMono + : pBwTab[i].bandWidth2AndMoreChan; + INT endBw = (entryNo == 0) ? pBwTab[i + 1].bandWidthMono + : pBwTab[i + 1].bandWidth2AndMoreChan; + INT startBr = pBwTab[i].chanBitRate; + INT endBr = pBwTab[i + 1].chanBitRate; + + FIXP_DBL bwFac_fix = + fDivNorm(chanBitRate - startBr, endBr - startBr, &q_res); + bandwidth = + (INT)scaleValue(fMult(bwFac_fix, (FIXP_DBL)(endBw - startBw)), + q_res) + + startBw; + } break; default: bandwidth = -1; } @@ -281,99 +257,104 @@ static INT GetBandwidthEntry( return bandwidth; } - -AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(INT* bandWidth, - INT proposedBandWidth, - INT bitrate, - AACENC_BITRATE_MODE bitrateMode, - INT sampleRate, - INT frameLength, - CHANNEL_MAPPING* cm, - CHANNEL_MODE encoderMode) -{ +AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth( + const INT proposedBandWidth, const INT bitrate, + const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate, + const INT frameLength, const CHANNEL_MAPPING *const cm, + const CHANNEL_MODE encoderMode, INT *const bandWidth) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT chanBitRate = bitrate/cm->nChannels; - - /* vbr */ - switch(bitrateMode){ - case AACENC_BR_MODE_VBR_1: - case AACENC_BR_MODE_VBR_2: - case AACENC_BR_MODE_VBR_3: - case AACENC_BR_MODE_VBR_4: - case AACENC_BR_MODE_VBR_5: - if (proposedBandWidth != 0){ - /* use given bw */ - *bandWidth = proposedBandWidth; - } else { - /* take bw from table */ - switch(encoderMode){ - case MODE_1: - *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono; - break; - case MODE_2: - case MODE_1_2: - case MODE_1_2_1: - case MODE_1_2_2: - case MODE_1_2_2_1: - case MODE_1_2_2_2_1: - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan; - break; - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + INT chanBitRate = bitrate / cm->nChannelsEff; + + switch (bitrateMode) { + case AACENC_BR_MODE_VBR_1: + case AACENC_BR_MODE_VBR_2: + case AACENC_BR_MODE_VBR_3: + case AACENC_BR_MODE_VBR_4: + case AACENC_BR_MODE_VBR_5: + if (proposedBandWidth != 0) { + /* use given bw */ + *bandWidth = proposedBandWidth; + } else { + /* take bw from table */ + switch (encoderMode) { + case MODE_1: + *bandWidth = bandWidthTableVBR[bitrateMode].bandWidthMono; + break; + case MODE_2: + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + *bandWidth = bandWidthTableVBR[bitrateMode].bandWidth2AndMoreChan; + break; + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + } } - } - break; - case AACENC_BR_MODE_CBR: - case AACENC_BR_MODE_SFR: - case AACENC_BR_MODE_FF: - - /* bandwidth limiting */ - if (proposedBandWidth != 0) { - *bandWidth = FDKmin(proposedBandWidth, FDKmin(20000, sampleRate>>1)); - } - else { /* search reasonable bandwidth */ + break; + case AACENC_BR_MODE_CBR: + case AACENC_BR_MODE_SFR: + case AACENC_BR_MODE_FF: - int entryNo = 0; + /* bandwidth limiting */ + if (proposedBandWidth != 0) { + *bandWidth = fMin(proposedBandWidth, fMin(20000, sampleRate >> 1)); + } else { /* search reasonable bandwidth */ - switch(encoderMode){ - case MODE_1: /* mono */ - entryNo = 0; /* use mono bandwith settings */ - break; + int entryNo = 0; - case MODE_2: /* stereo */ - case MODE_1_2: /* sce + cpe */ - case MODE_1_2_1: /* sce + cpe + sce */ - case MODE_1_2_2: /* sce + cpe + cpe */ - case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ - case MODE_1_2_2_2_1: /* (7.1) sce + cpe + cpe + cpe + lfe */ - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - entryNo = 1; /* use stereo bandwith settings */ - break; + switch (encoderMode) { + case MODE_1: /* mono */ + entryNo = 0; /* use mono bandwidth settings */ + break; - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; - } + case MODE_2: /* stereo */ + case MODE_1_2: /* sce + cpe */ + case MODE_1_2_1: /* sce + cpe + sce */ + case MODE_1_2_2: /* sce + cpe + cpe */ + case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + entryNo = 1; /* use stereo bandwidth settings */ + break; - *bandWidth = GetBandwidthEntry( - frameLength, - sampleRate, - chanBitRate, - entryNo); + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + } - if (*bandWidth==-1) { - ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE; + *bandWidth = + GetBandwidthEntry(frameLength, sampleRate, chanBitRate, entryNo); + + if (*bandWidth == -1) { + switch (frameLength) { + case 120: + case 128: + case 240: + case 256: + *bandWidth = 16000; + break; + default: + ErrorStatus = AAC_ENC_INVALID_CHANNEL_BITRATE; + } + } } - } - break; - default: - *bandWidth = 0; - return AAC_ENC_UNSUPPORTED_BITRATE_MODE; + break; + default: + *bandWidth = 0; + return AAC_ENC_UNSUPPORTED_BITRATE_MODE; } - *bandWidth = FDKmin(*bandWidth, sampleRate/2); + *bandWidth = fMin(*bandWidth, sampleRate / 2); - return ErrorStatus;; + return ErrorStatus; } diff --git a/libAACenc/src/bandwidth.h b/libAACenc/src/bandwidth.h index 2e92453..088e829 100644 --- a/libAACenc/src/bandwidth.h +++ b/libAACenc/src/bandwidth.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,28 +90,25 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: M. Schug / A. Groeschel - contents/description: bandwidth expert + Author(s): M. Schug / A. Groeschel -******************************************************************************/ + Description: bandwidth expert -#ifndef _BANDWIDTH_H -#define _BANDWIDTH_H +*******************************************************************************/ +#ifndef BANDWIDTH_H +#define BANDWIDTH_H #include "qc_data.h" -AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth(INT* bandWidth, - INT proposedBandwidth, - INT bitrate, - AACENC_BITRATE_MODE bitrateMode, - INT sampleRate, - INT frameLength, - CHANNEL_MAPPING* cm, - CHANNEL_MODE encoderMode); +AAC_ENCODER_ERROR FDKaacEnc_DetermineBandWidth( + const INT proposedBandWidth, const INT bitrate, + const AACENC_BITRATE_MODE bitrateMode, const INT sampleRate, + const INT frameLength, const CHANNEL_MAPPING *const cm, + const CHANNEL_MODE encoderMode, INT *const bandWidth); #endif /* BANDWIDTH_H */ diff --git a/libAACenc/src/bit_cnt.cpp b/libAACenc/src/bit_cnt.cpp index 926ee49..579df8c 100644 --- a/libAACenc/src/bit_cnt.cpp +++ b/libAACenc/src/bit_cnt.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,20 +90,21 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Huffman Bitcounter & coder + Description: Huffman Bitcounter & coder -******************************************************************************/ +*******************************************************************************/ #include "bit_cnt.h" #include "aacEnc_ram.h" -#define HI_LTAB(a) (a>>16) +#define HI_LTAB(a) (a >> 16) #define LO_LTAB(a) (a & 0xffff) /***************************************************************************** @@ -106,72 +118,62 @@ amm-info@iis.fraunhofer.de *****************************************************************************/ -static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc1_2,bc3_4,bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1,t2,t3; - bc1_2=0; - bc3_4=0; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i<width;i+=4){ - - t0= values[i+0]; - t1= values[i+1]; - t2= values[i+2]; - t3= values[i+3]; - - /* 1,2 */ - - bc1_2+=FDKaacEnc_huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]; - - /* 5,6 */ - bc5_6+=FDKaacEnc_huff_ltab5_6[t0+4][t1+4]; - bc5_6+=FDKaacEnc_huff_ltab5_6[t2+4][t3+4]; - - t0=fixp_abs(t0); - t1=fixp_abs(t1); - t2=fixp_abs(t2); - t3=fixp_abs(t3); - - - bc3_4+= FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; - - bc7_8+=FDKaacEnc_huff_ltab7_8[t0][t1]; - bc7_8+=FDKaacEnc_huff_ltab7_8[t2][t3]; - - bc9_10+=FDKaacEnc_huff_ltab9_10[t0][t1]; - bc9_10+=FDKaacEnc_huff_ltab9_10[t2][t3]; - - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - bc11+= (INT) FDKaacEnc_huff_ltab11[t2][t3]; - - sc+=(t0>0)+(t1>0)+(t2>0)+(t3>0); + INT bc1_2, bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + bc1_2 = 0; + bc3_4 = 0; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc1_2 += (INT)FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]; + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - - bitCount[1]=HI_LTAB(bc1_2); - bitCount[2]=LO_LTAB(bc1_2); - bitCount[3]=HI_LTAB(bc3_4)+sc; - bitCount[4]=LO_LTAB(bc3_4)+sc; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = HI_LTAB(bc1_2); + bitCount[2] = LO_LTAB(bc1_2); + bitCount[3] = HI_LTAB(bc3_4) + sc; + bitCount[4] = LO_LTAB(bc3_4) + sc; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - /***************************************************************************** functionname: FDKaacEnc_count3_4_5_6_7_8_9_10_11 @@ -182,66 +184,62 @@ static void FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc3_4,bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1,t2,t3; - - bc3_4=0; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i<width;i+=4){ - - t0= values[i+0]; - t1= values[i+1]; - t2= values[i+2]; - t3= values[i+3]; - - bc5_6+=FDKaacEnc_huff_ltab5_6[t0+4][t1+4]; - bc5_6+=FDKaacEnc_huff_ltab5_6[t2+4][t3+4]; - - t0=fixp_abs(t0); - t1=fixp_abs(t1); - t2=fixp_abs(t2); - t3=fixp_abs(t3); - - bc3_4+= FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; - - bc7_8+=FDKaacEnc_huff_ltab7_8[t0][t1]; - bc7_8+=FDKaacEnc_huff_ltab7_8[t2][t3]; - - bc9_10+=FDKaacEnc_huff_ltab9_10[t0][t1]; - bc9_10+=FDKaacEnc_huff_ltab9_10[t2][t3]; - - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - bc11+= (INT) FDKaacEnc_huff_ltab11[t2][t3]; - - sc+=(t0>0)+(t1>0)+(t2>0)+(t3>0); + INT bc3_4, bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc3_4 = 0; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc3_4 += (INT)FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]; + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=HI_LTAB(bc3_4)+sc; - bitCount[4]=LO_LTAB(bc3_4)+sc; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = HI_LTAB(bc3_4) + sc; + bitCount[4] = LO_LTAB(bc3_4) + sc; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - - /***************************************************************************** functionname: FDKaacEnc_count5_6_7_8_9_10_11 @@ -252,52 +250,58 @@ static void FDKaacEnc_count3_4_5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ - -static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc5_6,bc7_8,bc9_10,bc11,sc; - INT t0,t1; - bc5_6=0; - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i<width;i+=2){ - - t0 = values[i+0]; - t1 = values[i+1]; - - bc5_6+=FDKaacEnc_huff_ltab5_6[t0+4][t1+4]; - - t0=fixp_abs(t0); - t1=fixp_abs(t1); - - bc7_8+=FDKaacEnc_huff_ltab7_8[t0][t1]; - bc9_10+=FDKaacEnc_huff_ltab9_10[t0][t1]; - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - - sc+=(t0>0)+(t1>0); + INT bc5_6, bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + bc5_6 = 0; + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + bc5_6 += (INT)FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4] + + (INT)FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=HI_LTAB(bc5_6); - bitCount[6]=LO_LTAB(bc5_6); - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = HI_LTAB(bc5_6); + bitCount[6] = LO_LTAB(bc5_6); + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } - /***************************************************************************** functionname: FDKaacEnc_count7_8_9_10_11 @@ -308,42 +312,54 @@ static void FDKaacEnc_count5_6_7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count7_8_9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count7_8_9_10_11(const SHORT *const values, + const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc7_8,bc9_10,bc11,sc; - INT t0,t1; - - bc7_8=0; - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i<width;i+=2){ - t0=fixp_abs(values[i+0]); - t1=fixp_abs(values[i+1]); - - bc7_8+=FDKaacEnc_huff_ltab7_8[t0][t1]; - bc9_10+=FDKaacEnc_huff_ltab9_10[t0][t1]; - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - sc+=(t0>0)+(t1>0); + INT bc7_8, bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc7_8 = 0; + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc7_8 += (INT)FDKaacEnc_huff_ltab7_8[t0][t1] + + (INT)FDKaacEnc_huff_ltab7_8[t2][t3]; + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=HI_LTAB(bc7_8)+sc; - bitCount[8]=LO_LTAB(bc7_8)+sc; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = HI_LTAB(bc7_8) + sc; + bitCount[8] = LO_LTAB(bc7_8) + sc; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -356,43 +372,50 @@ static void FDKaacEnc_count7_8_9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ - - -static void FDKaacEnc_count9_10_11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count9_10_11(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc9_10,bc11,sc; - INT t0,t1; - - bc9_10=0; - bc11=0; - sc=0; - - for(i=0;i<width;i+=2){ - t0=fixp_abs(values[i+0]); - t1=fixp_abs(values[i+1]); - - bc9_10+=FDKaacEnc_huff_ltab9_10[t0][t1]; - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - - sc+=(t0>0)+(t1>0); + INT bc9_10, bc11, sc; + INT t0, t1, t2, t3; + + bc9_10 = 0; + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc9_10 += (INT)FDKaacEnc_huff_ltab9_10[t0][t1] + + (INT)FDKaacEnc_huff_ltab9_10[t2][t3]; + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=INVALID_BITCOUNT; - bitCount[8]=INVALID_BITCOUNT; - bitCount[9]=HI_LTAB(bc9_10)+sc; - bitCount[10]=LO_LTAB(bc9_10)+sc; - bitCount[11]=bc11+sc; - + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = INVALID_BITCOUNT; + bitCount[8] = INVALID_BITCOUNT; + bitCount[9] = HI_LTAB(bc9_10) + sc; + bitCount[10] = LO_LTAB(bc9_10) + sc; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -405,35 +428,47 @@ static void FDKaacEnc_count9_10_11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_count11(const SHORT *RESTRICT values, - const INT width, - INT *bitCount) -{ - +static void FDKaacEnc_count11(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc11,sc; - INT t0,t1; - - bc11=0; - sc=0; - for(i=0;i<width;i+=2){ - t0=fixp_abs(values[i+0]); - t1=fixp_abs(values[i+1]); - bc11+= (INT) FDKaacEnc_huff_ltab11[t0][t1]; - sc+=(t0>0)+(t1>0); + INT bc11, sc; + INT t0, t1, t2, t3; + + bc11 = 0; + sc = 0; + + DWORD_ALIGNED(values); + + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + + t0 = fixp_abs(t0); + sc += (t0 > 0); + t1 = fixp_abs(t1); + sc += (t1 > 0); + t2 = fixp_abs(t2); + sc += (t2 > 0); + t3 = fixp_abs(t3); + sc += (t3 > 0); + + bc11 += + (INT)FDKaacEnc_huff_ltab11[t0][t1] + (INT)FDKaacEnc_huff_ltab11[t2][t3]; } - bitCount[1]=INVALID_BITCOUNT; - bitCount[2]=INVALID_BITCOUNT; - bitCount[3]=INVALID_BITCOUNT; - bitCount[4]=INVALID_BITCOUNT; - bitCount[5]=INVALID_BITCOUNT; - bitCount[6]=INVALID_BITCOUNT; - bitCount[7]=INVALID_BITCOUNT; - bitCount[8]=INVALID_BITCOUNT; - bitCount[9]=INVALID_BITCOUNT; - bitCount[10]=INVALID_BITCOUNT; - bitCount[11]=bc11+sc; + bitCount[1] = INVALID_BITCOUNT; + bitCount[2] = INVALID_BITCOUNT; + bitCount[3] = INVALID_BITCOUNT; + bitCount[4] = INVALID_BITCOUNT; + bitCount[5] = INVALID_BITCOUNT; + bitCount[6] = INVALID_BITCOUNT; + bitCount[7] = INVALID_BITCOUNT; + bitCount[8] = INVALID_BITCOUNT; + bitCount[9] = INVALID_BITCOUNT; + bitCount[10] = INVALID_BITCOUNT; + bitCount[11] = bc11 + sc; } /***************************************************************************** @@ -446,677 +481,470 @@ static void FDKaacEnc_count11(const SHORT *RESTRICT values, *****************************************************************************/ -static void FDKaacEnc_countEsc(const SHORT *RESTRICT values, - const INT width, - INT *RESTRICT bitCount) -{ - +static void FDKaacEnc_countEsc(const SHORT *const values, const INT width, + INT *RESTRICT bitCount) { INT i; - INT bc11,ec,sc; - INT t0,t1,t00,t01; - - bc11=0; - sc=0; - ec=0; - for(i=0;i<width;i+=2){ - t0=fixp_abs(values[i+0]); - t1=fixp_abs(values[i+1]); - - sc+=(t0>0)+(t1>0); - - t00 = fixMin(t0,16); - t01 = fixMin(t1,16); - bc11+= (INT) FDKaacEnc_huff_ltab11[t00][t01]; - - if(t0>=16){ - ec+=5; - while((t0>>=1) >= 16) - ec+=2; + INT bc11, ec, sc; + INT t0, t1, t00, t01; + + bc11 = 0; + sc = 0; + ec = 0; + for (i = 0; i < width; i += 2) { + t0 = fixp_abs(values[i + 0]); + t1 = fixp_abs(values[i + 1]); + + sc += (t0 > 0) + (t1 > 0); + + t00 = fixMin(t0, 16); + t01 = fixMin(t1, 16); + bc11 += (INT)FDKaacEnc_huff_ltab11[t00][t01]; + + if (t0 >= 16) { + ec += 5; + while ((t0 >>= 1) >= 16) ec += 2; } - if(t1>=16){ - ec+=5; - while((t1>>=1) >= 16) - ec+=2; + if (t1 >= 16) { + ec += 5; + while ((t1 >>= 1) >= 16) ec += 2; } } - for (i=0; i<11; i++) - bitCount[i]=INVALID_BITCOUNT; + for (i = 0; i < 11; i++) bitCount[i] = INVALID_BITCOUNT; - bitCount[11]=bc11+sc+ec; + bitCount[11] = bc11 + sc + ec; } - -typedef void (*COUNT_FUNCTION)(const SHORT *RESTRICT values, - const INT width, - INT *RESTRICT bitCount); - -static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV+1] = -{ - - FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */ - FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */ - FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */ - FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */ - FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */ - FDKaacEnc_count7_8_9_10_11, /* 5 */ - FDKaacEnc_count7_8_9_10_11, /* 6 */ - FDKaacEnc_count7_8_9_10_11, /* 7 */ - FDKaacEnc_count9_10_11, /* 8 */ - FDKaacEnc_count9_10_11, /* 9 */ - FDKaacEnc_count9_10_11, /* 10 */ - FDKaacEnc_count9_10_11, /* 11 */ - FDKaacEnc_count9_10_11, /* 12 */ - FDKaacEnc_count11, /* 13 */ - FDKaacEnc_count11, /* 14 */ - FDKaacEnc_count11, /* 15 */ - FDKaacEnc_countEsc /* 16 */ +typedef void (*COUNT_FUNCTION)(const SHORT *const values, const INT width, + INT *RESTRICT bitCount); + +static const COUNT_FUNCTION countFuncTable[CODE_BOOK_ESC_LAV + 1] = { + + FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 0 */ + FDKaacEnc_count1_2_3_4_5_6_7_8_9_10_11, /* 1 */ + FDKaacEnc_count3_4_5_6_7_8_9_10_11, /* 2 */ + FDKaacEnc_count5_6_7_8_9_10_11, /* 3 */ + FDKaacEnc_count5_6_7_8_9_10_11, /* 4 */ + FDKaacEnc_count7_8_9_10_11, /* 5 */ + FDKaacEnc_count7_8_9_10_11, /* 6 */ + FDKaacEnc_count7_8_9_10_11, /* 7 */ + FDKaacEnc_count9_10_11, /* 8 */ + FDKaacEnc_count9_10_11, /* 9 */ + FDKaacEnc_count9_10_11, /* 10 */ + FDKaacEnc_count9_10_11, /* 11 */ + FDKaacEnc_count9_10_11, /* 12 */ + FDKaacEnc_count11, /* 13 */ + FDKaacEnc_count11, /* 14 */ + FDKaacEnc_count11, /* 15 */ + FDKaacEnc_countEsc /* 16 */ }; - - -INT FDKaacEnc_bitCount(const SHORT *values, - const INT width, - INT maxVal, - INT *bitCount) -{ - +INT FDKaacEnc_bitCount(const SHORT *const values, const INT width, + const INT maxVal, INT *const RESTRICT bitCount) { /* check if we can use codebook 0 */ - if(maxVal == 0) - bitCount[0] = 0; - else - bitCount[0] = INVALID_BITCOUNT; - - maxVal = fixMin(maxVal,(INT)CODE_BOOK_ESC_LAV); - countFuncTable[maxVal](values,width,bitCount); - return(0); -} - + bitCount[0] = (maxVal == 0) ? 0 : INVALID_BITCOUNT; + countFuncTable[fixMin(maxVal, (INT)CODE_BOOK_ESC_LAV)](values, width, + bitCount); + return (0); +} /* count difference between actual and zeroed lines */ -INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) -{ - - INT i,t0,t1,t2,t3,t00,t01; - INT codeLength; - INT signLength; - INT bitCnt=0; - - switch(codeBook){ - case CODE_BOOK_ZERO_NO: - break; - - case CODE_BOOK_1_NO: - for(i=0; i<width; i+=4) { - t0 = values[i+0]; - t1 = values[i+1]; - t2 = values[i+2]; - t3 = values[i+3]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]); - bitCnt+= codeLength; - } - break; - - case CODE_BOOK_2_NO: - for(i=0; i<width; i+=4) { - t0 = values[i+0]; - t1 = values[i+1]; - t2 = values[i+2]; - t3 = values[i+3]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab1_2[t0+1][t1+1][t2+1][t3+1]); - bitCnt+= codeLength; - } - break; - - case CODE_BOOK_3_NO: - for(i=0; i<width; i+=4) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - t2 = values[i+2]; - if(t2 != 0){ - signLength++; - t2=fixp_abs(t2); - } - t3 = values[i+3]; - if(t3 != 0){ - signLength++; - t3=fixp_abs(t3); - } - - codeLength = HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); - bitCnt+=codeLength+signLength; - } - break; - - case CODE_BOOK_4_NO: - for(i=0; i<width; i+=4) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - t2 = values[i+2]; - if(t2 != 0){ - signLength++; - t2=fixp_abs(t2); - } - t3 = values[i+3]; - if(t3 != 0){ - signLength++; - t3=fixp_abs(t3); - } - codeLength = LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); - bitCnt+=codeLength+signLength; - } - break; - - case CODE_BOOK_5_NO: - for(i=0; i<width; i+=2) { - t0 = values[i+0]; - t1 = values[i+1]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab5_6[t0+4][t1+4]); - bitCnt+=codeLength; - } - break; - - case CODE_BOOK_6_NO: - for(i=0; i<width; i+=2) { - t0 = values[i+0]; - t1 = values[i+1]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab5_6[t0+4][t1+4]); - bitCnt+=codeLength; - } - break; - - case CODE_BOOK_7_NO: - for(i=0; i<width; i+=2){ - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); - bitCnt+=codeLength +signLength; - } - break; - - case CODE_BOOK_8_NO: - for(i=0; i<width; i+=2) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); - bitCnt+=codeLength +signLength; - } - break; - - case CODE_BOOK_9_NO: - for(i=0; i<width; i+=2) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); - bitCnt+=codeLength +signLength; - } - break; - - case CODE_BOOK_10_NO: - for(i=0; i<width; i+=2) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); - bitCnt+=codeLength +signLength; - } - break; - - case CODE_BOOK_ESC_NO: - for(i=0; i<width; i+=2) { - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - t0=fixp_abs(t0); - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - t1=fixp_abs(t1); - } - t00 = fixMin(t0,16); - t01 = fixMin(t1,16); - - codeLength = (INT) FDKaacEnc_huff_ltab11[t00][t01]; - bitCnt+=codeLength +signLength; - if(t0 >=16){ - INT n,p; - n=0; - p=t0; - while((p>>=1) >=16){ - bitCnt++; - n++; +INT FDKaacEnc_countValues(SHORT *RESTRICT values, INT width, INT codeBook) { + INT i, t0, t1, t2, t3; + INT bitCnt = 0; + + switch (codeBook) { + case CODE_BOOK_ZERO_NO: + break; + + case CODE_BOOK_1_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += + HI_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]); + } + break; + + case CODE_BOOK_2_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += + LO_LTAB(FDKaacEnc_huff_ltab1_2[t0 + 1][t1 + 1][t2 + 1][t3 + 1]); + } + break; + + case CODE_BOOK_3_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); + } + break; + + case CODE_BOOK_4_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); + } + break; + + case CODE_BOOK_5_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) + + HI_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]); + } + break; + + case CODE_BOOK_6_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0]; + t1 = values[i + 1]; + t2 = values[i + 2]; + t3 = values[i + 3]; + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0 + 4][t1 + 4]) + + LO_LTAB(FDKaacEnc_huff_ltab5_6[t2 + 4][t3 + 4]); + } + break; + + case CODE_BOOK_7_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) + + HI_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]); + } + break; + + case CODE_BOOK_8_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]) + + LO_LTAB(FDKaacEnc_huff_ltab7_8[t2][t3]); + } + break; + + case CODE_BOOK_9_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) + + HI_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]); + } + break; + + case CODE_BOOK_10_NO: + for (i = 0; i < width; i += 4) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + t2 = fixp_abs(values[i + 2]); + bitCnt += (t2 > 0); + t3 = fixp_abs(values[i + 3]); + bitCnt += (t3 > 0); + bitCnt += LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]) + + LO_LTAB(FDKaacEnc_huff_ltab9_10[t2][t3]); + } + break; + + case CODE_BOOK_ESC_NO: + for (i = 0; i < width; i += 2) { + t0 = fixp_abs(values[i + 0]); + bitCnt += (t0 > 0); + t1 = fixp_abs(values[i + 1]); + bitCnt += (t1 > 0); + bitCnt += (INT)FDKaacEnc_huff_ltab11[fixMin(t0, 16)][fixMin(t1, 16)]; + if (t0 >= 16) { + bitCnt += 5; + while ((t0 >>= 1) >= 16) bitCnt += 2; } - bitCnt+=(n+5); - } - if(t1 >=16){ - INT n,p; - n=0; - p=t1; - while((p>>=1) >=16){ - bitCnt++; - n++; + if (t1 >= 16) { + bitCnt += 5; + while ((t1 >>= 1) >= 16) bitCnt += 2; } - bitCnt+=(n+5); } - } - break; + break; - default: - break; + default: + break; } - return(bitCnt); + return (bitCnt); } - - -INT FDKaacEnc_codeValues(SHORT *RESTRICT values, INT width, INT codeBook, HANDLE_FDK_BITSTREAM hBitstream) -{ - - INT i,t0,t1,t2,t3,t00,t01; - INT codeWord,codeLength; - INT sign,signLength; - - switch(codeBook){ - case CODE_BOOK_ZERO_NO: - break; - - case CODE_BOOK_1_NO: - for(i=0; i<width; i+=4) { - t0 = values[i+0]+1; - t1 = values[i+1]+1; - t2 = values[i+2]+1; - t3 = values[i+3]+1; - codeWord = FDKaacEnc_huff_ctab1[t0][t1][t2][t3]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]); - FDKwriteBits(hBitstream,codeWord,codeLength); - } - break; - - case CODE_BOOK_2_NO: - for(i=0; i<width; i+=4) { - t0 = values[i+0]+1; - t1 = values[i+1]+1; - t2 = values[i+2]+1; - t3 = values[i+3]+1; - codeWord = FDKaacEnc_huff_ctab2[t0][t1][t2][t3]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]); - FDKwriteBits(hBitstream,codeWord,codeLength); - } - break; - - case CODE_BOOK_3_NO: - for(i=0; i<width; i+=4) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); +INT FDKaacEnc_codeValues(SHORT *RESTRICT values, INT width, INT codeBook, + HANDLE_FDK_BITSTREAM hBitstream) { + INT i, t0, t1, t2, t3, t00, t01; + INT codeWord, codeLength; + INT sign, signLength; + + DWORD_ALIGNED(values); + + switch (codeBook) { + case CODE_BOOK_ZERO_NO: + break; + + case CODE_BOOK_1_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0] + 1; + t1 = values[i + 1] + 1; + t2 = values[i + 2] + 1; + t3 = values[i + 3] + 1; + codeWord = FDKaacEnc_huff_ctab1[t0][t1][t2][t3]; + codeLength = HI_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_2_NO: + for (i = 0; i < width; i += 4) { + t0 = values[i + 0] + 1; + t1 = values[i + 1] + 1; + t2 = values[i + 2] + 1; + t3 = values[i + 3] + 1; + codeWord = FDKaacEnc_huff_ctab2[t0][t1][t2][t3]; + codeLength = LO_LTAB(FDKaacEnc_huff_ltab1_2[t0][t1][t2][t3]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_3_NO: + for (i = 0; i < (width >> 2); i++) { + sign = 0; + signLength = 0; + int index[4]; + for (int j = 0; j < 4; j++) { + int ti = *values++; + int zero = (ti == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)ti >> 31); + index[j] = fixp_abs(ti); } - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - t2 = values[i+2]; - if(t2 != 0){ - signLength++; - sign<<=1; - if(t2 < 0){ - sign|=1; - t2=fixp_abs(t2); + codeWord = FDKaacEnc_huff_ctab3[index[0]][index[1]][index[2]][index[3]]; + codeLength = HI_LTAB( + FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_4_NO: + for (i = 0; i < width; i += 4) { + sign = 0; + signLength = 0; + int index[4]; + for (int j = 0; j < 4; j++) { + int ti = *values++; + int zero = (ti == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)ti >> 31); + index[j] = fixp_abs(ti); } - } - t3 = values[i+3]; - if(t3 != 0){ - signLength++; - sign<<=1; - if(t3 < 0){ - sign|=1; - t3=fixp_abs(t3); + codeWord = FDKaacEnc_huff_ctab4[index[0]][index[1]][index[2]][index[3]]; + codeLength = LO_LTAB( + FDKaacEnc_huff_ltab3_4[index[0]][index[1]][index[2]][index[3]]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_5_NO: + for (i = 0; i < (width >> 2); i++) { + t0 = *values++ + 4; + t1 = *values++ + 4; + t2 = *values++ + 4; + t3 = *values++ + 4; + codeWord = FDKaacEnc_huff_ctab5[t0][t1]; + codeLength = + HI_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */ + codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab5[t2][t3]; + codeLength += HI_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_6_NO: + for (i = 0; i < (width >> 2); i++) { + t0 = *values++ + 4; + t1 = *values++ + 4; + t2 = *values++ + 4; + t3 = *values++ + 4; + codeWord = FDKaacEnc_huff_ctab6[t0][t1]; + codeLength = + LO_LTAB(FDKaacEnc_huff_ltab5_6[t2][t3]); /* length of 2nd cw */ + codeWord = (codeWord << codeLength) + FDKaacEnc_huff_ctab6[t2][t3]; + codeLength += LO_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); + FDKwriteBits(hBitstream, codeWord, codeLength); + } + break; + + case CODE_BOOK_7_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab7[t0][t1]; + codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_8_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab8[t0][t1]; + codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_9_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab9[t0][t1]; + codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_10_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + codeWord = FDKaacEnc_huff_ctab10[t0][t1]; + codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + } + break; + + case CODE_BOOK_ESC_NO: + for (i = 0; i < (width >> 1); i++) { + t0 = *values++; + sign = ((UINT)t0 >> 31); + t0 = fixp_abs(t0); + signLength = (t0 == 0) ? 0 : 1; + t1 = *values++; + INT zero = (t1 == 0) ? 0 : 1; + signLength += zero; + sign = (sign << zero) + ((UINT)t1 >> 31); + t1 = fixp_abs(t1); + + t00 = fixMin(t0, 16); + t01 = fixMin(t1, 16); + + codeWord = FDKaacEnc_huff_ctab11[t00][t01]; + codeLength = (INT)FDKaacEnc_huff_ltab11[t00][t01]; + FDKwriteBits(hBitstream, (codeWord << signLength) | sign, + codeLength + signLength); + for (int j = 0; j < 2; j++) { + if (t0 >= 16) { + INT n = 4, p = t0; + for (; (p >>= 1) >= 16;) n++; + FDKwriteBits(hBitstream, + (((1 << (n - 3)) - 2) << n) | (t0 - (1 << n)), + n + n - 3); + } + t0 = t1; } } + break; - codeWord = FDKaacEnc_huff_ctab3[t0][t1][t2][t3]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_4_NO: - for(i=0; i<width; i+=4) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - t2 = values[i+2]; - if(t2 != 0){ - signLength++; - sign<<=1; - if(t2 < 0){ - sign|=1; - t2=fixp_abs(t2); - } - } - t3 = values[i+3]; - if(t3 != 0){ - signLength++; - sign<<=1; - if(t3 < 0){ - sign|=1; - t3=fixp_abs(t3); - } - } - codeWord = FDKaacEnc_huff_ctab4[t0][t1][t2][t3]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab3_4[t0][t1][t2][t3]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_5_NO: - for(i=0; i<width; i+=2) { - t0 = values[i+0]+4; - t1 = values[i+1]+4; - codeWord = FDKaacEnc_huff_ctab5[t0][t1]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - } - break; - - case CODE_BOOK_6_NO: - for(i=0; i<width; i+=2) { - t0 = values[i+0]+4; - t1 = values[i+1]+4; - codeWord = FDKaacEnc_huff_ctab6[t0][t1]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab5_6[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - } - break; - - case CODE_BOOK_7_NO: - for(i=0; i<width; i+=2){ - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - codeWord = FDKaacEnc_huff_ctab7[t0][t1]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_8_NO: - for(i=0; i<width; i+=2) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - codeWord = FDKaacEnc_huff_ctab8[t0][t1]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab7_8[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_9_NO: - for(i=0; i<width; i+=2) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - codeWord = FDKaacEnc_huff_ctab9[t0][t1]; - codeLength = HI_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_10_NO: - for(i=0; i<width; i+=2) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - codeWord = FDKaacEnc_huff_ctab10[t0][t1]; - codeLength = LO_LTAB(FDKaacEnc_huff_ltab9_10[t0][t1]); - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - } - break; - - case CODE_BOOK_ESC_NO: - for(i=0; i<width; i+=2) { - sign=0; - signLength=0; - t0 = values[i+0]; - if(t0 != 0){ - signLength++; - sign<<=1; - if(t0 < 0){ - sign|=1; - t0=fixp_abs(t0); - } - } - t1 = values[i+1]; - if(t1 != 0){ - signLength++; - sign<<=1; - if(t1 < 0){ - sign|=1; - t1=fixp_abs(t1); - } - } - t00 = fixMin(t0,16); - t01 = fixMin(t1,16); - - codeWord = FDKaacEnc_huff_ctab11[t00][t01]; - codeLength = (INT) FDKaacEnc_huff_ltab11[t00][t01]; - FDKwriteBits(hBitstream,codeWord,codeLength); - FDKwriteBits(hBitstream,sign,signLength); - if(t0 >=16){ - INT n,p; - n=0; - p=t0; - while((p>>=1) >=16){ - FDKwriteBits(hBitstream,1,1); - n++; - } - FDKwriteBits(hBitstream,0,1); - FDKwriteBits(hBitstream,t0-(1<<(n+4)),n+4); - } - if(t1 >=16){ - INT n,p; - n=0; - p=t1; - while((p>>=1) >=16){ - FDKwriteBits(hBitstream,1,1); - n++; - } - FDKwriteBits(hBitstream,0,1); - FDKwriteBits(hBitstream,t1-(1<<(n+4)),n+4); - } - } - break; - - default: - break; + default: + break; } - return(0); + return (0); } -INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) -{ - INT codeWord,codeLength; +INT FDKaacEnc_codeScalefactorDelta(INT delta, HANDLE_FDK_BITSTREAM hBitstream) { + INT codeWord, codeLength; - if(fixp_abs(delta) >CODE_BOOK_SCF_LAV) - return(1); + if (fixp_abs(delta) > CODE_BOOK_SCF_LAV) return (1); - codeWord = FDKaacEnc_huff_ctabscf[delta+CODE_BOOK_SCF_LAV]; - codeLength = (INT)FDKaacEnc_huff_ltabscf[delta+CODE_BOOK_SCF_LAV]; - FDKwriteBits(hBitstream,codeWord,codeLength); - return(0); + codeWord = FDKaacEnc_huff_ctabscf[delta + CODE_BOOK_SCF_LAV]; + codeLength = (INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]; + FDKwriteBits(hBitstream, codeWord, codeLength); + return (0); } - - - diff --git a/libAACenc/src/bit_cnt.h b/libAACenc/src/bit_cnt.h index 7c4b59e..7f4c450 100644 --- a/libAACenc/src/bit_cnt.h +++ b/libAACenc/src/bit_cnt.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,46 +90,46 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Huffman Bitcounter & coder + Author(s): M.Werner -******************************************************************************/ + Description: Huffman Bitcounter & coder -#ifndef __BITCOUNT_H -#define __BITCOUNT_H +*******************************************************************************/ +#ifndef BIT_CNT_H +#define BIT_CNT_H #include "common_fix.h" #include "FDK_bitstream.h" #include "aacEnc_rom.h" -#define INVALID_BITCOUNT (FDK_INT_MAX/4) +#define INVALID_BITCOUNT (FDK_INT_MAX / 4) /* code book number table */ -enum codeBookNo{ - CODE_BOOK_ZERO_NO= 0, - CODE_BOOK_1_NO= 1, - CODE_BOOK_2_NO= 2, - CODE_BOOK_3_NO= 3, - CODE_BOOK_4_NO= 4, - CODE_BOOK_5_NO= 5, - CODE_BOOK_6_NO= 6, - CODE_BOOK_7_NO= 7, - CODE_BOOK_8_NO= 8, - CODE_BOOK_9_NO= 9, - CODE_BOOK_10_NO= 10, - CODE_BOOK_ESC_NO= 11, - CODE_BOOK_RES_NO= 12, - CODE_BOOK_PNS_NO= 13, - CODE_BOOK_IS_OUT_OF_PHASE_NO= 14, - CODE_BOOK_IS_IN_PHASE_NO= 15 +enum codeBookNo { + CODE_BOOK_ZERO_NO = 0, + CODE_BOOK_1_NO = 1, + CODE_BOOK_2_NO = 2, + CODE_BOOK_3_NO = 3, + CODE_BOOK_4_NO = 4, + CODE_BOOK_5_NO = 5, + CODE_BOOK_6_NO = 6, + CODE_BOOK_7_NO = 7, + CODE_BOOK_8_NO = 8, + CODE_BOOK_9_NO = 9, + CODE_BOOK_10_NO = 10, + CODE_BOOK_ESC_NO = 11, + CODE_BOOK_RES_NO = 12, + CODE_BOOK_PNS_NO = 13, + CODE_BOOK_IS_OUT_OF_PHASE_NO = 14, + CODE_BOOK_IS_IN_PHASE_NO = 15 }; @@ -126,62 +137,64 @@ enum codeBookNo{ code book index table */ -enum codeBookNdx{ - CODE_BOOK_ZERO_NDX, - CODE_BOOK_1_NDX, - CODE_BOOK_2_NDX, - CODE_BOOK_3_NDX, - CODE_BOOK_4_NDX, - CODE_BOOK_5_NDX, - CODE_BOOK_6_NDX, - CODE_BOOK_7_NDX, - CODE_BOOK_8_NDX, - CODE_BOOK_9_NDX, - CODE_BOOK_10_NDX, - CODE_BOOK_ESC_NDX, - CODE_BOOK_RES_NDX, - CODE_BOOK_PNS_NDX, - CODE_BOOK_IS_OUT_OF_PHASE_NDX, - CODE_BOOK_IS_IN_PHASE_NDX, - NUMBER_OF_CODE_BOOKS +enum codeBookNdx { + CODE_BOOK_ZERO_NDX, + CODE_BOOK_1_NDX, + CODE_BOOK_2_NDX, + CODE_BOOK_3_NDX, + CODE_BOOK_4_NDX, + CODE_BOOK_5_NDX, + CODE_BOOK_6_NDX, + CODE_BOOK_7_NDX, + CODE_BOOK_8_NDX, + CODE_BOOK_9_NDX, + CODE_BOOK_10_NDX, + CODE_BOOK_ESC_NDX, + CODE_BOOK_RES_NDX, + CODE_BOOK_PNS_NDX, + CODE_BOOK_IS_OUT_OF_PHASE_NDX, + CODE_BOOK_IS_IN_PHASE_NDX, + NUMBER_OF_CODE_BOOKS }; /* code book lav table */ -enum codeBookLav{ - CODE_BOOK_ZERO_LAV=0, - CODE_BOOK_1_LAV=1, - CODE_BOOK_2_LAV=1, - CODE_BOOK_3_LAV=2, - CODE_BOOK_4_LAV=2, - CODE_BOOK_5_LAV=4, - CODE_BOOK_6_LAV=4, - CODE_BOOK_7_LAV=7, - CODE_BOOK_8_LAV=7, - CODE_BOOK_9_LAV=12, - CODE_BOOK_10_LAV=12, - CODE_BOOK_ESC_LAV=16, - CODE_BOOK_SCF_LAV=60, - CODE_BOOK_PNS_LAV=60 - }; - -INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, - const INT noOfSpecLines, - INT maxVal, - INT *bitCountLut); - -INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook); - -INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook, HANDLE_FDK_BITSTREAM hBitstream); - -INT FDKaacEnc_codeScalefactorDelta(INT scalefactor, HANDLE_FDK_BITSTREAM hBitstream); - -inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) -{ - FDK_ASSERT( (0 <= (delta+CODE_BOOK_SCF_LAV)) && ((delta+CODE_BOOK_SCF_LAV)<(int)(sizeof(FDKaacEnc_huff_ltabscf)/sizeof((FDKaacEnc_huff_ltabscf[0])))) ); - return((INT)FDKaacEnc_huff_ltabscf[delta+CODE_BOOK_SCF_LAV]); +enum codeBookLav { + CODE_BOOK_ZERO_LAV = 0, + CODE_BOOK_1_LAV = 1, + CODE_BOOK_2_LAV = 1, + CODE_BOOK_3_LAV = 2, + CODE_BOOK_4_LAV = 2, + CODE_BOOK_5_LAV = 4, + CODE_BOOK_6_LAV = 4, + CODE_BOOK_7_LAV = 7, + CODE_BOOK_8_LAV = 7, + CODE_BOOK_9_LAV = 12, + CODE_BOOK_10_LAV = 12, + CODE_BOOK_ESC_LAV = 16, + CODE_BOOK_SCF_LAV = 60, + CODE_BOOK_PNS_LAV = 60 +}; + +INT FDKaacEnc_bitCount(const SHORT *aQuantSpectrum, const INT noOfSpecLines, + INT maxVal, INT *bitCountLut); + +INT FDKaacEnc_countValues(SHORT *values, INT width, INT codeBook); + +INT FDKaacEnc_codeValues(SHORT *values, INT width, INT codeBook, + HANDLE_FDK_BITSTREAM hBitstream); + +INT FDKaacEnc_codeScalefactorDelta(INT scalefactor, + HANDLE_FDK_BITSTREAM hBitstream); + +inline INT FDKaacEnc_bitCountScalefactorDelta(const INT delta) { + FDK_ASSERT((0 <= (delta + CODE_BOOK_SCF_LAV)) && + ((delta + CODE_BOOK_SCF_LAV) < + (int)(sizeof(FDKaacEnc_huff_ltabscf) / + sizeof((FDKaacEnc_huff_ltabscf[0]))))); + return ((INT)FDKaacEnc_huff_ltabscf[delta + CODE_BOOK_SCF_LAV]); } #endif diff --git a/libAACenc/src/bitenc.cpp b/libAACenc/src/bitenc.cpp index 8e477aa..652d1fd 100644 --- a/libAACenc/src/bitenc.cpp +++ b/libAACenc/src/bitenc.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ - /******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Bitstream encoder + Author(s): M. Werner -******************************************************************************/ + Description: Bitstream encoder + +*******************************************************************************/ #include "bitenc.h" #include "bit_cnt.h" @@ -95,14 +107,13 @@ amm-info@iis.fraunhofer.de #include "interface.h" #include "aacEnc_ram.h" - #include "tpenc_lib.h" -#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */ +#include "FDK_tools_rom.h" /* needed for the bitstream syntax tables */ static const int globalGainOffset = 100; -static const int icsReservedBit = 0; -static const int noiseOffset = 90; +static const int icsReservedBit = 0; +static const int noiseOffset = 90; /***************************************************************************** @@ -113,30 +124,26 @@ static const int noiseOffset = 90; output: *****************************************************************************/ -static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, - SECTION_DATA *sectionData, - SHORT *quantSpectrum, - HANDLE_FDK_BITSTREAM hBitStream) -{ - INT i,sfb; +static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, + SECTION_DATA *sectionData, + SHORT *quantSpectrum, + HANDLE_FDK_BITSTREAM hBitStream) { + INT i, sfb; INT dbgVal = FDKgetValidBits(hBitStream); - for(i=0;i<sectionData->noOfSections;i++) - { - if(sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO) { /* huffencode spectral data for this huffsection */ - INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt; - for(sfb=sectionData->huffsection[i].sfbStart; sfb<tmp; sfb++) - { - FDKaacEnc_codeValues(quantSpectrum+sfbOffset[sfb], - sfbOffset[sfb+1]-sfbOffset[sfb], - sectionData->huffsection[i].codeBook, - hBitStream); + INT tmp = sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (sfb = sectionData->huffsection[i].sfbStart; sfb < tmp; sfb++) { + FDKaacEnc_codeValues(quantSpectrum + sfbOffset[sfb], + sfbOffset[sfb + 1] - sfbOffset[sfb], + sectionData->huffsection[i].codeBook, hBitStream); } } } - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } /***************************************************************************** @@ -148,18 +155,18 @@ static INT FDKaacEnc_encodeSpectralData(INT *sfbOffset, output: *****************************************************************************/ -static INT FDKaacEnc_encodeGlobalGain(INT globalGain, - INT scalefac, +static INT FDKaacEnc_encodeGlobalGain(INT globalGain, INT scalefac, HANDLE_FDK_BITSTREAM hBitStream, - INT mdctScale) -{ + INT mdctScale) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,globalGain - scalefac + globalGainOffset-4*(LOG_NORM_PCM-mdctScale),8); + FDKwriteBits(hBitStream, + globalGain - scalefac + globalGainOffset - + 4 * (LOG_NORM_PCM - mdctScale), + 8); } return (8); } - /***************************************************************************** functionname:FDKaacEnc_encodeIcsInfo @@ -170,13 +177,10 @@ static INT FDKaacEnc_encodeGlobalGain(INT globalGain, *****************************************************************************/ -static INT FDKaacEnc_encodeIcsInfo(INT blockType, - INT windowShape, - INT groupingMask, - INT maxSfbPerGroup, - HANDLE_FDK_BITSTREAM hBitStream, - UINT syntaxFlags) -{ +static INT FDKaacEnc_encodeIcsInfo(INT blockType, INT windowShape, + INT groupingMask, INT maxSfbPerGroup, + HANDLE_FDK_BITSTREAM hBitStream, + UINT syntaxFlags) { INT statBits; if (blockType == SHORT_WINDOW) { @@ -184,38 +188,38 @@ static INT FDKaacEnc_encodeIcsInfo(INT blockType, } else { if (syntaxFlags & AC_ELD) { statBits = 6; - } else - { + } else { statBits = (!(syntaxFlags & AC_SCALABLE)) ? 11 : 10; } } if (hBitStream != NULL) { - - if (!(syntaxFlags & AC_ELD)){ - FDKwriteBits(hBitStream,icsReservedBit,1); - FDKwriteBits(hBitStream,blockType,2); - FDKwriteBits(hBitStream, (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape,1); + if (!(syntaxFlags & AC_ELD)) { + FDKwriteBits(hBitStream, icsReservedBit, 1); + FDKwriteBits(hBitStream, blockType, 2); + FDKwriteBits(hBitStream, + (windowShape == LOL_WINDOW) ? KBD_WINDOW : windowShape, 1); } - switch(blockType){ - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - FDKwriteBits(hBitStream,maxSfbPerGroup,6); + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + FDKwriteBits(hBitStream, maxSfbPerGroup, 6); - if (!(syntaxFlags & (AC_SCALABLE|AC_ELD)) ) { /* If not scalable syntax then ... */ - /* No predictor data present */ - FDKwriteBits(hBitStream, 0, 1); - } - break; + if (!(syntaxFlags & + (AC_SCALABLE | AC_ELD))) { /* If not scalable syntax then ... */ + /* No predictor data present */ + FDKwriteBits(hBitStream, 0, 1); + } + break; - case SHORT_WINDOW: - FDKwriteBits(hBitStream,maxSfbPerGroup,4); + case SHORT_WINDOW: + FDKwriteBits(hBitStream, maxSfbPerGroup, 4); - /* Write grouping bits */ - FDKwriteBits(hBitStream,groupingMask,TRANS_FAC-1); - break; + /* Write grouping bits */ + FDKwriteBits(hBitStream, groupingMask, TRANS_FAC - 1); + break; } } @@ -234,48 +238,44 @@ static INT FDKaacEnc_encodeIcsInfo(INT blockType, *****************************************************************************/ static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData, HANDLE_FDK_BITSTREAM hBitStream, - UINT useVCB11) -{ + UINT useVCB11) { if (hBitStream != NULL) { - INT sectEscapeVal=0,sectLenBits=0; + INT sectEscapeVal = 0, sectLenBits = 0; INT sectLen; INT i; - INT dbgVal=FDKgetValidBits(hBitStream); + INT dbgVal = FDKgetValidBits(hBitStream); INT sectCbBits = 4; - switch(sectionData->blockType) - { - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sectEscapeVal = SECT_ESC_VAL_LONG; - sectLenBits = SECT_BITS_LONG; - break; - - case SHORT_WINDOW: - sectEscapeVal = SECT_ESC_VAL_SHORT; - sectLenBits = SECT_BITS_SHORT; - break; + switch (sectionData->blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + sectEscapeVal = SECT_ESC_VAL_LONG; + sectLenBits = SECT_BITS_LONG; + break; + + case SHORT_WINDOW: + sectEscapeVal = SECT_ESC_VAL_SHORT; + sectLenBits = SECT_BITS_SHORT; + break; } - for(i=0;i<sectionData->noOfSections;i++) - { + for (i = 0; i < sectionData->noOfSections; i++) { INT codeBook = sectionData->huffsection[i].codeBook; - FDKwriteBits(hBitStream,codeBook,sectCbBits); + FDKwriteBits(hBitStream, codeBook, sectCbBits); { sectLen = sectionData->huffsection[i].sfbCnt; - while(sectLen >= sectEscapeVal) - { - FDKwriteBits(hBitStream,sectEscapeVal,sectLenBits); - sectLen-=sectEscapeVal; + while (sectLen >= sectEscapeVal) { + FDKwriteBits(hBitStream, sectEscapeVal, sectLenBits); + sectLen -= sectEscapeVal; } - FDKwriteBits(hBitStream,sectLen,sectLenBits); + FDKwriteBits(hBitStream, sectLen, sectLenBits); } } - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } return (0); } @@ -289,16 +289,14 @@ static INT FDKaacEnc_encodeSectionData(SECTION_DATA *sectionData, output: *****************************************************************************/ -static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, - SECTION_DATA *sectionData, - INT *scalefac, - HANDLE_FDK_BITSTREAM hBitStream, - INT *RESTRICT noiseNrg, - const INT *isScale, - INT globalGain) -{ +static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, + SECTION_DATA *sectionData, + INT *scalefac, + HANDLE_FDK_BITSTREAM hBitStream, + INT *RESTRICT noiseNrg, + const INT *isScale, INT globalGain) { if (hBitStream != NULL) { - INT i,j,lastValScf,deltaScf; + INT i, j, lastValScf, deltaScf; INT deltaPns; INT lastValPns = 0; INT noisePCMFlag = TRUE; @@ -306,65 +304,65 @@ static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, INT dbgVal = FDKgetValidBits(hBitStream); - lastValScf=scalefac[sectionData->firstScf]; - lastValPns = globalGain-scalefac[sectionData->firstScf]+globalGainOffset-4*LOG_NORM_PCM-noiseOffset; - lastValIs = 0; + lastValScf = scalefac[sectionData->firstScf]; + lastValPns = globalGain - scalefac[sectionData->firstScf] + + globalGainOffset - 4 * LOG_NORM_PCM - noiseOffset; + lastValIs = 0; - for(i=0; i<sectionData->noOfSections; i++){ + for (i = 0; i < sectionData->noOfSections; i++) { if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) { - - if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) - { + if ((sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_IN_PHASE_NO)) { INT sfbStart = sectionData->huffsection[i].sfbStart; INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt; - for(j=sfbStart; j<tmp; j++) { - INT deltaIs = isScale[j]-lastValIs; + for (j = sfbStart; j < tmp; j++) { + INT deltaIs = isScale[j] - lastValIs; lastValIs = isScale[j]; - if(FDKaacEnc_codeScalefactorDelta(deltaIs,hBitStream)) { - return(1); + if (FDKaacEnc_codeScalefactorDelta(deltaIs, hBitStream)) { + return (1); } } /* sfb */ - } - else if(sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) { + } else if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) { INT sfbStart = sectionData->huffsection[i].sfbStart; INT tmp = sfbStart + sectionData->huffsection[i].sfbCnt; - for(j=sfbStart; j<tmp; j++) { - deltaPns = noiseNrg[j]-lastValPns; + for (j = sfbStart; j < tmp; j++) { + deltaPns = noiseNrg[j] - lastValPns; lastValPns = noiseNrg[j]; - if(noisePCMFlag){ - FDKwriteBits(hBitStream,deltaPns+(1<<(PNS_PCM_BITS-1)),PNS_PCM_BITS); + if (noisePCMFlag) { + FDKwriteBits(hBitStream, deltaPns + (1 << (PNS_PCM_BITS - 1)), + PNS_PCM_BITS); noisePCMFlag = FALSE; - } - else { - if(FDKaacEnc_codeScalefactorDelta(deltaPns,hBitStream)) { - return(1); + } else { + if (FDKaacEnc_codeScalefactorDelta(deltaPns, hBitStream)) { + return (1); } } } /* sfb */ - } - else { - INT tmp = sectionData->huffsection[i].sfbStart+sectionData->huffsection[i].sfbCnt; - for(j=sectionData->huffsection[i].sfbStart; j<tmp; j++){ + } else { + INT tmp = sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) { /* check if we can repeat the last value to save bits */ - if(maxValueInSfb[j] == 0) + if (maxValueInSfb[j] == 0) deltaScf = 0; - else{ - deltaScf = -(scalefac[j]-lastValScf); + else { + deltaScf = -(scalefac[j] - lastValScf); lastValScf = scalefac[j]; } - if(FDKaacEnc_codeScalefactorDelta(deltaScf,hBitStream)){ - return(1); + if (FDKaacEnc_codeScalefactorDelta(deltaScf, hBitStream)) { + return (1); } } /* sfb */ - } /* code scalefactor */ - } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */ - } /* section loop */ + } /* code scalefactor */ + } /* sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO */ + } /* section loop */ - return(FDKgetValidBits(hBitStream)-dbgVal); + return (FDKgetValidBits(hBitStream) - dbgVal); } /* if (hBitStream != NULL) */ return (0); @@ -379,53 +377,43 @@ static INT FDKaacEnc_encodeScaleFactorData(UINT *maxValueInSfb, output: *****************************************************************************/ -static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, - INT grpSfb, - INT maxSfb, - INT msDigest, - INT *jsFlags, - HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, INT grpSfb, INT maxSfb, + INT msDigest, INT *jsFlags, + HANDLE_FDK_BITSTREAM hBitStream) { INT sfb, sfbOff, msBits = 0; - if (hBitStream != NULL) - { - switch(msDigest) - { - case MS_NONE: - FDKwriteBits(hBitStream,SI_MS_MASK_NONE,2); - msBits += 2; - break; - - case MS_ALL: - FDKwriteBits(hBitStream,SI_MS_MASK_ALL,2); - msBits += 2; - break; - - case MS_SOME: - FDKwriteBits(hBitStream,SI_MS_MASK_SOME,2); - msBits += 2; - for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) - { - for(sfb=0; sfb<maxSfb; sfb++) - { - if(jsFlags[sfbOff+sfb] & MS_ON){ - FDKwriteBits(hBitStream,1,1); - } - else{ - FDKwriteBits(hBitStream,0,1); + if (hBitStream != NULL) { + switch (msDigest) { + case MS_NONE: + FDKwriteBits(hBitStream, SI_MS_MASK_NONE, 2); + msBits += 2; + break; + + case MS_ALL: + FDKwriteBits(hBitStream, SI_MS_MASK_ALL, 2); + msBits += 2; + break; + + case MS_SOME: + FDKwriteBits(hBitStream, SI_MS_MASK_SOME, 2); + msBits += 2; + for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) { + for (sfb = 0; sfb < maxSfb; sfb++) { + if (jsFlags[sfbOff + sfb] & MS_ON) { + FDKwriteBits(hBitStream, 1, 1); + } else { + FDKwriteBits(hBitStream, 0, 1); + } + msBits += 1; } - msBits += 1; } - } - break; + break; } - } - else { + } else { msBits += 2; if (msDigest == MS_SOME) { - for(sfbOff = 0; sfbOff < sfbCnt; sfbOff+=grpSfb) { - for(sfb=0; sfb<maxSfb; sfb++) { + for (sfbOff = 0; sfbOff < sfbCnt; sfbOff += grpSfb) { + for (sfb = 0; sfb < maxSfb; sfb++) { msBits += 1; } } @@ -443,26 +431,23 @@ static INT FDKaacEnc_encodeMSInfo(INT sfbCnt, output: *****************************************************************************/ -static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, - INT blockType, - HANDLE_FDK_BITSTREAM hBitStream) -{ - if ( (hBitStream!=NULL) && (tnsInfo!=NULL) ) - { +static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, INT blockType, + HANDLE_FDK_BITSTREAM hBitStream) { + if ((hBitStream != NULL) && (tnsInfo != NULL)) { INT i, tnsPresent = 0; - INT numOfWindows = (blockType==SHORT_WINDOW?TRANS_FAC:1); + INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1); - for (i=0; i<numOfWindows; i++) { - if (tnsInfo->numOfFilters[i]!=0) { - tnsPresent=1; + for (i = 0; i < numOfWindows; i++) { + if (tnsInfo->numOfFilters[i] != 0) { + tnsPresent = 1; break; } } - if (tnsPresent==0) { - FDKwriteBits(hBitStream,0,1); + if (tnsPresent == 0) { + FDKwriteBits(hBitStream, 0, 1); } else { - FDKwriteBits(hBitStream,1,1); + FDKwriteBits(hBitStream, 1, 1); } } return (1); @@ -477,106 +462,108 @@ static INT FDKaacEnc_encodeTnsDataPresent(TNS_INFO *tnsInfo, output: *****************************************************************************/ -static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, - INT blockType, - HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, INT blockType, + HANDLE_FDK_BITSTREAM hBitStream) { INT tnsBits = 0; - if (tnsInfo!=NULL) { - - INT i,j,k; + if (tnsInfo != NULL) { + INT i, j, k; INT tnsPresent = 0; INT coefBits; - INT numOfWindows=(blockType==SHORT_WINDOW?TRANS_FAC:1); + INT numOfWindows = (blockType == SHORT_WINDOW ? TRANS_FAC : 1); - for (i=0; i<numOfWindows; i++) { - if (tnsInfo->numOfFilters[i]!=0) { - tnsPresent=1; + for (i = 0; i < numOfWindows; i++) { + if (tnsInfo->numOfFilters[i] != 0) { + tnsPresent = 1; } } - if (hBitStream != NULL) - { - if (tnsPresent==1) { /* there is data to be written*/ - for (i=0; i<numOfWindows; i++) { - FDKwriteBits(hBitStream,tnsInfo->numOfFilters[i],(blockType==SHORT_WINDOW?1:2)); - tnsBits += (blockType==SHORT_WINDOW?1:2); + if (hBitStream != NULL) { + if (tnsPresent == 1) { /* there is data to be written*/ + for (i = 0; i < numOfWindows; i++) { + FDKwriteBits(hBitStream, tnsInfo->numOfFilters[i], + (blockType == SHORT_WINDOW ? 1 : 2)); + tnsBits += (blockType == SHORT_WINDOW ? 1 : 2); if (tnsInfo->numOfFilters[i]) { - FDKwriteBits(hBitStream,(tnsInfo->coefRes[i]==4?1:0),1); + FDKwriteBits(hBitStream, (tnsInfo->coefRes[i] == 4 ? 1 : 0), 1); tnsBits += 1; } - for (j=0; j<tnsInfo->numOfFilters[i]; j++) { - FDKwriteBits(hBitStream,tnsInfo->length[i][j],(blockType==SHORT_WINDOW?4:6)); - tnsBits += (blockType==SHORT_WINDOW?4:6); + for (j = 0; j < tnsInfo->numOfFilters[i]; j++) { + FDKwriteBits(hBitStream, tnsInfo->length[i][j], + (blockType == SHORT_WINDOW ? 4 : 6)); + tnsBits += (blockType == SHORT_WINDOW ? 4 : 6); FDK_ASSERT(tnsInfo->order[i][j] <= 12); - FDKwriteBits(hBitStream,tnsInfo->order[i][j],(blockType==SHORT_WINDOW?3:5)); - tnsBits += (blockType==SHORT_WINDOW?3:5); - if (tnsInfo->order[i][j]){ - FDKwriteBits(hBitStream,tnsInfo->direction[i][j],1); - tnsBits +=1; /*direction*/ - if(tnsInfo->coefRes[i] == 4) { + FDKwriteBits(hBitStream, tnsInfo->order[i][j], + (blockType == SHORT_WINDOW ? 3 : 5)); + tnsBits += (blockType == SHORT_WINDOW ? 3 : 5); + if (tnsInfo->order[i][j]) { + FDKwriteBits(hBitStream, tnsInfo->direction[i][j], 1); + tnsBits += 1; /*direction*/ + if (tnsInfo->coefRes[i] == 4) { coefBits = 3; - for(k=0; k<tnsInfo->order[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 3 || - tnsInfo->coef[i][j][k]< -4) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 3 || + tnsInfo->coef[i][j][k] < -4) { coefBits = 4; break; } } } else { coefBits = 2; - for(k=0; k<tnsInfo->order[i][j]; k++) { - if ( tnsInfo->coef[i][j][k]> 1 - || tnsInfo->coef[i][j][k]< -2) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 1 || + tnsInfo->coef[i][j][k] < -2) { coefBits = 3; break; } } } - FDKwriteBits(hBitStream,-(coefBits - tnsInfo->coefRes[i]),1); /*coef_compres*/ - tnsBits +=1; /*coef_compression */ - for (k=0; k<tnsInfo->order[i][j]; k++ ) { - static const INT rmask[] = {0,1,3,7,15}; - FDKwriteBits(hBitStream,tnsInfo->coef[i][j][k] & rmask[coefBits],coefBits); + FDKwriteBits(hBitStream, -(coefBits - tnsInfo->coefRes[i]), + 1); /*coef_compres*/ + tnsBits += 1; /*coef_compression */ + for (k = 0; k < tnsInfo->order[i][j]; k++) { + static const INT rmask[] = {0, 1, 3, 7, 15}; + FDKwriteBits(hBitStream, + tnsInfo->coef[i][j][k] & rmask[coefBits], + coefBits); tnsBits += coefBits; } } } } } - } - else { + } else { if (tnsPresent != 0) { - for (i=0; i<numOfWindows; i++) { - tnsBits += (blockType==SHORT_WINDOW?1:2); + for (i = 0; i < numOfWindows; i++) { + tnsBits += (blockType == SHORT_WINDOW ? 1 : 2); if (tnsInfo->numOfFilters[i]) { tnsBits += 1; - for (j=0; j<tnsInfo->numOfFilters[i]; j++) { - tnsBits += (blockType==SHORT_WINDOW?4:6); - tnsBits += (blockType==SHORT_WINDOW?3:5); + for (j = 0; j < tnsInfo->numOfFilters[i]; j++) { + tnsBits += (blockType == SHORT_WINDOW ? 4 : 6); + tnsBits += (blockType == SHORT_WINDOW ? 3 : 5); if (tnsInfo->order[i][j]) { - tnsBits +=1; /*direction*/ - tnsBits +=1; /*coef_compression */ + tnsBits += 1; /*direction*/ + tnsBits += 1; /*coef_compression */ if (tnsInfo->coefRes[i] == 4) { - coefBits=3; - for (k=0; k<tnsInfo->order[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 3 || tnsInfo->coef[i][j][k]< -4) { + coefBits = 3; + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 3 || + tnsInfo->coef[i][j][k] < -4) { coefBits = 4; break; } } - } - else { + } else { coefBits = 2; - for (k=0; k<tnsInfo->order[i][j]; k++) { - if (tnsInfo->coef[i][j][k]> 1 || tnsInfo->coef[i][j][k]< -2) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { + if (tnsInfo->coef[i][j][k] > 1 || + tnsInfo->coef[i][j][k] < -2) { coefBits = 3; break; } } } - for (k=0; k<tnsInfo->order[i][j]; k++) { + for (k = 0; k < tnsInfo->order[i][j]; k++) { tnsBits += coefBits; } } @@ -599,10 +586,9 @@ static INT FDKaacEnc_encodeTnsData(TNS_INFO *tnsInfo, output: *****************************************************************************/ -static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,0,1); + FDKwriteBits(hBitStream, 0, 1); } return (1); } @@ -616,15 +602,13 @@ static INT FDKaacEnc_encodeGainControlData(HANDLE_FDK_BITSTREAM hBitStream) output: *****************************************************************************/ -static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) -{ +static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) { if (hBitStream != NULL) { - FDKwriteBits(hBitStream,0,1); + FDKwriteBits(hBitStream, 0, 1); } return (1); } - /***************************************************************************** functionname: FDKaacEnc_writeExtensionPayload @@ -634,21 +618,18 @@ static INT FDKaacEnc_encodePulseData(HANDLE_FDK_BITSTREAM hBitStream) output: *****************************************************************************/ -static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, - EXT_PAYLOAD_TYPE extPayloadType, - const UCHAR *extPayloadData, - INT extPayloadBits - ) -{ - #define EXT_TYPE_BITS ( 4 ) - #define DATA_EL_VERSION_BITS ( 4 ) - #define FILL_NIBBLE_BITS ( 4 ) - - INT extBitsUsed = 0; - - if (extPayloadBits >= EXT_TYPE_BITS) - { - UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */ +static INT FDKaacEnc_writeExtensionPayload(HANDLE_FDK_BITSTREAM hBitStream, + EXT_PAYLOAD_TYPE extPayloadType, + const UCHAR *extPayloadData, + INT extPayloadBits) { +#define EXT_TYPE_BITS (4) +#define DATA_EL_VERSION_BITS (4) +#define FILL_NIBBLE_BITS (4) + + INT extBitsUsed = 0; + + if (extPayloadBits >= EXT_TYPE_BITS) { + UCHAR fillByte = 0x00; /* for EXT_FIL and EXT_FILL_DATA */ if (hBitStream != NULL) { FDKwriteBits(hBitStream, extPayloadType, EXT_TYPE_BITS); @@ -656,50 +637,56 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, extBitsUsed += EXT_TYPE_BITS; switch (extPayloadType) { - case EXT_DYNAMIC_RANGE: /* case EXT_SAC_DATA: */ + case EXT_LDSAC_DATA: + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, *extPayloadData++, 4); /* nibble */ + } + extBitsUsed += 4; + case EXT_DYNAMIC_RANGE: case EXT_SBR_DATA: case EXT_SBR_DATA_CRC: if (hBitStream != NULL) { int i, writeBits = extPayloadBits; - for (i=0; writeBits >= 8; i++) { - FDKwriteBits(hBitStream, extPayloadData[i], 8); + for (i = 0; writeBits >= 8; i++) { + FDKwriteBits(hBitStream, *extPayloadData++, 8); writeBits -= 8; } if (writeBits > 0) { - FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); + FDKwriteBits(hBitStream, (*extPayloadData) >> (8 - writeBits), + writeBits); } } extBitsUsed += extPayloadBits; break; - case EXT_DATA_ELEMENT: - { - INT dataElementLength = (extPayloadBits+7)>>3; - INT cnt = dataElementLength; - int loopCounter = 1; + case EXT_DATA_ELEMENT: { + INT dataElementLength = (extPayloadBits + 7) >> 3; + INT cnt = dataElementLength; + int loopCounter = 1; - while (dataElementLength >= 255) { - loopCounter++; - dataElementLength -= 255; - } + while (dataElementLength >= 255) { + loopCounter++; + dataElementLength -= 255; + } - if (hBitStream != NULL) { - int i; - FDKwriteBits(hBitStream, 0x00, DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */ + if (hBitStream != NULL) { + int i; + FDKwriteBits( + hBitStream, 0x00, + DATA_EL_VERSION_BITS); /* data_element_version = ANC_DATA */ - for (i=1; i<loopCounter; i++) { - FDKwriteBits(hBitStream, 255, 8); - } - FDKwriteBits(hBitStream, dataElementLength, 8); + for (i = 1; i < loopCounter; i++) { + FDKwriteBits(hBitStream, 255, 8); + } + FDKwriteBits(hBitStream, dataElementLength, 8); - for (i=0; i<cnt; i++) { - FDKwriteBits(hBitStream, extPayloadData[i], 8); - } + for (i = 0; i < cnt; i++) { + FDKwriteBits(hBitStream, extPayloadData[i], 8); } - extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter*8) + (cnt*8); } - break; + extBitsUsed += DATA_EL_VERSION_BITS + (loopCounter * 8) + (cnt * 8); + } break; case EXT_FILL_DATA: fillByte = 0xA5; @@ -708,7 +695,8 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, if (hBitStream != NULL) { int writeBits = extPayloadBits; FDKwriteBits(hBitStream, 0x00, FILL_NIBBLE_BITS); - writeBits -= 8; /* acount for the extension type and the fill nibble */ + writeBits -= + 8; /* acount for the extension type and the fill nibble */ while (writeBits >= 8) { FDKwriteBits(hBitStream, fillByte, 8); writeBits -= 8; @@ -722,7 +710,6 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, return (extBitsUsed); } - /***************************************************************************** functionname: FDKaacEnc_writeDataStreamElement @@ -732,39 +719,37 @@ static INT FDKaacEnc_writeExtensionPayload( HANDLE_FDK_BITSTREAM hBitStream, output: ******************************************************************************/ -static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, - INT elementInstanceTag, - INT dataPayloadBytes, - UCHAR *dataBuffer, - UINT alignAnchor ) -{ - #define DATA_BYTE_ALIGN_FLAG ( 0 ) - - #define EL_INSTANCE_TAG_BITS ( 4 ) - #define DATA_BYTE_ALIGN_FLAG_BITS ( 1 ) - #define DATA_LEN_COUNT_BITS ( 8 ) - #define DATA_LEN_ESC_COUNT_BITS ( 8 ) - - #define MAX_DATA_ALIGN_BITS ( 7 ) - #define MAX_DSE_DATA_BYTES ( 510 ) - - INT dseBitsUsed = 0; - - while (dataPayloadBytes > 0) - { +static INT FDKaacEnc_writeDataStreamElement(HANDLE_TRANSPORTENC hTpEnc, + INT elementInstanceTag, + INT dataPayloadBytes, + UCHAR *dataBuffer, + UINT alignAnchor) { +#define DATA_BYTE_ALIGN_FLAG (0) + +#define EL_INSTANCE_TAG_BITS (4) +#define DATA_BYTE_ALIGN_FLAG_BITS (1) +#define DATA_LEN_COUNT_BITS (8) +#define DATA_LEN_ESC_COUNT_BITS (8) + +#define MAX_DATA_ALIGN_BITS (7) +#define MAX_DSE_DATA_BYTES (510) + + INT dseBitsUsed = 0; + + while (dataPayloadBytes > 0) { int esc_count = -1; int cnt = 0; INT crcReg = -1; - dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS - + DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS; + dseBitsUsed += EL_ID_BITS + EL_INSTANCE_TAG_BITS + + DATA_BYTE_ALIGN_FLAG_BITS + DATA_LEN_COUNT_BITS; if (DATA_BYTE_ALIGN_FLAG) { dseBitsUsed += MAX_DATA_ALIGN_BITS; } cnt = fixMin(MAX_DSE_DATA_BYTES, dataPayloadBytes); - if ( cnt >= 255 ) { + if (cnt >= 255) { esc_count = cnt - 255; dseBitsUsed += DATA_LEN_ESC_COUNT_BITS; } @@ -784,7 +769,7 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, FDKwriteBits(hBitStream, DATA_BYTE_ALIGN_FLAG, DATA_BYTE_ALIGN_FLAG_BITS); /* write length field(s) */ - if ( esc_count >= 0 ) { + if (esc_count >= 0) { FDKwriteBits(hBitStream, 255, DATA_LEN_COUNT_BITS); FDKwriteBits(hBitStream, esc_count, DATA_LEN_ESC_COUNT_BITS); } else { @@ -795,11 +780,12 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, INT tmp = (INT)FDKgetValidBits(hBitStream); FDKbyteAlign(hBitStream, alignAnchor); /* count actual bits */ - dseBitsUsed += (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS; + dseBitsUsed += + (INT)FDKgetValidBits(hBitStream) - tmp - MAX_DATA_ALIGN_BITS; } /* write payload */ - for (i=0; i<cnt; i++) { + for (i = 0; i < cnt; i++) { FDKwriteBits(hBitStream, dataBuffer[i], 8); } transportEnc_CrcEndReg(hTpEnc, crcReg); @@ -809,7 +795,6 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, return (dseBitsUsed); } - /***************************************************************************** functionname: FDKaacEnc_writeExtensionData @@ -819,18 +804,15 @@ static INT FDKaacEnc_writeDataStreamElement( HANDLE_TRANSPORTENC hTpEnc, output: *****************************************************************************/ -INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, - QC_OUT_EXTENSION *pExtension, - INT elInstanceTag, /* for DSE only */ - UINT alignAnchor, /* for DSE only */ - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig - ) -{ - #define FILL_EL_COUNT_BITS ( 4 ) - #define FILL_EL_ESC_COUNT_BITS ( 8 ) - #define MAX_FILL_DATA_BYTES ( 269 ) +INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc, + QC_OUT_EXTENSION *pExtension, + INT elInstanceTag, /* for DSE only */ + UINT alignAnchor, /* for DSE only */ + UINT syntaxFlags, AUDIO_OBJECT_TYPE aot, + SCHAR epConfig) { +#define FILL_EL_COUNT_BITS (4) +#define FILL_EL_ESC_COUNT_BITS (8) +#define MAX_FILL_DATA_BYTES (269) HANDLE_FDK_BITSTREAM hBitStream = NULL; INT payloadBits = pExtension->nPayloadBits; @@ -840,106 +822,53 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, hBitStream = transportEnc_GetBitstream(hTpEnc); } - if (syntaxFlags & (AC_SCALABLE|AC_ER)) - { - if ( syntaxFlags & AC_DRM ) - { /* CAUTION: The caller has to assure that fill - data is written before the SBR payload. */ - UCHAR *extPayloadData = pExtension->pPayload; - - switch (pExtension->type) - { - case EXT_SBR_DATA: - case EXT_SBR_DATA_CRC: - /* SBR payload is written in reverse */ - if (hBitStream != NULL) { - int i, writeBits = payloadBits; - - FDKpushFor(hBitStream, payloadBits-1); /* Does a cache sync internally */ - - for (i=0; writeBits >= 8; i++) { - FDKwriteBitsBwd(hBitStream, extPayloadData[i], 8); - writeBits -= 8; - } - if (writeBits > 0) { - FDKwriteBitsBwd(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); - } - - FDKsyncCacheBwd (hBitStream); - FDKpushFor (hBitStream, payloadBits+1); - } - extBitsUsed += payloadBits; - break; - - case EXT_FILL_DATA: - case EXT_FIL: - default: - if (hBitStream != NULL) { - int writeBits = payloadBits; - while (writeBits >= 8) { - FDKwriteBits(hBitStream, 0x00, 8); - writeBits -= 8; - } - FDKwriteBits(hBitStream, 0x00, writeBits); - } - extBitsUsed += payloadBits; - break; - } - } - else { - if ( (syntaxFlags & AC_ELD) && ((pExtension->type==EXT_SBR_DATA) || (pExtension->type==EXT_SBR_DATA_CRC)) ) { - + if (syntaxFlags & (AC_SCALABLE | AC_ER)) { + { + if ((syntaxFlags & AC_ELD) && ((pExtension->type == EXT_SBR_DATA) || + (pExtension->type == EXT_SBR_DATA_CRC))) { if (hBitStream != NULL) { int i, writeBits = payloadBits; UCHAR *extPayloadData = pExtension->pPayload; - for (i=0; writeBits >= 8; i++) { + for (i = 0; writeBits >= 8; i++) { FDKwriteBits(hBitStream, extPayloadData[i], 8); writeBits -= 8; } if (writeBits > 0) { - FDKwriteBits(hBitStream, extPayloadData[i]>>(8-writeBits), writeBits); + FDKwriteBits(hBitStream, extPayloadData[i] >> (8 - writeBits), + writeBits); } } extBitsUsed += payloadBits; - } - else - { + } else { /* ER or scalable syntax -> write extension en bloc */ - extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream, - pExtension->type, - pExtension->pPayload, - payloadBits ); + extBitsUsed += FDKaacEnc_writeExtensionPayload( + hBitStream, pExtension->type, pExtension->pPayload, payloadBits); } } - } - else { + } else { /* We have normal GA bitstream payload (AOT 2,5,29) so pack the data into a fill elements or DSEs */ - if ( pExtension->type == EXT_DATA_ELEMENT ) - { - extBitsUsed += FDKaacEnc_writeDataStreamElement( hTpEnc, - elInstanceTag, - pExtension->nPayloadBits>>3, - pExtension->pPayload, - alignAnchor ); - } - else { + if (pExtension->type == EXT_DATA_ELEMENT) { + extBitsUsed += FDKaacEnc_writeDataStreamElement( + hTpEnc, elInstanceTag, pExtension->nPayloadBits >> 3, + pExtension->pPayload, alignAnchor); + } else { while (payloadBits >= (EL_ID_BITS + FILL_EL_COUNT_BITS)) { - INT cnt, esc_count=-1, alignBits=7; + INT cnt, esc_count = -1, alignBits = 7; - if ( (pExtension->type == EXT_FILL_DATA) || (pExtension->type == EXT_FIL) ) - { + if ((pExtension->type == EXT_FILL_DATA) || + (pExtension->type == EXT_FIL)) { payloadBits -= EL_ID_BITS + FILL_EL_COUNT_BITS; - if (payloadBits >= 15*8) { + if (payloadBits >= 15 * 8) { payloadBits -= FILL_EL_ESC_COUNT_BITS; - esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */ + esc_count = 0; /* write esc_count even if cnt becomes smaller 15 */ } alignBits = 0; } - cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits+alignBits)>>3); + cnt = fixMin(MAX_FILL_DATA_BYTES, (payloadBits + alignBits) >> 3); if (cnt >= 15) { esc_count = cnt - 15 + 1; @@ -956,13 +885,12 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, } } - extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + ((esc_count>=0) ? FILL_EL_ESC_COUNT_BITS : 0); + extBitsUsed += EL_ID_BITS + FILL_EL_COUNT_BITS + + ((esc_count >= 0) ? FILL_EL_ESC_COUNT_BITS : 0); - cnt = fixMin(cnt*8, payloadBits); /* convert back to bits */ - extBitsUsed += FDKaacEnc_writeExtensionPayload( hBitStream, - pExtension->type, - pExtension->pPayload, - cnt ); + cnt = fixMin(cnt * 8, payloadBits); /* convert back to bits */ + extBitsUsed += FDKaacEnc_writeExtensionPayload( + hBitStream, pExtension->type, pExtension->pPayload, cnt); payloadBits -= cnt; } } @@ -971,7 +899,6 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, return (extBitsUsed); } - /***************************************************************************** functionname: FDKaacEnc_ByteAlignment @@ -981,50 +908,43 @@ INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, output: *****************************************************************************/ -static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, int alignBits) -{ +static void FDKaacEnc_ByteAlignment(HANDLE_FDK_BITSTREAM hBitStream, + int alignBits) { FDKwriteBits(hBitStream, 0, alignBits); } -AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, - ELEMENT_INFO *pElInfo, - QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_ELEMENT *psyOutElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig, - INT *pBitDemand, - UCHAR minCnt - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( + HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo, + QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags, + AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt) { AAC_ENCODER_ERROR error = AAC_ENC_OK; HANDLE_FDK_BITSTREAM hBitStream = NULL; - INT bitDemand = 0; - const element_list_t *list; - int i, ch, decision_bit; - INT crcReg1 = -1, crcReg2 = -1; - UCHAR numberOfChannels; + INT bitDemand = 0; + const element_list_t *list; + int i, ch, decision_bit; + INT crcReg1 = -1, crcReg2 = -1; + UCHAR numberOfChannels; if (hTpEnc != NULL) { /* Get bitstream handle */ hBitStream = transportEnc_GetBitstream(hTpEnc); } - if ( (pElInfo->elType==ID_SCE) || (pElInfo->elType==ID_LFE) ) { + if ((pElInfo->elType == ID_SCE) || (pElInfo->elType == ID_LFE)) { numberOfChannels = 1; } else { numberOfChannels = 2; } /* Get channel element sequence table */ - list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0); + list = getBitstreamElementList(aot, epConfig, numberOfChannels, 0, 0); if (list == NULL) { error = AAC_ENC_UNSUPPORTED_AOT; goto bail; } - if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) { + if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) { if (hBitStream != NULL) { FDKwriteBits(hBitStream, pElInfo->elType, EL_ID_BITS); } @@ -1038,225 +958,205 @@ AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, do { /* some tmp values */ SECTION_DATA *pChSectionData = NULL; - INT *pChScf = NULL; + INT *pChScf = NULL; UINT *pChMaxValueInSfb = NULL; - TNS_INFO *pTnsInfo = NULL; - INT chGlobalGain = 0; - INT chBlockType = 0; - INT chMaxSfbPerGrp = 0; - INT chSfbPerGrp = 0; - INT chSfbCnt = 0; - INT chFirstScf = 0; - - if (minCnt==0) { - if ( qcOutChannel!=NULL ) { - pChSectionData = &(qcOutChannel[ch]->sectionData); - pChScf = qcOutChannel[ch]->scf; - chGlobalGain = qcOutChannel[ch]->globalGain; - pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb; - chBlockType = pChSectionData->blockType; - chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup; - chSfbPerGrp = pChSectionData->sfbPerGroup; - chSfbCnt = pChSectionData->sfbCnt; - chFirstScf = pChScf[pChSectionData->firstScf]; - } - else { + TNS_INFO *pTnsInfo = NULL; + INT chGlobalGain = 0; + INT chBlockType = 0; + INT chMaxSfbPerGrp = 0; + INT chSfbPerGrp = 0; + INT chSfbCnt = 0; + INT chFirstScf = 0; + + if (minCnt == 0) { + if (qcOutChannel != NULL) { + pChSectionData = &(qcOutChannel[ch]->sectionData); + pChScf = qcOutChannel[ch]->scf; + chGlobalGain = qcOutChannel[ch]->globalGain; + pChMaxValueInSfb = qcOutChannel[ch]->maxValueInSfb; + chBlockType = pChSectionData->blockType; + chMaxSfbPerGrp = pChSectionData->maxSfbPerGroup; + chSfbPerGrp = pChSectionData->sfbPerGroup; + chSfbCnt = pChSectionData->sfbCnt; + chFirstScf = pChScf[pChSectionData->firstScf]; + } else { /* get values from PSY */ - chSfbCnt = psyOutChannel[ch]->sfbCnt; - chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup; + chSfbCnt = psyOutChannel[ch]->sfbCnt; + chSfbPerGrp = psyOutChannel[ch]->sfbPerGroup; chMaxSfbPerGrp = psyOutChannel[ch]->maxSfbPerGroup; } pTnsInfo = &psyOutChannel[ch]->tnsInfo; } /* minCnt==0 */ - if ( qcOutChannel==NULL ) { - chBlockType = psyOutChannel[ch]->lastWindowSequence; + if (qcOutChannel == NULL) { + chBlockType = psyOutChannel[ch]->lastWindowSequence; } - switch (list->id[i]) - { - case element_instance_tag: - /* Write element instance tag */ - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, pElInfo->instanceTag, 4); - } - bitDemand += 4; - break; - - case common_window: - /* Write common window flag */ - decision_bit = psyOutElement->commonWindow; - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1); - } - bitDemand += 1; - break; - - case ics_info: - /* Write individual channel info */ - bitDemand += FDKaacEnc_encodeIcsInfo( chBlockType, - psyOutChannel[ch]->windowShape, - psyOutChannel[ch]->groupingMask, - chMaxSfbPerGrp, - hBitStream, - syntaxFlags); - break; - - case ltp_data_present: - /* Write LTP data present flag */ - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, 0, 1); - } - bitDemand += 1; - break; - - case ltp_data: - /* Predictor data not supported. - Nothing to do here. */ - break; - - case ms: - /* Write MS info */ - bitDemand += FDKaacEnc_encodeMSInfo( chSfbCnt, - chSfbPerGrp, - chMaxSfbPerGrp, - (minCnt==0) ? psyOutElement->toolsInfo.msDigest : MS_NONE, - psyOutElement->toolsInfo.msMask, - hBitStream); - break; - - case global_gain: - bitDemand += FDKaacEnc_encodeGlobalGain( chGlobalGain, - chFirstScf, - hBitStream, - psyOutChannel[ch]->mdctScale ); - break; - - case section_data: - { - INT siBits = FDKaacEnc_encodeSectionData(pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11)?1:0); + switch (list->id[i]) { + case element_instance_tag: + /* Write element instance tag */ + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, pElInfo->instanceTag, 4); + } + bitDemand += 4; + break; + + case common_window: + /* Write common window flag */ + decision_bit = psyOutElement->commonWindow; + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, psyOutElement->commonWindow, 1); + } + bitDemand += 1; + break; + + case ics_info: + /* Write individual channel info */ + bitDemand += + FDKaacEnc_encodeIcsInfo(chBlockType, psyOutChannel[ch]->windowShape, + psyOutChannel[ch]->groupingMask, + chMaxSfbPerGrp, hBitStream, syntaxFlags); + break; + + case ltp_data_present: + /* Write LTP data present flag */ + if (hBitStream != NULL) { + FDKwriteBits(hBitStream, 0, 1); + } + bitDemand += 1; + break; + + case ltp_data: + /* Predictor data not supported. + Nothing to do here. */ + break; + + case ms: + /* Write MS info */ + bitDemand += FDKaacEnc_encodeMSInfo( + chSfbCnt, chSfbPerGrp, chMaxSfbPerGrp, + (minCnt == 0) ? psyOutElement->toolsInfo.msDigest : MS_NONE, + psyOutElement->toolsInfo.msMask, hBitStream); + break; + + case global_gain: + bitDemand += FDKaacEnc_encodeGlobalGain( + chGlobalGain, chFirstScf, hBitStream, psyOutChannel[ch]->mdctScale); + break; + + case section_data: { + INT siBits = FDKaacEnc_encodeSectionData( + pChSectionData, hBitStream, (syntaxFlags & AC_ER_VCB11) ? 1 : 0); if (hBitStream != NULL) { if (siBits != qcOutChannel[ch]->sectionData.sideInfoBits) { error = AAC_ENC_WRITE_SEC_ERROR; } } bitDemand += siBits; - } - break; - - case scale_factor_data: - { - INT sfDataBits = FDKaacEnc_encodeScaleFactorData( pChMaxValueInSfb, - pChSectionData, - pChScf, - hBitStream, - psyOutChannel[ch]->noiseNrg, - psyOutChannel[ch]->isScale, - chGlobalGain ); - if ( (hBitStream != NULL) - && (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + qcOutChannel[ch]->sectionData.noiseNrgBits)) ) { - error = AAC_ENC_WRITE_SCAL_ERROR; + } break; + + case scale_factor_data: { + INT sfDataBits = FDKaacEnc_encodeScaleFactorData( + pChMaxValueInSfb, pChSectionData, pChScf, hBitStream, + psyOutChannel[ch]->noiseNrg, psyOutChannel[ch]->isScale, + chGlobalGain); + if ((hBitStream != NULL) && + (sfDataBits != (qcOutChannel[ch]->sectionData.scalefacBits + + qcOutChannel[ch]->sectionData.noiseNrgBits))) { + error = AAC_ENC_WRITE_SCAL_ERROR; } bitDemand += sfDataBits; - } - break; + } break; - case esc2_rvlc: - if (syntaxFlags & AC_ER_RVLC) { - /* write RVLC data into bitstream (error sens. cat. 2) */ - error = AAC_ENC_UNSUPPORTED_AOT; - } - break; - - case pulse: - /* Write pulse data */ - bitDemand += FDKaacEnc_encodePulseData(hBitStream); - break; - - case tns_data_present: - /* Write TNS data present flag */ - bitDemand += FDKaacEnc_encodeTnsDataPresent(pTnsInfo, - chBlockType, - hBitStream); - break; - case tns_data: - /* Write TNS data */ - bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, - chBlockType, - hBitStream); - break; - - case gain_control_data: - /* Nothing to do here */ - break; - - case gain_control_data_present: - bitDemand += FDKaacEnc_encodeGainControlData(hBitStream); - break; - - - case esc1_hcr: - if (syntaxFlags & AC_ER_HCR) - { - error = AAC_ENC_UNKNOWN; - } - break; + case esc2_rvlc: + if (syntaxFlags & AC_ER_RVLC) { + /* write RVLC data into bitstream (error sens. cat. 2) */ + error = AAC_ENC_UNSUPPORTED_AOT; + } + break; - case spectral_data: - if (hBitStream != NULL) - { - INT spectralBits = 0; + case pulse: + /* Write pulse data */ + bitDemand += FDKaacEnc_encodePulseData(hBitStream); + break; + + case tns_data_present: + /* Write TNS data present flag */ + bitDemand += + FDKaacEnc_encodeTnsDataPresent(pTnsInfo, chBlockType, hBitStream); + break; + case tns_data: + /* Write TNS data */ + bitDemand += FDKaacEnc_encodeTnsData(pTnsInfo, chBlockType, hBitStream); + break; + + case gain_control_data: + /* Nothing to do here */ + break; - spectralBits = FDKaacEnc_encodeSpectralData( psyOutChannel[ch]->sfbOffsets, - pChSectionData, - qcOutChannel[ch]->quantSpec, - hBitStream ); + case gain_control_data_present: + bitDemand += FDKaacEnc_encodeGainControlData(hBitStream); + break; - if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) { - return AAC_ENC_WRITE_SPEC_ERROR; + case esc1_hcr: + if (syntaxFlags & AC_ER_HCR) { + error = AAC_ENC_UNKNOWN; } - bitDemand += spectralBits; - } - break; + break; - /* Non data cases */ - case adtscrc_start_reg1: - if (hTpEnc != NULL) { - crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192); - } - break; - case adtscrc_start_reg2: - if (hTpEnc != NULL) { - crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128); - } - break; - case adtscrc_end_reg1: - case drmcrc_end_reg: - if (hTpEnc != NULL) { - transportEnc_CrcEndReg(hTpEnc, crcReg1); - } - break; - case adtscrc_end_reg2: - if (hTpEnc != NULL) { - transportEnc_CrcEndReg(hTpEnc, crcReg2); - } - break; - case drmcrc_start_reg: - if (hTpEnc != NULL) { - crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0); - } - break; - case next_channel: - ch = (ch + 1) % numberOfChannels; - break; - case link_sequence: - list = list->next[decision_bit]; - i=-1; - break; - - default: - error = AAC_ENC_UNKNOWN; - break; + case spectral_data: + if (hBitStream != NULL) { + INT spectralBits = 0; + + spectralBits = FDKaacEnc_encodeSpectralData( + psyOutChannel[ch]->sfbOffsets, pChSectionData, + qcOutChannel[ch]->quantSpec, hBitStream); + + if (spectralBits != qcOutChannel[ch]->sectionData.huffmanBits) { + return AAC_ENC_WRITE_SPEC_ERROR; + } + bitDemand += spectralBits; + } + break; + + /* Non data cases */ + case adtscrc_start_reg1: + if (hTpEnc != NULL) { + crcReg1 = transportEnc_CrcStartReg(hTpEnc, 192); + } + break; + case adtscrc_start_reg2: + if (hTpEnc != NULL) { + crcReg2 = transportEnc_CrcStartReg(hTpEnc, 128); + } + break; + case adtscrc_end_reg1: + case drmcrc_end_reg: + if (hTpEnc != NULL) { + transportEnc_CrcEndReg(hTpEnc, crcReg1); + } + break; + case adtscrc_end_reg2: + if (hTpEnc != NULL) { + transportEnc_CrcEndReg(hTpEnc, crcReg2); + } + break; + case drmcrc_start_reg: + if (hTpEnc != NULL) { + crcReg1 = transportEnc_CrcStartReg(hTpEnc, 0); + } + break; + case next_channel: + ch = (ch + 1) % numberOfChannels; + break; + case link_sequence: + list = list->next[decision_bit]; + i = -1; + break; + + default: + error = AAC_ENC_UNKNOWN; + break; } if (error != AAC_ENC_OK) { @@ -1275,24 +1175,19 @@ bail: return error; } - //----------------------------------------------------------------------------------------------- AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, CHANNEL_MAPPING *channelMapping, - QC_OUT *qcOut, - PSY_OUT* psyOut, + QC_OUT *qcOut, PSY_OUT *psyOut, QC_STATE *qcKernel, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ + AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { HANDLE_FDK_BITSTREAM hBs = transportEnc_GetBitstream(hTpEnc); AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - int i, n, doByteAlign = 1; - INT bitMarkUp; - INT frameBits; + int i, n, doByteAlign = 1; + INT bitMarkUp; + INT frameBits; /* Get first bit of raw data block. In case of ADTS+PCE, AU would start at PCE. This is okay because PCE assures alignment. */ @@ -1300,160 +1195,112 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, frameBits = bitMarkUp = alignAnchor; - /* Channel element loop */ - for (i=0; i<channelMapping->nElements; i++) { - + for (i = 0; i < channelMapping->nElements; i++) { ELEMENT_INFO elInfo = channelMapping->elInfo[i]; INT elementUsedBits = 0; - switch (elInfo.elType) - { - case ID_SCE: /* single channel */ - case ID_CPE: /* channel pair */ - case ID_LFE: /* low freq effects channel */ - { - if ( AAC_ENC_OK != (ErrorStatus = FDKaacEnc_ChannelElementWrite( hTpEnc, - &elInfo, - qcOut->qcElement[i]->qcOutChannel, - psyOut->psyOutElement[i], - psyOut->psyOutElement[i]->psyOutChannel, - syntaxFlags, /* syntaxFlags (ER tools ...) */ - aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */ - epConfig, /* epConfig -1, 0, 1 */ - NULL, - 0 )) ) - { - return ErrorStatus; - } + switch (elInfo.elType) { + case ID_SCE: /* single channel */ + case ID_CPE: /* channel pair */ + case ID_LFE: /* low freq effects channel */ + { + if (AAC_ENC_OK != + (ErrorStatus = FDKaacEnc_ChannelElementWrite( + hTpEnc, &elInfo, qcOut->qcElement[i]->qcOutChannel, + psyOut->psyOutElement[i], + psyOut->psyOutElement[i]->psyOutChannel, + syntaxFlags, /* syntaxFlags (ER tools ...) */ + aot, /* aot: AOT_AAC_LC, AOT_SBR, AOT_PS */ + epConfig, /* epConfig -1, 0, 1 */ + NULL, 0))) { + return ErrorStatus; + } - if ( !(syntaxFlags & AC_ER) ) - { - /* Write associated extension payload */ - for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); - } + if (!(syntaxFlags & AC_ER)) { + /* Write associated extension payload */ + for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { + FDKaacEnc_writeExtensionData( + hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); } } - break; + } break; - /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */ - default: - return AAC_ENC_INVALID_ELEMENTINFO_TYPE; + /* In FDK, DSE signalling explicit done in elDSE. See channel_map.cpp */ + default: + return AAC_ENC_INVALID_ELEMENTINFO_TYPE; - } /* switch */ + } /* switch */ - if(elInfo.elType != ID_DSE) { + if (elInfo.elType != ID_DSE) { elementUsedBits -= bitMarkUp; - bitMarkUp = FDKgetValidBits(hBs); + bitMarkUp = FDKgetValidBits(hBs); elementUsedBits += bitMarkUp; - frameBits += elementUsedBits; + frameBits += elementUsedBits; } } /* for (i=0; i<channelMapping.nElements; i++) */ - if ( (syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM) ) - { - UCHAR channelElementExtensionWritten[(8)][(1)]; /* 0: extension not touched, 1: extension already written */ + if ((syntaxFlags & AC_ER) && !(syntaxFlags & AC_DRM)) { + UCHAR channelElementExtensionWritten[((8))][( + 1)]; /* 0: extension not touched, 1: extension already written */ - FDKmemclear(channelElementExtensionWritten, sizeof(channelElementExtensionWritten)); + FDKmemclear(channelElementExtensionWritten, + sizeof(channelElementExtensionWritten)); - if ( syntaxFlags & AC_ELD ) { - - for (i=0; i<channelMapping->nElements; i++) { + if (syntaxFlags & AC_ELD) { + for (i = 0; i < channelMapping->nElements; i++) { for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - - if ( (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA) - || (qcOut->qcElement[i]->extension[n].type==EXT_SBR_DATA_CRC) ) - { + if ((qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA) || + (qcOut->qcElement[i]->extension[n].type == EXT_SBR_DATA_CRC)) { /* Write sbr extension payload */ - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); + FDKaacEnc_writeExtensionData( + hTpEnc, &qcOut->qcElement[i]->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); channelElementExtensionWritten[i][n] = 1; } /* SBR */ - } /* n */ - } /* i */ - } /* AC_ELD */ + } /* n */ + } /* i */ + } /* AC_ELD */ - for (i=0; i<channelMapping->nElements; i++) { + for (i = 0; i < channelMapping->nElements; i++) { for (n = 0; n < qcOut->qcElement[i]->nExtensions; n++) { - - if (channelElementExtensionWritten[i][n]==0) - { + if (channelElementExtensionWritten[i][n] == 0) { /* Write all ramaining extension payloads in element */ - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->qcElement[i]->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); + FDKaacEnc_writeExtensionData(hTpEnc, + &qcOut->qcElement[i]->extension[n], 0, + alignAnchor, syntaxFlags, aot, epConfig); } } /* n */ - } /* i */ - } /* if AC_ER */ + } /* i */ + } /* if AC_ER */ /* Extend global extension payload table with fill bits */ - if ( syntaxFlags & AC_DRM ) - { - /* Exception for Drm */ - for (n = 0; n < qcOut->nExtensions; n++) { - if ( (qcOut->extension[n].type == EXT_SBR_DATA) - || (qcOut->extension[n].type == EXT_SBR_DATA_CRC) ) { - /* SBR data must be the last extension! */ - FDKmemcpy(&qcOut->extension[qcOut->nExtensions], &qcOut->extension[n], sizeof(QC_OUT_EXTENSION)); - break; - } - } - /* Do byte alignment after AAC (+ MPS) payload. - Assure that MPS has been written as channel assigned extension payload! */ - if (((FDKgetValidBits(hBs)-alignAnchor+(UINT)qcOut->totFillBits)&0x7)!=(UINT)qcOut->alignBits) { - return AAC_ENC_WRITTEN_BITS_ERROR; - } - FDKaacEnc_ByteAlignment(hBs, qcOut->alignBits); - doByteAlign = 0; - - } /* AC_DRM */ + n = qcOut->nExtensions; /* Add fill data / stuffing bits */ - n = qcOut->nExtensions; qcOut->extension[n].type = EXT_FILL_DATA; qcOut->extension[n].nPayloadBits = qcOut->totFillBits; qcOut->nExtensions++; /* Write global extension payload and fill data */ - for (n = 0; (n < qcOut->nExtensions) && (n < (2+2)); n++) - { - FDKaacEnc_writeExtensionData( hTpEnc, - &qcOut->extension[n], - 0, - alignAnchor, - syntaxFlags, - aot, - epConfig ); - - /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here */ + for (n = 0; (n < qcOut->nExtensions) && (n < (2 + 2)); n++) { + FDKaacEnc_writeExtensionData(hTpEnc, &qcOut->extension[n], 0, alignAnchor, + syntaxFlags, aot, epConfig); + + /* For EXT_FIL or EXT_FILL_DATA we could do an additional sanity check here + */ } - if (!(syntaxFlags & (AC_SCALABLE|AC_ER))) { + if (!(syntaxFlags & (AC_SCALABLE | AC_ER))) { FDKwriteBits(hBs, ID_END, EL_ID_BITS); } if (doByteAlign) { /* Assure byte alignment*/ - if (((alignAnchor-FDKgetValidBits(hBs))&0x7)!=(UINT)qcOut->alignBits) { + if (((FDKgetValidBits(hBs) - alignAnchor + qcOut->alignBits) & 0x7) != 0) { return AAC_ENC_WRITTEN_BITS_ERROR; } @@ -1465,10 +1312,9 @@ AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, transportEnc_EndAccessUnit(hTpEnc, &frameBits); - if (frameBits != qcOut->totalBits + qcKernel->globHdrBits){ + if (frameBits != qcOut->totalBits + qcKernel->globHdrBits) { return AAC_ENC_WRITTEN_BITS_ERROR; } return ErrorStatus; } - diff --git a/libAACenc/src/bitenc.h b/libAACenc/src/bitenc.h index 498be7c..75dc068 100644 --- a/libAACenc/src/bitenc.h +++ b/libAACenc/src/bitenc.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,74 +90,70 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Bitstream encoder + Author(s): M. Werner -******************************************************************************/ + Description: Bitstream encoder -#ifndef _BITENC_H -#define _BITENC_H +*******************************************************************************/ +#ifndef BITENC_H +#define BITENC_H #include "qc_data.h" #include "aacenc_tns.h" #include "channel_map.h" -#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */ +#include "interface.h" /* obsolete, when PSY_OUT is thrown out of the WritBS-call! */ #include "FDK_audio.h" #include "aacenc.h" #include "tpenc_lib.h" -typedef enum{ - MAX_ENCODER_CHANNELS = 9, - MAX_BLOCK_TYPES = 4, - MAX_AAC_LAYERS = 9, - MAX_LAYERS = MAX_AAC_LAYERS , /* only one core layer if present */ - FIRST_LAY = 1 /* default layer number for AAC nonscalable */ +typedef enum { + MAX_ENCODER_CHANNELS = 9, + MAX_BLOCK_TYPES = 4, + MAX_AAC_LAYERS = 9, + MAX_LAYERS = MAX_AAC_LAYERS, /* only one core layer if present */ + FIRST_LAY = 1 /* default layer number for AAC nonscalable */ } _MAX_CONST; -#define BUFFER_MX_HUFFCB_SIZE (32*sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */ - -#define EL_ID_BITS ( 3 ) +#define BUFFER_MX_HUFFCB_SIZE \ + (32 * sizeof(INT)) /* our FDK_bitbuffer needs size of power 2 */ +#define EL_ID_BITS (3) /** - * \brief Arbitrary order bitstream writer. This function can either assemble a bit stream - * and write into the bit buffer of hTpEnc or calculate the number of static bits (signal independent) - * TpEnc handle must be NULL in this case. Or also Calculate the minimum possible number of - * static bits which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt parameter - * has to be 1 in this latter case. - * \param hTpEnc Transport encoder handle. If NULL, the number of static bits will be returned into - * *pBitDemand. + * \brief Arbitrary order bitstream writer. This function can either assemble a + * bit stream and write into the bit buffer of hTpEnc or calculate the number of + * static bits (signal independent) TpEnc handle must be NULL in this + * case. Or also Calculate the minimum possible number of static bits + * which by disabling all tools e.g. MS, TNS and sbfCnt=0. The minCnt + * parameter has to be 1 in this latter case. + * \param hTpEnc Transport encoder handle. If NULL, the number of static bits + * will be returned into *pBitDemand. * \param pElInfo * \param qcOutChannel * \param hReorderInfo * \param psyOutElement * \param psyOutChannel - * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio Codec flags). + * \param syntaxFlags Bit stream syntax flags as defined in FDK_audio.h (Audio + * Codec flags). * \param aot * \param epConfig - * \param pBitDemand Pointer to an int where the amount of bits is returned into. The returned value - * depends on if hTpEnc is NULL and minCnt. - * \param minCnt If non-zero the value returned into *pBitDemand is the absolute minimum required amount of - * static bits in order to write a valid bit stream. + * \param pBitDemand Pointer to an int where the amount of bits is returned + * into. The returned value depends on if hTpEnc is NULL and minCnt. + * \param minCnt If non-zero the value returned into *pBitDemand is the absolute + * minimum required amount of static bits in order to write a valid bit stream. * \return AAC_ENCODER_ERROR error code */ -AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, - ELEMENT_INFO *pElInfo, - QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_ELEMENT *psyOutElement, - PSY_OUT_CHANNEL *psyOutChannel[(2)], - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig, - INT *pBitDemand, - UCHAR minCnt - ); +AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( + HANDLE_TRANSPORTENC hTpEnc, ELEMENT_INFO *pElInfo, + QC_OUT_CHANNEL *qcOutChannel[(2)], PSY_OUT_ELEMENT *psyOutElement, + PSY_OUT_CHANNEL *psyOutChannel[(2)], UINT syntaxFlags, + AUDIO_OBJECT_TYPE aot, SCHAR epConfig, INT *pBitDemand, UCHAR minCnt); /** * \brief Write bit stream or account static bits * \param hTpEnc transport encoder handle. If NULL, the function will @@ -161,23 +168,17 @@ AAC_ENCODER_ERROR FDKaacEnc_ChannelElementWrite( HANDLE_TRANSPORTENC hTpEnc, * \param syntaxFlags Flags indicating format specific detail * \param epConfig Error protection config */ -AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream (HANDLE_TRANSPORTENC hTpEnc, - CHANNEL_MAPPING *channelMapping, - QC_OUT* qcOut, - PSY_OUT* psyOut, - QC_STATE* qcKernel, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - -INT FDKaacEnc_writeExtensionData( HANDLE_TRANSPORTENC hTpEnc, - QC_OUT_EXTENSION *pExtension, - INT elInstanceTag, - UINT alignAnchor, - UINT syntaxFlags, - AUDIO_OBJECT_TYPE aot, - SCHAR epConfig - ); - -#endif /* _BITENC_H */ +AAC_ENCODER_ERROR FDKaacEnc_WriteBitstream(HANDLE_TRANSPORTENC hTpEnc, + CHANNEL_MAPPING *channelMapping, + QC_OUT *qcOut, PSY_OUT *psyOut, + QC_STATE *qcKernel, + AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); + +INT FDKaacEnc_writeExtensionData(HANDLE_TRANSPORTENC hTpEnc, + QC_OUT_EXTENSION *pExtension, + INT elInstanceTag, UINT alignAnchor, + UINT syntaxFlags, AUDIO_OBJECT_TYPE aot, + SCHAR epConfig); + +#endif /* BITENC_H */ diff --git a/libAACenc/src/block_switch.cpp b/libAACenc/src/block_switch.cpp index 7b3e275..c132253 100644 --- a/libAACenc/src/block_switch.cpp +++ b/libAACenc/src/block_switch.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,460 +90,488 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner, Tobias Chalupka + Description: Block switching -******************************************************************************/ +*******************************************************************************/ /****************** Includes *****************************/ #include "block_switch.h" #include "genericStds.h" - #define LOWOV_WINDOW _LOWOV_WINDOW /**************** internal function prototypes ***********/ -static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], const INT blSwWndIdx); +static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], + const INT blSwWndIdx); static void FDKaacEnc_CalcWindowEnergy( - BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, - INT windowLen, - const INT_PCM *pTimeSignal - ); + BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, + const INT_PCM *pTimeSignal); /****************** Constants *****************************/ -/* LONG START SHORT STOP LOWOV */ -static const INT blockType2windowShape[2][5] = { {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */ - {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW} }; /* LC */ +/* LONG START + * SHORT STOP LOWOV */ +static const INT blockType2windowShape[2][5] = { + {SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW, SINE_WINDOW, KBD_WINDOW}, /* LD */ + {KBD_WINDOW, SINE_WINDOW, SINE_WINDOW, KBD_WINDOW, WRONG_WINDOW}}; /* LC */ /* IIR high pass coeffs */ #ifndef SINETABLE_16BIT -static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN]= -{ - FL2FXCONST_DBL(-0.5095),FL2FXCONST_DBL(0.7548) -}; +static const FIXP_DBL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = { + FL2FXCONST_DBL(-0.5095), FL2FXCONST_DBL(0.7548)}; -static const FIXP_DBL accWindowNrgFac = FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ +static const FIXP_DBL accWindowNrgFac = + FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ static const FIXP_DBL oneMinusAccWindowNrgFac = FL2FXCONST_DBL(0.7f); -/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ -static const FIXP_DBL invAttackRatio = FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */ +/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ +static const FIXP_DBL invAttackRatio = + FL2FXCONST_DBL(0.1f); /* inverted lower ratio limit for attacks */ -/* The next constants are scaled, because they are used for comparison with scaled values*/ +/* The next constants are scaled, because they are used for comparison with + * scaled values*/ /* minimum energy for attacks */ -static const FIXP_DBL minAttackNrg = (FL2FXCONST_DBL(1e+6f*NORM_PCM_ENERGY)>>BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ +static const FIXP_DBL minAttackNrg = + (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >> + BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ #else -static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN]= -{ - FL2FXCONST_SGL(-0.5095),FL2FXCONST_SGL(0.7548) -}; +static const FIXP_SGL hiPassCoeff[BLOCK_SWITCHING_IIR_LEN] = { + FL2FXCONST_SGL(-0.5095), FL2FXCONST_SGL(0.7548)}; -static const FIXP_DBL accWindowNrgFac = FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ +static const FIXP_DBL accWindowNrgFac = + FL2FXCONST_DBL(0.3f); /* factor for accumulating filtered window energies */ static const FIXP_SGL oneMinusAccWindowNrgFac = FL2FXCONST_SGL(0.7f); -/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ -static const FIXP_SGL invAttackRatio = FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */ +/* static const float attackRatio = 10.0; */ /* lower ratio limit for attacks */ +static const FIXP_SGL invAttackRatio = + FL2FXCONST_SGL(0.1f); /* inverted lower ratio limit for attacks */ /* minimum energy for attacks */ -static const FIXP_DBL minAttackNrg = (FL2FXCONST_DBL(1e+6f*NORM_PCM_ENERGY)>>BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ +static const FIXP_DBL minAttackNrg = + (FL2FXCONST_DBL(1e+6f * NORM_PCM_ENERGY) >> + BLOCK_SWITCH_ENERGY_SHIFT); /* minimum energy for attacks */ #endif /**************** internal function prototypes ***********/ /****************** Routines ****************************/ -void FDKaacEnc_InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) -{ - FDKmemclear (blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL)); +void FDKaacEnc_InitBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay) { + FDKmemclear(blockSwitchingControl, sizeof(BLOCK_SWITCHING_CONTROL)); - if (isLowDelay) - { + if (isLowDelay) { blockSwitchingControl->nBlockSwitchWindows = 4; - blockSwitchingControl->allowShortFrames = 0; - blockSwitchingControl->allowLookAhead = 0; - } - else - { + blockSwitchingControl->allowShortFrames = 0; + blockSwitchingControl->allowLookAhead = 0; + } else { blockSwitchingControl->nBlockSwitchWindows = 8; - blockSwitchingControl->allowShortFrames = 1; - blockSwitchingControl->allowLookAhead = 1; + blockSwitchingControl->allowShortFrames = 1; + blockSwitchingControl->allowLookAhead = 1; } - blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; + blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; /* Initialize startvalue for blocktype */ - blockSwitchingControl->lastWindowSequence = LONG_WINDOW; - blockSwitchingControl->windowShape = blockType2windowShape[blockSwitchingControl->allowShortFrames][blockSwitchingControl->lastWindowSequence]; - + blockSwitchingControl->lastWindowSequence = LONG_WINDOW; + blockSwitchingControl->windowShape = + blockType2windowShape[blockSwitchingControl->allowShortFrames] + [blockSwitchingControl->lastWindowSequence]; } -static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = -{ - /* Attack in Window 0 */ {1, 3, 3, 1}, - /* Attack in Window 1 */ {1, 1, 3, 3}, - /* Attack in Window 2 */ {2, 1, 3, 2}, - /* Attack in Window 3 */ {3, 1, 3, 1}, - /* Attack in Window 4 */ {3, 1, 1, 3}, - /* Attack in Window 5 */ {3, 2, 1, 2}, - /* Attack in Window 6 */ {3, 3, 1, 1}, - /* Attack in Window 7 */ {3, 3, 1, 1} -}; - -/* change block type depending on current blocktype and whether there's an attack */ +static const INT suggestedGroupingTable[TRANS_FAC][MAX_NO_OF_GROUPS] = { + /* Attack in Window 0 */ {1, 3, 3, 1}, + /* Attack in Window 1 */ {1, 1, 3, 3}, + /* Attack in Window 2 */ {2, 1, 3, 2}, + /* Attack in Window 3 */ {3, 1, 3, 1}, + /* Attack in Window 4 */ {3, 1, 1, 3}, + /* Attack in Window 5 */ {3, 2, 1, 2}, + /* Attack in Window 6 */ {3, 3, 1, 1}, + /* Attack in Window 7 */ {3, 3, 1, 1}}; + +/* change block type depending on current blocktype and whether there's an + * attack */ /* assume no look-ahead */ -static const INT chgWndSq[2][N_BLOCKTYPES] = -{ - /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW, LOWOV_WINDOW, WRONG_WINDOW */ - /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW, STOP_WINDOW , WRONG_WINDOW }, - /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW } -}; - -/* change block type depending on current blocktype and whether there's an attack */ +static const INT chgWndSq[2][N_BLOCKTYPES] = { + /* LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW, + LOWOV_WINDOW, WRONG_WINDOW */ + /*no attack*/ {LONG_WINDOW, STOP_WINDOW, WRONG_WINDOW, LONG_WINDOW, + STOP_WINDOW, WRONG_WINDOW}, + /*attack */ {START_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, START_WINDOW, + LOWOV_WINDOW, WRONG_WINDOW}}; + +/* change block type depending on current blocktype and whether there's an + * attack */ /* assume look-ahead */ -static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = -{ - /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */ - /*no attack*/ { {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW, WRONG_WINDOW}, /* no attack */ - /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, WRONG_WINDOW, WRONG_WINDOW} }, /* no attack */ - /*no attack*/ { {LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW, WRONG_WINDOW, WRONG_WINDOW}, /* attack */ - /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, WRONG_WINDOW, WRONG_WINDOW} } /* attack */ +static const INT chgWndSqLkAhd[2][2][N_BLOCKTYPES] = { + /*attack LONG WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW, WRONG_WINDOW */ /* last attack */ + /*no attack*/ { + {LONG_WINDOW, SHORT_WINDOW, STOP_WINDOW, LONG_WINDOW, WRONG_WINDOW, + WRONG_WINDOW}, /* no attack */ + /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, START_WINDOW, + WRONG_WINDOW, WRONG_WINDOW}}, /* no attack */ + /*no attack*/ {{LONG_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LONG_WINDOW, + WRONG_WINDOW, WRONG_WINDOW}, /* attack */ + /*attack */ {START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, + START_WINDOW, WRONG_WINDOW, + WRONG_WINDOW}} /* attack */ }; -int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, const INT granuleLength, const int isLFE, const INT_PCM *pTimeSignal) -{ - UINT i; - FIXP_DBL enM1, enMax; - - UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows; - - /* for LFE : only LONG window allowed */ - if (isLFE) { - - /* case LFE: */ - /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */ - blockSwitchingControl->lastWindowSequence = LONG_WINDOW; - blockSwitchingControl->windowShape = SINE_WINDOW; - blockSwitchingControl->noOfGroups = 1; - blockSwitchingControl->groupLen[0] = 1; - - return(0); - }; - - /* Save current attack index as last attack index */ - blockSwitchingControl->lastattack = blockSwitchingControl->attack; - blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex; - - /* Save current window energy as last window energy */ - FDKmemcpy(blockSwitchingControl->windowNrg[0], blockSwitchingControl->windowNrg[1], sizeof(blockSwitchingControl->windowNrg[0])); - FDKmemcpy(blockSwitchingControl->windowNrgF[0], blockSwitchingControl->windowNrgF[1], sizeof(blockSwitchingControl->windowNrgF[0])); - - if (blockSwitchingControl->allowShortFrames) - { - /* Calculate suggested grouping info for the last frame */ - - /* Reset grouping info */ - FDKmemclear (blockSwitchingControl->groupLen, sizeof(blockSwitchingControl->groupLen)); - - /* Set grouping info */ - blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; - - FDKmemcpy(blockSwitchingControl->groupLen, suggestedGroupingTable[blockSwitchingControl->lastAttackIndex], sizeof(blockSwitchingControl->groupLen)); - - if (blockSwitchingControl->attack == TRUE) - blockSwitchingControl->maxWindowNrg = FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0], blockSwitchingControl->lastAttackIndex); - else - blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0); - - } - - - /* Calculate unfiltered and filtered energies in subwindows and combine to segments */ - FDKaacEnc_CalcWindowEnergy(blockSwitchingControl, granuleLength>>(nBlockSwitchWindows==4? 2:3 ), pTimeSignal); - - /* now calculate if there is an attack */ - - /* reset attack */ - blockSwitchingControl->attack = FALSE; +int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, + const INT granuleLength, const int isLFE, + const INT_PCM *pTimeSignal) { + UINT i; + FIXP_DBL enM1, enMax; + + UINT nBlockSwitchWindows = blockSwitchingControl->nBlockSwitchWindows; + + /* for LFE : only LONG window allowed */ + if (isLFE) { + /* case LFE: */ + /* only long blocks, always use sine windows (MPEG2 AAC, MPEG4 AAC) */ + blockSwitchingControl->lastWindowSequence = LONG_WINDOW; + blockSwitchingControl->windowShape = SINE_WINDOW; + blockSwitchingControl->noOfGroups = 1; + blockSwitchingControl->groupLen[0] = 1; + + return (0); + }; + + /* Save current attack index as last attack index */ + blockSwitchingControl->lastattack = blockSwitchingControl->attack; + blockSwitchingControl->lastAttackIndex = blockSwitchingControl->attackIndex; + + /* Save current window energy as last window energy */ + FDKmemcpy(blockSwitchingControl->windowNrg[0], + blockSwitchingControl->windowNrg[1], + sizeof(blockSwitchingControl->windowNrg[0])); + FDKmemcpy(blockSwitchingControl->windowNrgF[0], + blockSwitchingControl->windowNrgF[1], + sizeof(blockSwitchingControl->windowNrgF[0])); + + if (blockSwitchingControl->allowShortFrames) { + /* Calculate suggested grouping info for the last frame */ + + /* Reset grouping info */ + FDKmemclear(blockSwitchingControl->groupLen, + sizeof(blockSwitchingControl->groupLen)); + + /* Set grouping info */ + blockSwitchingControl->noOfGroups = MAX_NO_OF_GROUPS; + + FDKmemcpy(blockSwitchingControl->groupLen, + suggestedGroupingTable[blockSwitchingControl->lastAttackIndex], + sizeof(blockSwitchingControl->groupLen)); + + if (blockSwitchingControl->attack == TRUE) + blockSwitchingControl->maxWindowNrg = + FDKaacEnc_GetWindowEnergy(blockSwitchingControl->windowNrg[0], + blockSwitchingControl->lastAttackIndex); + else + blockSwitchingControl->maxWindowNrg = FL2FXCONST_DBL(0.0); + } - /* look for attack */ - enMax = FL2FXCONST_DBL(0.0f); - enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows-1]; + /* Calculate unfiltered and filtered energies in subwindows and combine to + * segments */ + FDKaacEnc_CalcWindowEnergy( + blockSwitchingControl, + granuleLength >> (nBlockSwitchWindows == 4 ? 2 : 3), pTimeSignal); - for (i=0; i<nBlockSwitchWindows; i++) { - FIXP_DBL tmp = fMultDiv2(oneMinusAccWindowNrgFac, blockSwitchingControl->accWindowNrg); - blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1) ; + /* now calculate if there is an attack */ - if (fMult(blockSwitchingControl->windowNrgF[1][i],invAttackRatio) > blockSwitchingControl->accWindowNrg ) { - blockSwitchingControl->attack = TRUE; - blockSwitchingControl->attackIndex = i; - } - enM1 = blockSwitchingControl->windowNrgF[1][i]; - enMax = fixMax(enMax, enM1); - } + /* reset attack */ + blockSwitchingControl->attack = FALSE; + /* look for attack */ + enMax = FL2FXCONST_DBL(0.0f); + enM1 = blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1]; - if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE; + for (i = 0; i < nBlockSwitchWindows; i++) { + FIXP_DBL tmp = + fMultDiv2(oneMinusAccWindowNrgFac, blockSwitchingControl->accWindowNrg); + blockSwitchingControl->accWindowNrg = fMultAdd(tmp, accWindowNrgFac, enM1); - /* Check if attack spreads over frame border */ - if((blockSwitchingControl->attack == FALSE) && (blockSwitchingControl->lastattack == TRUE)) { - /* if attack is in last window repeat SHORT_WINDOW */ - if ( ((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows-1]>>4) > fMult((FIXP_DBL)(10<<(DFRACT_BITS-1-4)), blockSwitchingControl->windowNrgF[1][1])) - && (blockSwitchingControl->lastAttackIndex == (INT)nBlockSwitchWindows-1) - ) - { - blockSwitchingControl->attack = TRUE; - blockSwitchingControl->attackIndex = 0; - } + if (fMult(blockSwitchingControl->windowNrgF[1][i], invAttackRatio) > + blockSwitchingControl->accWindowNrg) { + blockSwitchingControl->attack = TRUE; + blockSwitchingControl->attackIndex = i; } + enM1 = blockSwitchingControl->windowNrgF[1][i]; + enMax = fixMax(enMax, enM1); + } - - if(blockSwitchingControl->allowLookAhead) - { - - - blockSwitchingControl->lastWindowSequence = - chgWndSqLkAhd[blockSwitchingControl->lastattack][blockSwitchingControl->attack][blockSwitchingControl->lastWindowSequence]; - } - else - { - /* Low Delay */ - blockSwitchingControl->lastWindowSequence = - chgWndSq[blockSwitchingControl->attack][blockSwitchingControl->lastWindowSequence]; + if (enMax < minAttackNrg) blockSwitchingControl->attack = FALSE; + + /* Check if attack spreads over frame border */ + if ((blockSwitchingControl->attack == FALSE) && + (blockSwitchingControl->lastattack == TRUE)) { + /* if attack is in last window repeat SHORT_WINDOW */ + if (((blockSwitchingControl->windowNrgF[0][nBlockSwitchWindows - 1] >> 4) > + fMult((FIXP_DBL)(10 << (DFRACT_BITS - 1 - 4)), + blockSwitchingControl->windowNrgF[1][1])) && + (blockSwitchingControl->lastAttackIndex == + (INT)nBlockSwitchWindows - 1)) { + blockSwitchingControl->attack = TRUE; + blockSwitchingControl->attackIndex = 0; } + } + if (blockSwitchingControl->allowLookAhead) { + blockSwitchingControl->lastWindowSequence = + chgWndSqLkAhd[blockSwitchingControl->lastattack] + [blockSwitchingControl->attack] + [blockSwitchingControl->lastWindowSequence]; + } else { + /* Low Delay */ + blockSwitchingControl->lastWindowSequence = + chgWndSq[blockSwitchingControl->attack] + [blockSwitchingControl->lastWindowSequence]; + } - /* update window shape */ - blockSwitchingControl->windowShape = blockType2windowShape[blockSwitchingControl->allowShortFrames][blockSwitchingControl->lastWindowSequence]; + /* update window shape */ + blockSwitchingControl->windowShape = + blockType2windowShape[blockSwitchingControl->allowShortFrames] + [blockSwitchingControl->lastWindowSequence]; - return(0); + return (0); } - - -static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], const INT blSwWndIdx) -{ -/* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy for a block switching analysis windows, - not for a short block. The same is done FDKaacEnc_CalcWindowEnergy(). The result of FDKaacEnc_GetWindowEnergy() - is used for a comparision of the max energy of left/right channel. */ +static FIXP_DBL FDKaacEnc_GetWindowEnergy(const FIXP_DBL in[], + const INT blSwWndIdx) { + /* For coherency, change FDKaacEnc_GetWindowEnergy() to calcluate the energy + for a block switching analysis windows, not for a short block. The same is + done FDKaacEnc_CalcWindowEnergy(). The result of + FDKaacEnc_GetWindowEnergy() is used for a comparision of the max energy of + left/right channel. */ return in[blSwWndIdx]; - } -static void FDKaacEnc_CalcWindowEnergy(BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, const INT_PCM *pTimeSignal) -{ - INT i; - UINT w; - - FIXP_SGL hiPassCoeff0 = hiPassCoeff[0]; - FIXP_SGL hiPassCoeff1 = hiPassCoeff[1]; +static void FDKaacEnc_CalcWindowEnergy( + BLOCK_SWITCHING_CONTROL *RESTRICT blockSwitchingControl, INT windowLen, + const INT_PCM *pTimeSignal) { + INT i; + UINT w; - /* sum up scalarproduct of timesignal as windowed Energies */ - for (w=0; w < blockSwitchingControl->nBlockSwitchWindows; w++) { +#ifndef SINETABLE_16BIT + const FIXP_DBL hiPassCoeff0 = hiPassCoeff[0]; + const FIXP_DBL hiPassCoeff1 = hiPassCoeff[1]; +#else + const FIXP_SGL hiPassCoeff0 = hiPassCoeff[0]; + const FIXP_SGL hiPassCoeff1 = hiPassCoeff[1]; +#endif - FIXP_DBL temp_windowNrg = FL2FXCONST_DBL(0.0f); - FIXP_DBL temp_windowNrgF = FL2FXCONST_DBL(0.0f); - FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0]; - FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1]; + FIXP_DBL temp_iirState0 = blockSwitchingControl->iirStates[0]; + FIXP_DBL temp_iirState1 = blockSwitchingControl->iirStates[1]; - /* windowNrg = sum(timesample^2) */ - for(i=0;i<windowLen;i++) - { + /* sum up scalarproduct of timesignal as windowed Energies */ + for (w = 0; w < blockSwitchingControl->nBlockSwitchWindows; w++) { + ULONG temp_windowNrg = 0x0; + ULONG temp_windowNrgF = 0x0; - FIXP_DBL tempUnfiltered, tempFiltred, t1, t2; - /* tempUnfiltered is scaled with 1 to prevent overflows during calculation of tempFiltred */ + /* windowNrg = sum(timesample^2) */ + for (i = 0; i < windowLen; i++) { + FIXP_DBL tempUnfiltered, t1, t2; + /* tempUnfiltered is scaled with 1 to prevent overflows during calculation + * of tempFiltred */ #if SAMPLE_BITS == DFRACT_BITS - tempUnfiltered = (FIXP_DBL) *pTimeSignal++ >> 1; + tempUnfiltered = (FIXP_DBL)*pTimeSignal++ >> 1; #else - tempUnfiltered = (FIXP_DBL) *pTimeSignal++ << (DFRACT_BITS-SAMPLE_BITS-1); + tempUnfiltered = (FIXP_DBL)*pTimeSignal++ + << (DFRACT_BITS - SAMPLE_BITS - 1); #endif - t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered-temp_iirState0); - t2 = fMultDiv2(hiPassCoeff0, temp_iirState1); - tempFiltred = (t1 - t2) << 1; - - temp_iirState0 = tempUnfiltered; - temp_iirState1 = tempFiltred; - - /* subtract 2 from overallscaling (BLOCK_SWITCH_ENERGY_SHIFT) - * because tempUnfiltered was already scaled with 1 (is 2 after squaring) - * subtract 1 from overallscaling (BLOCK_SWITCH_ENERGY_SHIFT) - * because of fMultDiv2 is doing a scaling by one */ - temp_windowNrg += fPow2Div2(tempUnfiltered) >> (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); - temp_windowNrgF += fPow2Div2(tempFiltred) >> (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); - } - blockSwitchingControl->windowNrg[1][w] = temp_windowNrg; - blockSwitchingControl->windowNrgF[1][w] = temp_windowNrgF; - blockSwitchingControl->iirStates[0] = temp_iirState0; - blockSwitchingControl->iirStates[1] = temp_iirState1; + t1 = fMultDiv2(hiPassCoeff1, tempUnfiltered - temp_iirState0); + t2 = fMultDiv2(hiPassCoeff0, temp_iirState1); + temp_iirState0 = tempUnfiltered; + temp_iirState1 = (t1 - t2) << 1; + + temp_windowNrg += (LONG)fPow2Div2(temp_iirState0) >> + (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); + temp_windowNrgF += (LONG)fPow2Div2(temp_iirState1) >> + (BLOCK_SWITCH_ENERGY_SHIFT - 1 - 2); } + blockSwitchingControl->windowNrg[1][w] = + (LONG)fMin(temp_windowNrg, (UINT)MAXVAL_DBL); + blockSwitchingControl->windowNrgF[1][w] = + (LONG)fMin(temp_windowNrgF, (UINT)MAXVAL_DBL); + } + blockSwitchingControl->iirStates[0] = temp_iirState0; + blockSwitchingControl->iirStates[1] = temp_iirState1; } - -static const UCHAR synchronizedBlockTypeTable[5][5] = -{ - /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW LOWOV_WINDOW*/ - /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, - /* START_WINDOW */ {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW}, - /* SHORT_WINDOW */ {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW}, - /* STOP_WINDOW */ {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, - /* LOWOV_WINDOW */ {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW}, +static const UCHAR synchronizedBlockTypeTable[5][5] = { + /* LONG_WINDOW START_WINDOW SHORT_WINDOW STOP_WINDOW + LOWOV_WINDOW*/ + /* LONG_WINDOW */ {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW, + LOWOV_WINDOW}, + /* START_WINDOW */ + {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW, LOWOV_WINDOW}, + /* SHORT_WINDOW */ + {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, WRONG_WINDOW}, + /* STOP_WINDOW */ + {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW, LOWOV_WINDOW}, + /* LOWOV_WINDOW */ + {LOWOV_WINDOW, LOWOV_WINDOW, WRONG_WINDOW, LOWOV_WINDOW, LOWOV_WINDOW}, }; -int FDKaacEnc_SyncBlockSwitching ( - BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, - BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, - const INT nChannels, - const INT commonWindow ) -{ +int FDKaacEnc_SyncBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, + BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT nChannels, + const INT commonWindow) { UCHAR patchType = LONG_WINDOW; - if( nChannels == 2 && commonWindow == TRUE) - { + if (nChannels == 2 && commonWindow == TRUE) { /* could be better with a channel loop (need a handle to psy_data) */ /* get suggested Block Types and synchronize */ - patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft->lastWindowSequence]; - patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight->lastWindowSequence]; + patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlLeft + ->lastWindowSequence]; + patchType = synchronizedBlockTypeTable[patchType][blockSwitchingControlRight + ->lastWindowSequence]; - /* sanity check (no change from low overlap window to short winow and vice versa) */ - if (patchType == WRONG_WINDOW) - return -1; /* mixed up AAC-LC and AAC-LD */ + /* sanity check (no change from low overlap window to short winow and vice + * versa) */ + if (patchType == WRONG_WINDOW) return -1; /* mixed up AAC-LC and AAC-LD */ /* Set synchronized Blocktype */ - blockSwitchingControlLeft->lastWindowSequence = patchType; + blockSwitchingControlLeft->lastWindowSequence = patchType; blockSwitchingControlRight->lastWindowSequence = patchType; /* update window shape */ - blockSwitchingControlLeft->windowShape = blockType2windowShape[blockSwitchingControlLeft->allowShortFrames][blockSwitchingControlLeft->lastWindowSequence]; - blockSwitchingControlRight->windowShape = blockType2windowShape[blockSwitchingControlLeft->allowShortFrames][blockSwitchingControlRight->lastWindowSequence]; + blockSwitchingControlLeft->windowShape = + blockType2windowShape[blockSwitchingControlLeft->allowShortFrames] + [blockSwitchingControlLeft->lastWindowSequence]; + blockSwitchingControlRight->windowShape = + blockType2windowShape[blockSwitchingControlLeft->allowShortFrames] + [blockSwitchingControlRight->lastWindowSequence]; } - if (blockSwitchingControlLeft->allowShortFrames) - { + if (blockSwitchingControlLeft->allowShortFrames) { int i; - if( nChannels == 2 ) - { - if (commonWindow == TRUE) - { + if (nChannels == 2) { + if (commonWindow == TRUE) { /* Synchronize grouping info */ - int windowSequenceLeftOld = blockSwitchingControlLeft->lastWindowSequence; - int windowSequenceRightOld = blockSwitchingControlRight->lastWindowSequence; + int windowSequenceLeftOld = + blockSwitchingControlLeft->lastWindowSequence; + int windowSequenceRightOld = + blockSwitchingControlRight->lastWindowSequence; /* Long Blocks */ - if(patchType != SHORT_WINDOW) { + if (patchType != SHORT_WINDOW) { /* Set grouping info */ - blockSwitchingControlLeft->noOfGroups = 1; - blockSwitchingControlRight->noOfGroups = 1; - blockSwitchingControlLeft->groupLen[0] = 1; + blockSwitchingControlLeft->noOfGroups = 1; + blockSwitchingControlRight->noOfGroups = 1; + blockSwitchingControlLeft->groupLen[0] = 1; blockSwitchingControlRight->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { - blockSwitchingControlLeft->groupLen[i] = 0; + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = 0; blockSwitchingControlRight->groupLen[i] = 0; } } /* Short Blocks */ else { - /* in case all two channels were detected as short-blocks before syncing, use the grouping of channel with higher maxWindowNrg */ - if( (windowSequenceLeftOld == SHORT_WINDOW) && - (windowSequenceRightOld == SHORT_WINDOW) ) - { - if(blockSwitchingControlLeft->maxWindowNrg > blockSwitchingControlRight->maxWindowNrg) { - /* Left Channel wins */ - blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i]; - } + /* in case all two channels were detected as short-blocks before + * syncing, use the grouping of channel with higher maxWindowNrg */ + if ((windowSequenceLeftOld == SHORT_WINDOW) && + (windowSequenceRightOld == SHORT_WINDOW)) { + if (blockSwitchingControlLeft->maxWindowNrg > + blockSwitchingControlRight->maxWindowNrg) { + /* Left Channel wins */ + blockSwitchingControlRight->noOfGroups = + blockSwitchingControlLeft->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlRight->groupLen[i] = + blockSwitchingControlLeft->groupLen[i]; + } + } else { + /* Right Channel wins */ + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = + blockSwitchingControlRight->groupLen[i]; + } } - else { - /* Right Channel wins */ - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i]; - } - } - } - else if ( (windowSequenceLeftOld == SHORT_WINDOW) && - (windowSequenceRightOld != SHORT_WINDOW) ) - { + } else if ((windowSequenceLeftOld == SHORT_WINDOW) && + (windowSequenceRightOld != SHORT_WINDOW)) { /* else use grouping of short-block channel */ - blockSwitchingControlRight->noOfGroups = blockSwitchingControlLeft->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlRight->groupLen[i] = blockSwitchingControlLeft->groupLen[i]; + blockSwitchingControlRight->noOfGroups = + blockSwitchingControlLeft->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlRight->groupLen[i] = + blockSwitchingControlLeft->groupLen[i]; } - } - else if ( (windowSequenceRightOld == SHORT_WINDOW) && - (windowSequenceLeftOld != SHORT_WINDOW) ) - { - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups; - for (i = 0; i < MAX_NO_OF_GROUPS; i++){ - blockSwitchingControlLeft->groupLen[i] = blockSwitchingControlRight->groupLen[i]; + } else if ((windowSequenceRightOld == SHORT_WINDOW) && + (windowSequenceLeftOld != SHORT_WINDOW)) { + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups; + for (i = 0; i < MAX_NO_OF_GROUPS; i++) { + blockSwitchingControlLeft->groupLen[i] = + blockSwitchingControlRight->groupLen[i]; } } else { /* syncing a start and stop window ... */ - blockSwitchingControlLeft->noOfGroups = blockSwitchingControlRight->noOfGroups = 2; - blockSwitchingControlLeft->groupLen[0] = blockSwitchingControlRight->groupLen[0] = 4; - blockSwitchingControlLeft->groupLen[1] = blockSwitchingControlRight->groupLen[1] = 4; + blockSwitchingControlLeft->noOfGroups = + blockSwitchingControlRight->noOfGroups = 2; + blockSwitchingControlLeft->groupLen[0] = + blockSwitchingControlRight->groupLen[0] = 4; + blockSwitchingControlLeft->groupLen[1] = + blockSwitchingControlRight->groupLen[1] = 4; } } /* Short Blocks */ - } - else { + } else { /* stereo, no common window */ - if (blockSwitchingControlLeft->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlLeft->noOfGroups = 1; + if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlLeft->noOfGroups = 1; blockSwitchingControlLeft->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlLeft->groupLen[i] = 0; } } - if (blockSwitchingControlRight->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlRight->noOfGroups = 1; + if (blockSwitchingControlRight->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlRight->noOfGroups = 1; blockSwitchingControlRight->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlRight->groupLen[i] = 0; } } } /* common window */ } else { /* Mono */ - if (blockSwitchingControlLeft->lastWindowSequence!=SHORT_WINDOW){ - blockSwitchingControlLeft->noOfGroups = 1; + if (blockSwitchingControlLeft->lastWindowSequence != SHORT_WINDOW) { + blockSwitchingControlLeft->noOfGroups = 1; blockSwitchingControlLeft->groupLen[0] = 1; - for (i = 1; i < MAX_NO_OF_GROUPS; i++) - { + for (i = 1; i < MAX_NO_OF_GROUPS; i++) { blockSwitchingControlLeft->groupLen[i] = 0; } } } } /* allowShortFrames */ - /* Translate LOWOV_WINDOW block type to a meaningful window shape. */ - if ( ! blockSwitchingControlLeft->allowShortFrames ) { - if ( blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW - && blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW ) - { + if (!blockSwitchingControlLeft->allowShortFrames) { + if (blockSwitchingControlLeft->lastWindowSequence != LONG_WINDOW && + blockSwitchingControlLeft->lastWindowSequence != STOP_WINDOW) { blockSwitchingControlLeft->lastWindowSequence = LONG_WINDOW; blockSwitchingControlLeft->windowShape = LOL_WINDOW; } } if (nChannels == 2) { - if ( ! blockSwitchingControlRight->allowShortFrames ) { - if ( blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW - && blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW ) - { + if (!blockSwitchingControlRight->allowShortFrames) { + if (blockSwitchingControlRight->lastWindowSequence != LONG_WINDOW && + blockSwitchingControlRight->lastWindowSequence != STOP_WINDOW) { blockSwitchingControlRight->lastWindowSequence = LONG_WINDOW; blockSwitchingControlRight->windowShape = LOL_WINDOW; } @@ -541,5 +580,3 @@ int FDKaacEnc_SyncBlockSwitching ( return 0; } - - diff --git a/libAACenc/src/block_switch.h b/libAACenc/src/block_switch.h index e94b6f5..ff20f84 100644 --- a/libAACenc/src/block_switch.h +++ b/libAACenc/src/block_switch.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,68 +90,73 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/***************************** MPEG-4 AAC Encoder ************************** +/**************************** AAC encoder library ****************************** Author(s): M. Werner + Description: Block switching -******************************************************************************/ +*******************************************************************************/ -#ifndef _BLOCK_SWITCH_H -#define _BLOCK_SWITCH_H +#ifndef BLOCK_SWITCH_H +#define BLOCK_SWITCH_H #include "common_fix.h" #include "psy_const.h" /****************** Defines ******************************/ - #define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */ +#define BLOCK_SWITCH_WINDOWS 8 /* number of windows for energy calculation */ -#define BLOCK_SWITCHING_IIR_LEN 2 /* Length of HighPass-IIR-Filter for Attack-Detection */ -#define BLOCK_SWITCH_ENERGY_SHIFT 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in windowNrgs. */ +#define BLOCK_SWITCHING_IIR_LEN \ + 2 /* Length of HighPass-IIR-Filter for Attack-Detection */ +#define BLOCK_SWITCH_ENERGY_SHIFT \ + 7 /* should be logDualis(BLOCK_SWITCH_WINDOW_LEN) to avoid overflow in \ + windowNrgs. */ #define LAST_WINDOW 0 #define THIS_WINDOW 1 - /****************** Structures ***************************/ -typedef struct{ - INT lastWindowSequence; - INT windowShape; - INT lastWindowShape; - UINT nBlockSwitchWindows; /* number of windows for energy calculation */ - INT attack; - INT lastattack; - INT attackIndex; - INT lastAttackIndex; - INT allowShortFrames; /* for Low Delay, don't allow short frames */ - INT allowLookAhead; /* for Low Delay, don't do look-ahead */ - INT noOfGroups; - INT groupLen[MAX_NO_OF_GROUPS]; - FIXP_DBL maxWindowNrg; /* max energy in subwindows */ - - FIXP_DBL windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows (last and current) */ - FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy in segments (last and current) */ - FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */ - - FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */ +typedef struct { + INT lastWindowSequence; + INT windowShape; + INT lastWindowShape; + UINT nBlockSwitchWindows; /* number of windows for energy calculation */ + INT attack; + INT lastattack; + INT attackIndex; + INT lastAttackIndex; + INT allowShortFrames; /* for Low Delay, don't allow short frames */ + INT allowLookAhead; /* for Low Delay, don't do look-ahead */ + INT noOfGroups; + INT groupLen[MAX_NO_OF_GROUPS]; + FIXP_DBL maxWindowNrg; /* max energy in subwindows */ + + FIXP_DBL + windowNrg[2][BLOCK_SWITCH_WINDOWS]; /* time signal energy in Subwindows + (last and current) */ + FIXP_DBL windowNrgF[2][BLOCK_SWITCH_WINDOWS]; /* filtered time signal energy + in segments (last and + current) */ + FIXP_DBL accWindowNrg; /* recursively accumulated windowNrgF */ + + FIXP_DBL iirStates[BLOCK_SWITCHING_IIR_LEN]; /* filter delay-line */ } BLOCK_SWITCHING_CONTROL; +void FDKaacEnc_InitBlockSwitching( + BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay); - - - -void FDKaacEnc_InitBlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, INT isLowDelay); - -int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, const INT granuleLength, const int isLFE, const INT_PCM *pTimeSignal); +int FDKaacEnc_BlockSwitching(BLOCK_SWITCHING_CONTROL *blockSwitchingControl, + const INT granuleLength, const int isLFE, + const INT_PCM *pTimeSignal); int FDKaacEnc_SyncBlockSwitching( - BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, - BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, - const INT noOfChannels, - const INT commonWindow); + BLOCK_SWITCHING_CONTROL *blockSwitchingControlLeft, + BLOCK_SWITCHING_CONTROL *blockSwitchingControlRight, const INT noOfChannels, + const INT commonWindow); -#endif /* #ifndef _BLOCK_SWITCH_H */ +#endif /* #ifndef BLOCK_SWITCH_H */ diff --git a/libAACenc/src/channel_map.cpp b/libAACenc/src/channel_map.cpp index 559a4ce..6ee91d5 100644 --- a/libAACenc/src/channel_map.cpp +++ b/libAACenc/src/channel_map.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,21 +90,22 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/************************* Fast MPEG AAC Audio Encoder ********************** + Author(s): A. Groeschel - Initial author: A. Groeschel - contents/description: channel mapping functionality + Description: channel mapping functionality -******************************************************************************/ +*******************************************************************************/ #include "channel_map.h" #include "bitenc.h" #include "psy_const.h" #include "qc_data.h" #include "aacEnc_ram.h" - +#include "FDK_tools_rom.h" /* channel_assignment treats the relationship of Input file channels to the encoder channels. @@ -121,369 +133,464 @@ amm-info@iis.fraunhofer.de LFE 3 5 (LFE) */ -typedef struct { - - CHANNEL_MODE encoderMode; - INT channel_assignment[/*(8)*/12]; - -} CHANNEL_ASSIGNMENT_INFO_TAB; - - -static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabMpeg[] = -{ - { MODE_INVALID, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* invalid */ - { MODE_1, { 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* mono */ - { MODE_2, { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* stereo */ - { MODE_1_2, { 0, 1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 3ch */ - { MODE_1_2_1, { 0, 1, 2, 3,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 4ch */ - { MODE_1_2_2, { 0, 1, 2, 3, 4,-1,-1,-1,-1,-1,-1,-1} }, /* 5ch */ - { MODE_1_2_2_1, { 0, 1, 2, 3, 4, 5,-1,-1,-1,-1,-1,-1} }, /* 5.1ch */ - { MODE_1_2_2_2_1, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_REAR_SURROUND, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_FRONT_CENTER, { 0, 1, 2, 3, 4, 5, 6, 7,-1,-1,-1,-1} } /* 7.1ch */ -}; - -static const CHANNEL_ASSIGNMENT_INFO_TAB assignmentInfoTabWav[] = -{ - { MODE_INVALID, {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* invalid */ - { MODE_1, { 0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* mono */ - { MODE_2, { 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* stereo */ - { MODE_1_2, { 2, 0, 1,-1,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 3ch */ - { MODE_1_2_1, { 2, 0, 1, 3,-1,-1,-1,-1,-1,-1,-1,-1} }, /* 4ch */ - { MODE_1_2_2, { 2, 0, 1, 3, 4,-1,-1,-1,-1,-1,-1,-1} }, /* 5ch */ - { MODE_1_2_2_1, { 2, 0, 1, 4, 5, 3,-1,-1,-1,-1,-1,-1} }, /* 5.1ch */ - { MODE_1_2_2_2_1, { 2, 6, 7, 0, 1, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_REAR_SURROUND, { 2, 0, 1, 6, 7, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ - { MODE_7_1_FRONT_CENTER, { 2, 6, 7, 0, 1, 4, 5, 3,-1,-1,-1,-1} }, /* 7.1ch */ -}; - /* Channel mode configuration tab provides, corresponding number of channels and elements */ -static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = -{ - { MODE_1, 1, 1, 1 }, /* SCE */ - { MODE_2, 2, 2, 1 }, /* CPE */ - { MODE_1_2, 3, 3, 2 }, /* SCE,CPE */ - { MODE_1_2_1, 4, 4, 3 }, /* SCE,CPE,SCE */ - { MODE_1_2_2, 5, 5, 3 }, /* SCE,CPE,CPE */ - { MODE_1_2_2_1, 6, 5, 4 }, /* SCE,CPE,CPE,LFE */ - { MODE_1_2_2_2_1, 8, 7, 5 }, /* SCE,CPE,CPE,CPE,LFE */ - { MODE_7_1_REAR_SURROUND, 8, 7, 5 }, - { MODE_7_1_FRONT_CENTER, 8, 7, 5 }, -}; +static const CHANNEL_MODE_CONFIG_TAB channelModeConfig[] = { + {MODE_1, 1, 1, 1}, /* chCfg 1, SCE */ + {MODE_2, 2, 2, 1}, /* chCfg 2, CPE */ + {MODE_1_2, 3, 3, 2}, /* chCfg 3, SCE,CPE */ + {MODE_1_2_1, 4, 4, 3}, /* chCfg 4, SCE,CPE,SCE */ + {MODE_1_2_2, 5, 5, 3}, /* chCfg 5, SCE,CPE,CPE */ + {MODE_1_2_2_1, 6, 5, 4}, /* chCfg 6, SCE,CPE,CPE,LFE */ + {MODE_1_2_2_2_1, 8, 7, 5}, /* chCfg 7, SCE,CPE,CPE,CPE,LFE */ + {MODE_6_1, 7, 6, 5}, /* chCfg 11, SCE,CPE,CPE,SCE,LFE */ + {MODE_7_1_BACK, 8, 7, 5}, /* chCfg 12, SCE,CPE,CPE,CPE,LFE */ + {MODE_7_1_TOP_FRONT, 8, 7, 5}, /* chCfg 14, SCE,CPE,CPE,LFE,CPE */ + {MODE_7_1_REAR_SURROUND, 8, 7, + 5}, /* same as MODE_7_1_BACK, SCE,CPE,CPE,CPE,LFE */ + {MODE_7_1_FRONT_CENTER, 8, 7, + 5}, /* same as MODE_1_2_2_2_1, SCE,CPE,CPE,CPE,LFE */ -#define MAX_MODES (sizeof(assignmentInfoTabWav)/sizeof(CHANNEL_ASSIGNMENT_INFO_TAB)) - -const INT* FDKaacEnc_getChannelAssignment(CHANNEL_MODE encMode, CHANNEL_ORDER co) -{ - const CHANNEL_ASSIGNMENT_INFO_TAB *pTab; - int i; - - if (co == CH_ORDER_MPEG) - pTab = assignmentInfoTabMpeg; - else - pTab = assignmentInfoTabWav; - - for(i=MAX_MODES-1; i>0; i--) { - if (encMode== pTab[i].encoderMode) { - break; - } - } - return (pTab[i].channel_assignment); -} +}; -AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, INT nChannels) -{ +AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, + INT nChannels) { INT i; CHANNEL_MODE encMode = MODE_INVALID; - if (*mode==MODE_UNKNOWN) { - for (i=0; i<(INT)sizeof(channelModeConfig)/(INT)sizeof(CHANNEL_MODE_CONFIG_TAB); i++) { - if (channelModeConfig[i].nChannels==nChannels) { - encMode = channelModeConfig[i].encMode; - break; + if (*mode == MODE_UNKNOWN) { + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].nChannels == nChannels) { + encMode = channelModeConfig[i].encMode; + break; } } *mode = encMode; - } - else { + } else { /* check if valid channel configuration */ - if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels==nChannels) { - encMode = *mode; + if (FDKaacEnc_GetChannelModeConfiguration(*mode)->nChannels == nChannels) { + encMode = *mode; } } - if (encMode==MODE_INVALID) { + if (encMode == MODE_INVALID) { return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } return AAC_ENC_OK; } -static INT FDKaacEnc_initElement (ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType, INT* cnt, CHANNEL_MODE mode, CHANNEL_ORDER co, INT* it_cnt, const FIXP_DBL relBits) { - - INT error=0; - INT counter =*cnt; +static INT FDKaacEnc_initElement(ELEMENT_INFO* elInfo, MP4_ELEMENT_ID elType, + INT* cnt, FDK_channelMapDescr* mapDescr, + UINT mapIdx, INT* it_cnt, + const FIXP_DBL relBits) { + INT error = 0; + INT counter = *cnt; - const INT *assign = FDKaacEnc_getChannelAssignment(mode, co); - - elInfo->elType=elType; + elInfo->elType = elType; elInfo->relativeBits = relBits; - switch(elInfo->elType) { - case ID_SCE: case ID_LFE: case ID_CCE: - elInfo->nChannelsInEl=1; - elInfo->ChannelIndex[0]=assign[counter++]; - elInfo->instanceTag=it_cnt[elType]++; - - break; - case ID_CPE: - elInfo->nChannelsInEl=2; - elInfo->ChannelIndex[0]=assign[counter++]; - elInfo->ChannelIndex[1]=assign[counter++]; - elInfo->instanceTag=it_cnt[elType]++; - break; - case ID_DSE: - elInfo->nChannelsInEl=0; - elInfo->ChannelIndex[0]=0; - elInfo->ChannelIndex[1]=0; - elInfo->instanceTag=it_cnt[elType]++; - break; - default: error=1; + switch (elInfo->elType) { + case ID_SCE: + case ID_LFE: + case ID_CCE: + elInfo->nChannelsInEl = 1; + elInfo->ChannelIndex[0] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->instanceTag = it_cnt[elType]++; + break; + case ID_CPE: + elInfo->nChannelsInEl = 2; + elInfo->ChannelIndex[0] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->ChannelIndex[1] = + FDK_chMapDescr_getMapValue(mapDescr, counter++, mapIdx); + elInfo->instanceTag = it_cnt[elType]++; + break; + case ID_DSE: + elInfo->nChannelsInEl = 0; + elInfo->ChannelIndex[0] = 0; + elInfo->ChannelIndex[1] = 0; + elInfo->instanceTag = it_cnt[elType]++; + break; + default: + error = 1; }; *cnt = counter; return error; - } -AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, CHANNEL_ORDER co, CHANNEL_MAPPING* cm) -{ - INT count=0; /* count through coder channels */ - INT it_cnt[ID_END+1]; +AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, + CHANNEL_ORDER co, + CHANNEL_MAPPING* cm) { + INT count = 0; /* count through coder channels */ + INT it_cnt[ID_END + 1]; INT i; + UINT mapIdx; + FDK_channelMapDescr mapDescr; - for (i=0; i<ID_END; i++) - it_cnt[i]=0; + for (i = 0; i < ID_END; i++) it_cnt[i] = 0; FDKmemclear(cm, sizeof(CHANNEL_MAPPING)); /* init channel mapping*/ - for (i=0; i<(INT)sizeof(channelModeConfig)/(INT)sizeof(CHANNEL_MODE_CONFIG_TAB); i++) { - if (channelModeConfig[i].encMode==mode) - { - cm->encMode = channelModeConfig[i].encMode; - cm->nChannels = channelModeConfig[i].nChannels; - cm->nChannelsEff = channelModeConfig[i].nChannelsEff; - cm->nElements = channelModeConfig[i].nElements; + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].encMode == mode) { + cm->encMode = channelModeConfig[i].encMode; + cm->nChannels = channelModeConfig[i].nChannels; + cm->nChannelsEff = channelModeConfig[i].nChannelsEff; + cm->nElements = channelModeConfig[i].nElements; - break; + break; } } + /* init map descriptor */ + FDK_chMapDescr_init(&mapDescr, NULL, 0, (co == CH_ORDER_MPEG) ? 1 : 0); + switch (mode) { + case MODE_7_1_REAR_SURROUND: /* MODE_7_1_REAR_SURROUND is equivalent to + MODE_7_1_BACK */ + mapIdx = (INT)MODE_7_1_BACK; + break; + case MODE_7_1_FRONT_CENTER: /* MODE_7_1_FRONT_CENTER is equivalent to + MODE_1_2_2_2_1 */ + mapIdx = (INT)MODE_1_2_2_2_1; + break; + default: + mapIdx = + (INT)mode > 14 + ? 0 + : (INT) + mode; /* if channel config > 14 MPEG mapping will be used */ + } + /* init element info struct */ - switch(mode) { + switch (mode) { case MODE_1: /* (mono) sce */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, (FIXP_DBL)MAXVAL_DBL); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, (FIXP_DBL)MAXVAL_DBL); break; case MODE_2: /* (stereo) cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, mode, co, it_cnt, (FIXP_DBL)MAXVAL_DBL); + FDKaacEnc_initElement(&cm->elInfo[0], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, (FIXP_DBL)MAXVAL_DBL); break; case MODE_1_2: /* sce + cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.4f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.6f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.4f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.6f)); break; case MODE_1_2_1: /* sce + cpe + sce */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.3f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.4f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.3f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.3f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.4f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.3f)); break; case MODE_1_2_2: /* sce + cpe + cpe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.37f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.37f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.37f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.37f)); break; case MODE_1_2_2_1: /* (5.1) sce + cpe + cpe + lfe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.24f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.35f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.35f)); - FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.06f)); + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.24f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.35f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.35f)); + FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.06f)); + break; + + case MODE_6_1: + /* (6.1) sce + cpe + cpe + sce + lfe */ + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.2f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.275f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.275f)); + FDKaacEnc_initElement(&cm->elInfo[3], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.2f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.05f)); break; case MODE_1_2_2_2_1: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: + case MODE_7_1_FRONT_CENTER: { /* (7.1) sce + cpe + cpe + cpe + lfe */ - FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.18f)); - FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.26f)); - FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, mode, co, it_cnt, FL2FXCONST_DBL(0.04f)); + /* (7.1 top) sce + cpe + cpe + lfe + cpe */ + + FDKaacEnc_initElement(&cm->elInfo[0], ID_SCE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.18f)); + FDKaacEnc_initElement(&cm->elInfo[1], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[2], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + if (mode != MODE_7_1_TOP_FRONT) { + FDKaacEnc_initElement(&cm->elInfo[3], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.04f)); + } else { + FDKaacEnc_initElement(&cm->elInfo[3], ID_LFE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.04f)); + FDKaacEnc_initElement(&cm->elInfo[4], ID_CPE, &count, &mapDescr, mapIdx, + it_cnt, FL2FXCONST_DBL(0.26f)); + } break; + } + default: //*chMap=0; return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; }; - - FDK_ASSERT(cm->nElements<=(8)); - + FDK_ASSERT(cm->nElements <= ((8))); return AAC_ENC_OK; } -AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, - CHANNEL_MAPPING *cm, - INT bitrateTot, - INT averageBitsTot, - INT maxChannelBits) -{ +AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm, + INT bitrateTot, INT averageBitsTot, + INT maxChannelBits) { int sc_brTot = CountLeadingBits(bitrateTot); - switch(cm->encMode) { - case MODE_1: - hQC->elementBits[0]->chBitrateEl = bitrateTot; + switch (cm->encMode) { + case MODE_1: + hQC->elementBits[0]->chBitrateEl = bitrateTot; - hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - break; + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + break; - case MODE_2: - hQC->elementBits[0]->chBitrateEl = bitrateTot>>1; + case MODE_2: + hQC->elementBits[0]->chBitrateEl = bitrateTot >> 1; - hQC->elementBits[0]->maxBitsEl = 2*maxChannelBits; + hQC->elementBits[0]->maxBitsEl = 2 * maxChannelBits; - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - break; - case MODE_1_2: { - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + break; + case MODE_1_2: { + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + break; + } + case MODE_1_2_1: { + /* sce + cpe + sce */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits; + FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; + FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sce1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = maxChannelBits; + break; + } + case MODE_1_2_2: { + /* sce + cpe + cpe */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + break; + } + case MODE_1_2_2_1: { + /* (5.1) sce + cpe + cpe + lfe */ + hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; + hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; + hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; + hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits; + FIXP_DBL sceRate = cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; + FIXP_DBL lfeRate = cm->elInfo[3].relativeBits; + + int maxBitsTot = + maxChannelBits * 5; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits); + sc = CountLeadingBits(maxChannelBits); + + maxChannelBits = + fMult((FIXP_DBL)maxChannelBits << sc, GetInvInt(5)) >> sc; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[3]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[3]->maxBitsEl = maxLfeBits; - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpeRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); + break; + } + case MODE_6_1: { + /* (6.1) sce + cpe + cpe + sce + lfe */ + FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = + cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = + cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = + cm->elInfo[2].relativeBits; + FIXP_DBL sce2Rate = hQC->elementBits[3]->relativeBitsEl = + cm->elInfo[3].relativeBits; + FIXP_DBL lfeRate = hQC->elementBits[4]->relativeBitsEl = + cm->elInfo[4].relativeBits; + + int maxBitsTot = + maxChannelBits * 6; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits) / 6; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[3]->chBitrateEl = + fMult(sce2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[4]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[3]->maxBitsEl = maxChannelBits; + hQC->elementBits[4]->maxBitsEl = maxLfeBits; + break; + } + case MODE_7_1_TOP_FRONT: + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_1_2_2_2_1: { + int cpe3Idx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 3 : 4; + int lfeIdx = (cm->encMode != MODE_7_1_TOP_FRONT) ? 4 : 3; - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - break; - } - case MODE_1_2_1: { - /* sce + cpe + sce */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL sce1Rate = cm->elInfo[0].relativeBits; - FIXP_DBL cpeRate = cm->elInfo[1].relativeBits; - FIXP_DBL sce2Rate = cm->elInfo[2].relativeBits; - - hQC->elementBits[0]->chBitrateEl = fMult(sce1Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpeRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(sce2Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = maxChannelBits; - break; - } - case MODE_1_2_2: { - /* sce + cpe + cpe */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - break; - } + /* (7.1) sce + cpe + cpe + cpe + lfe */ + FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = + cm->elInfo[0].relativeBits; + FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = + cm->elInfo[1].relativeBits; + FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = + cm->elInfo[2].relativeBits; + FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl = + cm->elInfo[cpe3Idx].relativeBits; + FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl = + cm->elInfo[lfeIdx].relativeBits; + + int maxBitsTot = + maxChannelBits * 7; /* LFE does not add to bit reservoir */ + int sc = CountLeadingBits(fixMax(maxChannelBits, averageBitsTot)); + int maxLfeBits = (int)fMax( + (INT)((fMult(lfeRate, (FIXP_DBL)(maxChannelBits << sc)) >> sc) << 1), + (INT)((fMult(FL2FXCONST_DBL(1.1f / 2.f), + fMult(lfeRate, (FIXP_DBL)(averageBitsTot << sc))) + << 1) >> + sc)); + + maxChannelBits = (maxBitsTot - maxLfeBits) / 7; + + hQC->elementBits[0]->chBitrateEl = + fMult(sceRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + hQC->elementBits[1]->chBitrateEl = + fMult(cpe1Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[2]->chBitrateEl = + fMult(cpe2Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[cpe3Idx]->chBitrateEl = + fMult(cpe3Rate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> (sc_brTot + 1); + hQC->elementBits[lfeIdx]->chBitrateEl = + fMult(lfeRate, (FIXP_DBL)(bitrateTot << sc_brTot)) >> sc_brTot; + + hQC->elementBits[0]->maxBitsEl = maxChannelBits; + hQC->elementBits[1]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[2]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[cpe3Idx]->maxBitsEl = 2 * maxChannelBits; + hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits; + break; + } - case MODE_1_2_2_1: { - /* (5.1) sce + cpe + cpe + lfe */ - hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - hQC->elementBits[3]->relativeBitsEl = cm->elInfo[3].relativeBits; - FIXP_DBL sceRate = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = cm->elInfo[2].relativeBits; - FIXP_DBL lfeRate = cm->elInfo[3].relativeBits; - - int maxBitsTot = maxChannelBits * 5; /* LFE does not add to bit reservoir */ - int sc = CountLeadingBits(fixMax(maxChannelBits,averageBitsTot)); - int maxLfeBits = (int) FDKmax ( (INT)((fMult(lfeRate,(FIXP_DBL)(maxChannelBits<<sc))>>sc)<<1), - (INT)((fMult(FL2FXCONST_DBL(1.1f/2.f),fMult(lfeRate,(FIXP_DBL)(averageBitsTot<<sc)))<<1)>>sc) ); - - maxChannelBits = (maxBitsTot - maxLfeBits); - sc = CountLeadingBits(maxChannelBits); - - maxChannelBits = fMult((FIXP_DBL)maxChannelBits<<sc,GetInvInt(5))>>sc; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[3]->chBitrateEl = fMult(lfeRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[3]->maxBitsEl = maxLfeBits; - - break; - } - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - case MODE_1_2_2_2_1: { - int cpe3Idx = 3; - int lfeIdx = 4; - - /* (7.1) sce + cpe + cpe + cpe + lfe */ - FIXP_DBL sceRate = hQC->elementBits[0]->relativeBitsEl = cm->elInfo[0].relativeBits; - FIXP_DBL cpe1Rate = hQC->elementBits[1]->relativeBitsEl = cm->elInfo[1].relativeBits; - FIXP_DBL cpe2Rate = hQC->elementBits[2]->relativeBitsEl = cm->elInfo[2].relativeBits; - FIXP_DBL cpe3Rate = hQC->elementBits[cpe3Idx]->relativeBitsEl = cm->elInfo[cpe3Idx].relativeBits; - FIXP_DBL lfeRate = hQC->elementBits[lfeIdx]->relativeBitsEl = cm->elInfo[lfeIdx].relativeBits; - - int maxBitsTot = maxChannelBits * 7; /* LFE does not add to bit reservoir */ - int sc = CountLeadingBits(fixMax(maxChannelBits,averageBitsTot)); - int maxLfeBits = (int) FDKmax ( (INT)((fMult(lfeRate,(FIXP_DBL)(maxChannelBits<<sc))>>sc)<<1), - (INT)((fMult(FL2FXCONST_DBL(1.1f/2.f),fMult(lfeRate,(FIXP_DBL)(averageBitsTot<<sc)))<<1)>>sc) ); - - maxChannelBits = (maxBitsTot - maxLfeBits) / 7; - - hQC->elementBits[0]->chBitrateEl = fMult(sceRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - hQC->elementBits[1]->chBitrateEl = fMult(cpe1Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[2]->chBitrateEl = fMult(cpe2Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[cpe3Idx]->chBitrateEl = fMult(cpe3Rate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>(sc_brTot+1); - hQC->elementBits[lfeIdx]->chBitrateEl = fMult(lfeRate, (FIXP_DBL)(bitrateTot<<sc_brTot))>>sc_brTot; - - hQC->elementBits[0]->maxBitsEl = maxChannelBits; - hQC->elementBits[1]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[2]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[cpe3Idx]->maxBitsEl = 2*maxChannelBits; - hQC->elementBits[lfeIdx]->maxBitsEl = maxLfeBits; - break; - } - default: - return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; + default: + return AAC_ENC_UNSUPPORTED_CHANNELCONFIG; } return AAC_ENC_OK; @@ -491,61 +598,66 @@ AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, /********************************************************************************/ /* */ -/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */ +/* function: GetMonoStereoMODE(const CHANNEL_MODE mode) */ /* */ -/* description: Determines encoder setting from channel mode. */ -/* Multichannel modes are mapped to mono or stereo modes */ +/* description: Determines encoder setting from channel mode. */ +/* Multichannel modes are mapped to mono or stereo modes */ /* returns MODE_MONO in case of mono, */ /* MODE_STEREO in case of stereo */ /* MODE_INVALID in case of error */ /* */ -/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */ -/* output: return: CM_STEREO_MODE monoStereoSetting */ +/* input: CHANNEL_MODE mode: Encoder mode (see qc_data.h). */ +/* output: return: CM_STEREO_MODE monoStereoSetting */ /* (MODE_INVALID: error, */ /* MODE_MONO: mono */ /* MODE_STEREO: stereo). */ /* */ -/* misc: No memory is allocated. */ +/* misc: No memory is allocated. */ /* */ /********************************************************************************/ -ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode){ - +ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode) { ELEMENT_MODE monoStereoSetting = EL_MODE_INVALID; - switch(mode){ - case MODE_1: /* mono setups */ - monoStereoSetting = EL_MODE_MONO; - break; - case MODE_2: /* stereo setups */ - case MODE_1_2: - case MODE_1_2_1: - case MODE_1_2_2: - case MODE_1_2_2_1: - case MODE_1_2_2_2_1: - case MODE_7_1_REAR_SURROUND: - case MODE_7_1_FRONT_CENTER: - monoStereoSetting = EL_MODE_STEREO; - break; - default: /* error */ - monoStereoSetting = EL_MODE_INVALID; - break; + switch (mode) { + case MODE_1: /* mono setups */ + monoStereoSetting = EL_MODE_MONO; + break; + + case MODE_2: /* stereo setups */ + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + case MODE_6_1: + case MODE_1_2_2_2_1: + case MODE_7_1_REAR_SURROUND: + case MODE_7_1_FRONT_CENTER: + case MODE_7_1_BACK: + case MODE_7_1_TOP_FRONT: + monoStereoSetting = EL_MODE_STEREO; + break; + + default: /* error */ + monoStereoSetting = EL_MODE_INVALID; + break; } return monoStereoSetting; } -const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(const CHANNEL_MODE mode) -{ +const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration( + const CHANNEL_MODE mode) { INT i; - const CHANNEL_MODE_CONFIG_TAB *cm_config = NULL; + const CHANNEL_MODE_CONFIG_TAB* cm_config = NULL; /* get channel mode config */ - for (i=0; i<(INT)sizeof(channelModeConfig)/(INT)sizeof(CHANNEL_MODE_CONFIG_TAB); i++) { - if (channelModeConfig[i].encMode==mode) - { - cm_config = &channelModeConfig[i]; - break; + for (i = 0; i < (INT)sizeof(channelModeConfig) / + (INT)sizeof(CHANNEL_MODE_CONFIG_TAB); + i++) { + if (channelModeConfig[i].encMode == mode) { + cm_config = &channelModeConfig[i]; + break; } } return cm_config; diff --git a/libAACenc/src/channel_map.h b/libAACenc/src/channel_map.h index 2cfb486..f9154cd 100644 --- a/libAACenc/src/channel_map.h +++ b/libAACenc/src/channel_map.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/************************* Fast MPEG AAC Audio Encoder ********************** +/**************************** AAC encoder library ****************************** - Initial author: A. Groeschel - contents/description: channel mapping functionality + Author(s): A. Groeschel -******************************************************************************/ + Description: channel mapping functionality -#ifndef _CHANNEL_MAP_H -#define _CHANNEL_MAP_H +*******************************************************************************/ +#ifndef CHANNEL_MAP_H +#define CHANNEL_MAP_H #include "aacenc.h" #include "psy_const.h" @@ -103,14 +114,8 @@ typedef struct { INT nElements; } CHANNEL_MODE_CONFIG_TAB; - /* Element mode */ -typedef enum { - EL_MODE_INVALID = 0, - EL_MODE_MONO, - EL_MODE_STEREO -} ELEMENT_MODE; - +typedef enum { EL_MODE_INVALID = 0, EL_MODE_MONO, EL_MODE_STEREO } ELEMENT_MODE; AAC_ENCODER_ERROR FDKaacEnc_DetermineEncoderMode(CHANNEL_MODE* mode, INT nChannels); @@ -119,14 +124,13 @@ AAC_ENCODER_ERROR FDKaacEnc_InitChannelMapping(CHANNEL_MODE mode, CHANNEL_ORDER co, CHANNEL_MAPPING* chMap); -AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE *hQC, - CHANNEL_MAPPING *cm, - INT bitrateTot, - INT averageBitsTot, +AAC_ENCODER_ERROR FDKaacEnc_InitElementBits(QC_STATE* hQC, CHANNEL_MAPPING* cm, + INT bitrateTot, INT averageBitsTot, INT maxChannelBits); ELEMENT_MODE FDKaacEnc_GetMonoStereoMode(const CHANNEL_MODE mode); -const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration(const CHANNEL_MODE mode); +const CHANNEL_MODE_CONFIG_TAB* FDKaacEnc_GetChannelModeConfiguration( + const CHANNEL_MODE mode); #endif /* CHANNEL_MAP_H */ diff --git a/libAACenc/src/chaosmeasure.cpp b/libAACenc/src/chaosmeasure.cpp index 4e56e9e..664284b 100644 --- a/libAACenc/src/chaosmeasure.cpp +++ b/libAACenc/src/chaosmeasure.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Chaos measure calculation + Description: Chaos measure calculation -******************************************************************************/ +*******************************************************************************/ #include "chaosmeasure.h" @@ -94,40 +106,63 @@ amm-info@iis.fraunhofer.de functionname: FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast description: Eberlein method of chaos measure calculation by high-pass filtering amplitude spectrum - A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric -- - highly optimized + A special case of FDKaacEnc_CalculateChaosMeasureTonalGeneric +-- highly optimized *****************************************************************************/ -static void -FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *RESTRICT chaosMeasure ) -{ +static void FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( + FIXP_DBL *RESTRICT paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *RESTRICT chaosMeasure) { INT i, j; /* calculate chaos measure by "peak filter" */ - for (i=0; i<2; i++) { - /* make even and odd pass through data */ - FIXP_DBL left,center; /* left, center tap of filter */ - - left = (FIXP_DBL)((LONG)paMDCTDataNM0[i]^((LONG)paMDCTDataNM0[i]>>(DFRACT_BITS-1))); - center = (FIXP_DBL)((LONG)paMDCTDataNM0[i+2]^((LONG)paMDCTDataNM0[i+2]>>(DFRACT_BITS-1))); - - for (j = i+2; j < numberOfLines - 2; j+=2) { - FIXP_DBL right = (FIXP_DBL)((LONG)paMDCTDataNM0[j+2]^((LONG)paMDCTDataNM0[j+2]>>(DFRACT_BITS-1))); - FIXP_DBL tmp = (left>>1)+(right>>1); - - if (tmp < center ) { - INT leadingBits = CntLeadingZeros(center)-1; - tmp = schur_div(tmp<<leadingBits, center<<leadingBits, 8); - chaosMeasure[j] = fMult(tmp,tmp); - } - else { - chaosMeasure[j] = (FIXP_DBL)MAXVAL_DBL; - } - - left = center; - center = right; + /* make even and odd pass through data */ + FIXP_DBL left_0_div2, + center_0; /* left, center tap of filter, even numbered */ + FIXP_DBL left_1_div2, center_1; /* left, center tap of filter, odd numbered */ + + left_0_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[0] ^ + ((LONG)paMDCTDataNM0[0] >> (DFRACT_BITS - 1))) >> + 1); + left_1_div2 = (FIXP_DBL)(((LONG)paMDCTDataNM0[1] ^ + ((LONG)paMDCTDataNM0[1] >> (DFRACT_BITS - 1))) >> + 1); + center_0 = (FIXP_DBL)((LONG)paMDCTDataNM0[2] ^ + ((LONG)paMDCTDataNM0[2] >> (DFRACT_BITS - 1))); + center_1 = (FIXP_DBL)((LONG)paMDCTDataNM0[3] ^ + ((LONG)paMDCTDataNM0[3] >> (DFRACT_BITS - 1))); + + for (j = 2; j < numberOfLines - 2; j += 2) { + FIXP_DBL right_0 = + (FIXP_DBL)((LONG)paMDCTDataNM0[j + 2] ^ + ((LONG)paMDCTDataNM0[j + 2] >> (DFRACT_BITS - 1))); + FIXP_DBL tmp_0 = left_0_div2 + (right_0 >> 1); + FIXP_DBL right_1 = + (FIXP_DBL)((LONG)paMDCTDataNM0[j + 3] ^ + ((LONG)paMDCTDataNM0[j + 3] >> (DFRACT_BITS - 1))); + FIXP_DBL tmp_1 = left_1_div2 + (right_1 >> 1); + + if (tmp_0 < center_0) { + INT leadingBits = CntLeadingZeros(center_0) - 1; + tmp_0 = schur_div(tmp_0 << leadingBits, center_0 << leadingBits, 8); + tmp_0 = fMult(tmp_0, tmp_0); + } else { + tmp_0 = (FIXP_DBL)MAXVAL_DBL; + } + chaosMeasure[j + 0] = tmp_0; + left_0_div2 = center_0 >> 1; + center_0 = right_0; + + if (tmp_1 < center_1) { + INT leadingBits = CntLeadingZeros(center_1) - 1; + tmp_1 = schur_div(tmp_1 << leadingBits, center_1 << leadingBits, 8); + tmp_1 = fMult(tmp_1, tmp_1); + } else { + tmp_1 = (FIXP_DBL)MAXVAL_DBL; } + + left_1_div2 = center_1 >> 1; + center_1 = right_1; + chaosMeasure[j + 1] = tmp_1; } /* provide chaos measure for first few lines */ @@ -135,11 +170,10 @@ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDat chaosMeasure[1] = chaosMeasure[2]; /* provide chaos measure for last few lines */ - for (i = (numberOfLines-3); i < numberOfLines; i++) + for (i = (numberOfLines - 3); i < numberOfLines; i++) chaosMeasure[i] = FL2FXCONST_DBL(0.5); } - /***************************************************************************** functionname: FDKaacEnc_CalculateChaosMeasure description: calculates a chaosmeasure for every line, different methods @@ -148,14 +182,10 @@ FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( FIXP_DBL *RESTRICT paMDCTDat input: MDCT data, number of lines output: chaosMeasure *****************************************************************************/ -void -FDKaacEnc_CalculateChaosMeasure( FIXP_DBL *paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *chaosMeasure ) +void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *chaosMeasure) { - FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( paMDCTDataNM0, - numberOfLines, - chaosMeasure ); + FDKaacEnc_FDKaacEnc_CalculateChaosMeasurePeakFast( + paMDCTDataNM0, numberOfLines, chaosMeasure); } - diff --git a/libAACenc/src/chaosmeasure.h b/libAACenc/src/chaosmeasure.h index 44301c5..60d4137 100644 --- a/libAACenc/src/chaosmeasure.h +++ b/libAACenc/src/chaosmeasure.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,25 +90,23 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Chaos measure calculation + Author(s): M. Werner -******************************************************************************/ + Description: Chaos measure calculation -#ifndef __CHAOSMEASURE_H -#define __CHAOSMEASURE_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef CHAOSMEASURE_H +#define CHAOSMEASURE_H +#include "common_fix.h" #include "psy_const.h" -void -FDKaacEnc_CalculateChaosMeasure( FIXP_DBL *paMDCTDataNM0, - INT numberOfLines, - FIXP_DBL *chaosMeasure ); +void FDKaacEnc_CalculateChaosMeasure(FIXP_DBL *paMDCTDataNM0, INT numberOfLines, + FIXP_DBL *chaosMeasure); -#endif +#endif /* CHAOSMEASURE_H */ diff --git a/libAACenc/src/dyn_bits.cpp b/libAACenc/src/dyn_bits.cpp index 0c07109..74baeb8 100644 --- a/libAACenc/src/dyn_bits.cpp +++ b/libAACenc/src/dyn_bits.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Noiseless coder module + Description: Noiseless coder module -******************************************************************************/ +*******************************************************************************/ #include "dyn_bits.h" #include "bit_cnt.h" @@ -97,18 +109,15 @@ amm-info@iis.fraunhofer.de typedef INT (*lookUpTable)[CODE_BOOK_ESC_NDX + 1]; -static INT FDKaacEnc_getSideInfoBits( - const SECTION_INFO* const huffsection, - const SHORT* const sideInfoTab, - const INT useHCR - ) -{ +static INT FDKaacEnc_getSideInfoBits(const SECTION_INFO* const huffsection, + const SHORT* const sideInfoTab, + const INT useHCR) { INT sideInfoBits; - if ( useHCR && ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16)) ) { + if (useHCR && + ((huffsection->codeBook == 11) || (huffsection->codeBook >= 16))) { sideInfoBits = 5; - } - else { + } else { sideInfoBits = sideInfoTab[huffsection->sfbCnt]; } @@ -117,43 +126,32 @@ static INT FDKaacEnc_getSideInfoBits( /* count bits using all possible tables */ static void FDKaacEnc_buildBitLookUp( - const SHORT* const quantSpectrum, - const INT maxSfb, - const INT* const sfbOffset, - const UINT* const sfbMax, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - SECTION_INFO* const huffsection - ) -{ + const SHORT* const quantSpectrum, const INT maxSfb, + const INT* const sfbOffset, const UINT* const sfbMax, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + SECTION_INFO* const huffsection) { INT i, sfbWidth; - for (i = 0; i < maxSfb; i++) - { + for (i = 0; i < maxSfb; i++) { huffsection[i].sfbCnt = 1; huffsection[i].sfbStart = i; huffsection[i].sectionBits = INVALID_BITCOUNT; huffsection[i].codeBook = -1; sfbWidth = sfbOffset[i + 1] - sfbOffset[i]; - FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i], bitLookUp[i]); + FDKaacEnc_bitCount(quantSpectrum + sfbOffset[i], sfbWidth, sfbMax[i], + bitLookUp[i]); } } /* essential helper functions */ -static INT FDKaacEnc_findBestBook( - const INT* const bc, - INT* const book, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_findBestBook(const INT* const bc, INT* const book, + const INT useVCB11) { INT minBits = INVALID_BITCOUNT, j; int end = CODE_BOOK_ESC_NDX; - - for (j = 0; j <= end; j++) - { - if (bc[j] < minBits) - { + for (j = 0; j <= end; j++) { + if (bc[j] < minBits) { minBits = bc[j]; *book = j; } @@ -161,114 +159,94 @@ static INT FDKaacEnc_findBestBook( return (minBits); } -static INT FDKaacEnc_findMinMergeBits( - const INT* const bc1, - const INT* const bc2, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_findMinMergeBits(const INT* const bc1, + const INT* const bc2, + const INT useVCB11) { INT minBits = INVALID_BITCOUNT, j; - int end = CODE_BOOK_ESC_NDX; - + DWORD_ALIGNED(bc1); + DWORD_ALIGNED(bc2); - for (j = 0; j <= end; j++) - { - if (bc1[j] + bc2[j] < minBits) - { - minBits = bc1[j] + bc2[j]; - } + for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) { + minBits = fixMin(minBits, bc1[j] + bc2[j]); } return (minBits); } -static void FDKaacEnc_mergeBitLookUp( - INT* const bc1, - const INT* const bc2 - ) -{ +static inline void FDKaacEnc_mergeBitLookUp(INT* const RESTRICT bc1, + const INT* const RESTRICT bc2) { int j; - for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) - { + for (j = 0; j <= CODE_BOOK_ESC_NDX; j++) { + FDK_ASSERT(INVALID_BITCOUNT == 0x1FFFFFFF); bc1[j] = fixMin(bc1[j] + bc2[j], INVALID_BITCOUNT); } } -static INT FDKaacEnc_findMaxMerge( - const INT* const mergeGainLookUp, - const SECTION_INFO* const huffsection, - const INT maxSfb, - INT* const maxNdx - ) -{ +static inline INT FDKaacEnc_findMaxMerge(const INT* const mergeGainLookUp, + const SECTION_INFO* const huffsection, + const INT maxSfb, INT* const maxNdx) { INT i, maxMergeGain = 0; + int lastMaxNdx = 0; - for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) - { - if (mergeGainLookUp[i] > maxMergeGain) - { + for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) { + if (mergeGainLookUp[i] > maxMergeGain) { maxMergeGain = mergeGainLookUp[i]; - *maxNdx = i; + lastMaxNdx = i; } } + *maxNdx = lastMaxNdx; return (maxMergeGain); } -static INT FDKaacEnc_CalcMergeGain( - const SECTION_INFO* const huffsection, - const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const SHORT* const sideInfoTab, - const INT ndx1, - const INT ndx2, - const INT useVCB11 - ) -{ +static inline INT FDKaacEnc_CalcMergeGain( + const SECTION_INFO* const huffsection, + const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + const SHORT* const sideInfoTab, const INT ndx1, const INT ndx2, + const INT useVCB11) { INT MergeGain, MergeBits, SplitBits; - MergeBits = sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] + FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11); - SplitBits = huffsection[ndx1].sectionBits + huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */ + MergeBits = + sideInfoTab[huffsection[ndx1].sfbCnt + huffsection[ndx2].sfbCnt] + + FDKaacEnc_findMinMergeBits(bitLookUp[ndx1], bitLookUp[ndx2], useVCB11); + SplitBits = + huffsection[ndx1].sectionBits + + huffsection[ndx2].sectionBits; /* Bit amount for splitted huffsections */ MergeGain = SplitBits - MergeBits; - if ( (huffsection[ndx1].codeBook==CODE_BOOK_PNS_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_PNS_NO) - || (huffsection[ndx1].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO) - || (huffsection[ndx1].codeBook==CODE_BOOK_IS_IN_PHASE_NO)||(huffsection[ndx2].codeBook==CODE_BOOK_IS_IN_PHASE_NO) - ) - { + if ((huffsection[ndx1].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[ndx1].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[ndx1].codeBook == CODE_BOOK_IS_IN_PHASE_NO) || + (huffsection[ndx2].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { MergeGain = -1; } return (MergeGain); } - /* sectioning Stage 0:find minimum codbooks */ static void FDKaacEnc_gmStage0( - SECTION_INFO* const RESTRICT huffsection, - const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const INT* const noiseNrg, - const INT* const isBook - ) -{ + SECTION_INFO* const RESTRICT huffsection, + const INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const INT* const noiseNrg, const INT* const isBook) { INT i; - for (i = 0; i < maxSfb; i++) - { + for (i = 0; i < maxSfb; i++) { /* Side-Info bits will be calculated in Stage 1! */ - if (huffsection[i].sectionBits == INVALID_BITCOUNT) - { + if (huffsection[i].sectionBits == INVALID_BITCOUNT) { /* intensity and pns codebooks are already allocated in bitcount.c */ - if(noiseNrg[i] != NO_NOISE_PNS){ - huffsection[i].codeBook=CODE_BOOK_PNS_NO; + if (noiseNrg[i] != NO_NOISE_PNS) { + huffsection[i].codeBook = CODE_BOOK_PNS_NO; huffsection[i].sectionBits = 0; - } - else if( isBook[i] ) { - huffsection[i].codeBook=isBook[i]; + } else if (isBook[i]) { + huffsection[i].codeBook = isBook[i]; huffsection[i].sectionBits = 0; - } - else { - huffsection[i].sectionBits = FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), 0); /* useVCB11 must be 0!!! */ + } else { + huffsection[i].sectionBits = + FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), + 0); /* useVCB11 must be 0!!! */ } } } @@ -279,24 +257,18 @@ static void FDKaacEnc_gmStage0( calculate side info */ static void FDKaacEnc_gmStage1( - SECTION_INFO* const RESTRICT huffsection, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const SHORT* const sideInfoTab, - const INT useVCB11 - ) -{ + SECTION_INFO* const RESTRICT huffsection, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const SHORT* const sideInfoTab, const INT useVCB11) { INT mergeStart = 0, mergeEnd; - do - { - for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) - { + do { + for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) { if (huffsection[mergeStart].codeBook != huffsection[mergeEnd].codeBook) break; - - /* we can merge. update tables, side info bits will be updated outside of this loop */ + /* we can merge. update tables, side info bits will be updated outside of + * this loop */ huffsection[mergeStart].sfbCnt++; huffsection[mergeStart].sectionBits += huffsection[mergeEnd].sectionBits; @@ -305,8 +277,10 @@ static void FDKaacEnc_gmStage1( } /* add side info info bits */ - huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits(&huffsection[mergeStart], sideInfoTab, useVCB11); - huffsection[mergeEnd - 1].sfbStart = huffsection[mergeStart].sfbStart; /* speed up prev search */ + huffsection[mergeStart].sectionBits += FDKaacEnc_getSideInfoBits( + &huffsection[mergeStart], sideInfoTab, useVCB11); + huffsection[mergeEnd - 1].sfbStart = + huffsection[mergeStart].sfbStart; /* speed up prev search */ mergeStart = mergeEnd; @@ -317,132 +291,101 @@ static void FDKaacEnc_gmStage1( sectioning Stage 2:greedy merge algorithm, merge connected sections with maximum bit gain until no more gain is possible */ -static void -FDKaacEnc_gmStage2( - SECTION_INFO* const RESTRICT huffsection, - INT* const RESTRICT mergeGainLookUp, - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const INT maxSfb, - const SHORT* const sideInfoTab, - const INT useVCB11 - ) -{ +static inline void FDKaacEnc_gmStage2( + SECTION_INFO* const RESTRICT huffsection, + INT* const RESTRICT mergeGainLookUp, + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const INT maxSfb, + const SHORT* const sideInfoTab, const INT useVCB11) { INT i; - for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) - { - mergeGainLookUp[i] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - i, - i + huffsection[i].sfbCnt, - useVCB11); + for (i = 0; i + huffsection[i].sfbCnt < maxSfb; i += huffsection[i].sfbCnt) { + mergeGainLookUp[i] = + FDKaacEnc_CalcMergeGain(huffsection, bitLookUp, sideInfoTab, i, + i + huffsection[i].sfbCnt, useVCB11); } - while (TRUE) - { - INT maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast; + while (TRUE) { + INT maxMergeGain, maxNdx, maxNdxNext, maxNdxLast; - maxMergeGain = FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx); + maxMergeGain = + FDKaacEnc_findMaxMerge(mergeGainLookUp, huffsection, maxSfb, &maxNdx); /* exit while loop if no more gain is possible */ - if (maxMergeGain <= 0) - break; + if (maxMergeGain <= 0) break; maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt; /* merge sections with maximum bit gain */ huffsection[maxNdx].sfbCnt += huffsection[maxNdxNext].sfbCnt; - huffsection[maxNdx].sectionBits += huffsection[maxNdxNext].sectionBits - maxMergeGain; + huffsection[maxNdx].sectionBits += + huffsection[maxNdxNext].sectionBits - maxMergeGain; /* update bit look up table for merged huffsection */ FDKaacEnc_mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]); /* update mergeLookUpTable */ - if (maxNdx != 0) - { + if (maxNdx != 0) { maxNdxLast = huffsection[maxNdx - 1].sfbStart; - mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - maxNdxLast, - maxNdx, - useVCB11); - + mergeGainLookUp[maxNdxLast] = FDKaacEnc_CalcMergeGain( + huffsection, bitLookUp, sideInfoTab, maxNdxLast, maxNdx, useVCB11); } maxNdxNext = maxNdx + huffsection[maxNdx].sfbCnt; huffsection[maxNdxNext - 1].sfbStart = huffsection[maxNdx].sfbStart; if (maxNdxNext < maxSfb) - mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain(huffsection, - bitLookUp, - sideInfoTab, - maxNdx, - maxNdxNext, - useVCB11); - + mergeGainLookUp[maxNdx] = FDKaacEnc_CalcMergeGain( + huffsection, bitLookUp, sideInfoTab, maxNdx, maxNdxNext, useVCB11); } } /* count bits used by the noiseless coder */ static void FDKaacEnc_noiselessCounter( - SECTION_DATA* const RESTRICT sectionData, - INT mergeGainLookUp[MAX_SFB_LONG], - INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const sfbOffset, - const INT blockType, - const INT* const noiseNrg, - const INT* const isBook, - const INT useVCB11 - ) -{ + SECTION_DATA* const RESTRICT sectionData, INT mergeGainLookUp[MAX_SFB_LONG], + INT bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], + const SHORT* const quantSpectrum, const UINT* const maxValueInSfb, + const INT* const sfbOffset, const INT blockType, const INT* const noiseNrg, + const INT* const isBook, const INT useVCB11) { INT grpNdx, i; - const SHORT *sideInfoTab = NULL; - SECTION_INFO *huffsection; + const SHORT* sideInfoTab = NULL; + SECTION_INFO* huffsection; /* use appropriate side info table */ - switch (blockType) - { - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sideInfoTab = FDKaacEnc_sideInfoTabLong; - break; - case SHORT_WINDOW: - sideInfoTab = FDKaacEnc_sideInfoTabShort; - break; + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + default: + sideInfoTab = FDKaacEnc_sideInfoTabLong; + break; + case SHORT_WINDOW: + sideInfoTab = FDKaacEnc_sideInfoTabShort; + break; } sectionData->noOfSections = 0; sectionData->huffmanBits = 0; sectionData->sideInfoBits = 0; - - if (sectionData->maxSfbPerGroup == 0) - return; + if (sectionData->maxSfbPerGroup == 0) return; /* loop trough groups */ - for (grpNdx = 0; grpNdx < sectionData->sfbCnt; grpNdx += sectionData->sfbPerGroup) - { + for (grpNdx = 0; grpNdx < sectionData->sfbCnt; + grpNdx += sectionData->sfbPerGroup) { huffsection = sectionData->huffsection + sectionData->noOfSections; /* count bits in this group */ - FDKaacEnc_buildBitLookUp(quantSpectrum, - sectionData->maxSfbPerGroup, - sfbOffset + grpNdx, - maxValueInSfb + grpNdx, - bitLookUp, - huffsection); + FDKaacEnc_buildBitLookUp(quantSpectrum, sectionData->maxSfbPerGroup, + sfbOffset + grpNdx, maxValueInSfb + grpNdx, + bitLookUp, huffsection); /* 0.Stage :Find minimum Codebooks */ - FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup, noiseNrg+grpNdx, isBook+grpNdx); + FDKaacEnc_gmStage0(huffsection, bitLookUp, sectionData->maxSfbPerGroup, + noiseNrg + grpNdx, isBook + grpNdx); /* 1.Stage :Merge all connected regions with the same code book */ - FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup, sideInfoTab, useVCB11); - + FDKaacEnc_gmStage1(huffsection, bitLookUp, sectionData->maxSfbPerGroup, + sideInfoTab, useVCB11); /* 2.Stage @@ -450,14 +393,8 @@ static void FDKaacEnc_noiselessCounter( gain until no more gain is possible */ - FDKaacEnc_gmStage2(huffsection, - mergeGainLookUp, - bitLookUp, - sectionData->maxSfbPerGroup, - sideInfoTab, - useVCB11); - - + FDKaacEnc_gmStage2(huffsection, mergeGainLookUp, bitLookUp, + sectionData->maxSfbPerGroup, sideInfoTab, useVCB11); /* compress output, calculate total huff and side bits @@ -465,31 +402,33 @@ static void FDKaacEnc_noiselessCounter( to save time, we must set it here for later use in bitenc */ - for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) - { - if ((huffsection[i].codeBook==CODE_BOOK_PNS_NO) || - (huffsection[i].codeBook==CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (huffsection[i].codeBook==CODE_BOOK_IS_IN_PHASE_NO)) - { - huffsection[i].sectionBits=0; + for (i = 0; i < sectionData->maxSfbPerGroup; i += huffsection[i].sfbCnt) { + if ((huffsection[i].codeBook == CODE_BOOK_PNS_NO) || + (huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { + huffsection[i].sectionBits = 0; } else { - /* the sections in the sectionData are now marked with the optimal code book */ + /* the sections in the sectionData are now marked with the optimal code + * book */ - FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), useVCB11); + FDKaacEnc_findBestBook(bitLookUp[i], &(huffsection[i].codeBook), + useVCB11); - sectionData->huffmanBits += huffsection[i].sectionBits - FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); + sectionData->huffmanBits += + huffsection[i].sectionBits - + FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); } huffsection[i].sfbStart += grpNdx; /* sum up side info bits (section data bits) */ - sectionData->sideInfoBits += FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); + sectionData->sideInfoBits += + FDKaacEnc_getSideInfoBits(&huffsection[i], sideInfoTab, useVCB11); sectionData->huffsection[sectionData->noOfSections++] = huffsection[i]; } } } - /******************************************************************************* functionname: FDKaacEnc_scfCount @@ -525,80 +464,68 @@ static void FDKaacEnc_noiselessCounter( scalfacGain (75) and the future scalefacGain (5) is 70. ********************************************************************************/ -static void FDKaacEnc_scfCount( - const INT* const scalefacGain, - const UINT* const maxValueInSfb, - SECTION_DATA* const RESTRICT sectionData, - const INT* const isScale - ) -{ +static void FDKaacEnc_scfCount(const INT* const scalefacGain, + const UINT* const maxValueInSfb, + SECTION_DATA* const RESTRICT sectionData, + const INT* const isScale) { INT i, j, k, m, n; - INT lastValScf = 0; - INT deltaScf = 0; - INT found = 0; + INT lastValScf = 0; + INT deltaScf = 0; + INT found = 0; INT scfSkipCounter = 0; - INT lastValIs = 0; + INT lastValIs = 0; sectionData->scalefacBits = 0; - if (scalefacGain == NULL) - return; + if (scalefacGain == NULL) return; sectionData->firstScf = 0; - for (i=0; i<sectionData->noOfSections; i++) - { - if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if (sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) { sectionData->firstScf = sectionData->huffsection[i].sfbStart; lastValScf = scalefacGain[sectionData->firstScf]; break; } } - for (i=0; i<sectionData->noOfSections; i++) - { - if ((sectionData->huffsection[i].codeBook == CODE_BOOK_IS_OUT_OF_PHASE_NO) || - (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) - { + for (i = 0; i < sectionData->noOfSections; i++) { + if ((sectionData->huffsection[i].codeBook == + CODE_BOOK_IS_OUT_OF_PHASE_NO) || + (sectionData->huffsection[i].codeBook == CODE_BOOK_IS_IN_PHASE_NO)) { for (j = sectionData->huffsection[i].sfbStart; - j < sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt; - j++) - { - INT deltaIs = isScale[j]-lastValIs; - lastValIs = isScale[j]; - sectionData->scalefacBits+=FDKaacEnc_bitCountScalefactorDelta(deltaIs); + j < sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + j++) { + INT deltaIs = isScale[j] - lastValIs; + lastValIs = isScale[j]; + sectionData->scalefacBits += + FDKaacEnc_bitCountScalefactorDelta(deltaIs); } } /* Intensity */ else if ((sectionData->huffsection[i].codeBook != CODE_BOOK_ZERO_NO) && - (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) - { - INT tmp = sectionData->huffsection[i].sfbStart + sectionData->huffsection[i].sfbCnt; - for (j = sectionData->huffsection[i].sfbStart; j<tmp; j++) - { + (sectionData->huffsection[i].codeBook != CODE_BOOK_PNS_NO)) { + INT tmp = sectionData->huffsection[i].sfbStart + + sectionData->huffsection[i].sfbCnt; + for (j = sectionData->huffsection[i].sfbStart; j < tmp; j++) { /* check if we can repeat the last value to save bits */ - if (maxValueInSfb[j] == 0) - { + if (maxValueInSfb[j] == 0) { found = 0; /* are scalefactors skipped? */ - if (scfSkipCounter == 0) - { + if (scfSkipCounter == 0) { /* end of section */ - if (j == (tmp - 1) ) - found = 0; /* search in other sections for maxValueInSfb != 0 */ - else - { + if (j == (tmp - 1)) + found = 0; /* search in other sections for maxValueInSfb != 0 */ + else { /* search in this section for the next maxValueInSfb[] != 0 */ - for (k = (j+1); k < tmp; k++) - { - if (maxValueInSfb[k] != 0) - { + for (k = (j + 1); k < tmp; k++) { + if (maxValueInSfb[k] != 0) { found = 1; - if ( (fixp_abs(scalefacGain[k] - lastValScf)) <= CODE_BOOK_SCF_LAV) - deltaScf = 0; /* save bits */ - else - { + if ((fixp_abs(scalefacGain[k] - lastValScf)) <= + CODE_BOOK_SCF_LAV) + deltaScf = 0; /* save bits */ + else { /* do not save bits */ deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; @@ -612,20 +539,19 @@ static void FDKaacEnc_scfCount( } /* search for the next maxValueInSfb[] != 0 in all other sections */ - for (m=(i+1); (m < sectionData->noOfSections) && (found == 0); m++) - { - if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) && (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) - { - INT end = sectionData->huffsection[m].sfbStart + sectionData->huffsection[m].sfbCnt; - for (n = sectionData->huffsection[m].sfbStart; n<end; n++) - { - if (maxValueInSfb[n] != 0) - { + for (m = (i + 1); (m < sectionData->noOfSections) && (found == 0); + m++) { + if ((sectionData->huffsection[m].codeBook != CODE_BOOK_ZERO_NO) && + (sectionData->huffsection[m].codeBook != CODE_BOOK_PNS_NO)) { + INT end = sectionData->huffsection[m].sfbStart + + sectionData->huffsection[m].sfbCnt; + for (n = sectionData->huffsection[m].sfbStart; n < end; n++) { + if (maxValueInSfb[n] != 0) { found = 1; - if (fixp_abs(scalefacGain[n] - lastValScf) <= CODE_BOOK_SCF_LAV) - deltaScf = 0; /* save bits */ - else - { + if (fixp_abs(scalefacGain[n] - lastValScf) <= + CODE_BOOK_SCF_LAV) + deltaScf = 0; /* save bits */ + else { /* do not save bits */ deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; @@ -639,64 +565,29 @@ static void FDKaacEnc_scfCount( } } /* no maxValueInSfb[] != 0 found */ - if (found == 0) - { + if (found == 0) { deltaScf = 0; scfSkipCounter = 0; } - } - else { + } else { /* consider skipped scalefactors */ deltaScf = 0; scfSkipCounter--; } - } - else { + } else { deltaScf = lastValScf - scalefacGain[j]; lastValScf = scalefacGain[j]; } - sectionData->scalefacBits += FDKaacEnc_bitCountScalefactorDelta(deltaScf); + sectionData->scalefacBits += + FDKaacEnc_bitCountScalefactorDelta(deltaScf); } } } /* for (i=0; i<sectionData->noOfSections; i++) */ } -#ifdef PNS_PRECOUNT_ENABLE -/* - preCount bits used pns -*/ -/* estimate bits used by pns for correction of static bits */ -/* no codebook switch estimation, see AAC LD FASTENC */ -INT noisePreCount(const INT *noiseNrg, INT maxSfb) -{ - INT noisePCMFlag = TRUE; - INT lastValPns = 0, deltaPns; - int i, bits=0; - - for (i = 0; i < maxSfb; i++) { - if (noiseNrg[i] != NO_NOISE_PNS) { - - if (noisePCMFlag) { - bits+=PNS_PCM_BITS; - lastValPns = noiseNrg[i]; - noisePCMFlag = FALSE; - }else { - deltaPns = noiseNrg[i]-lastValPns; - lastValPns = noiseNrg[i]; - bits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns); - } - } - } - return ( bits ); -} -#endif /* PNS_PRECOUNT_ENABLE */ - /* count bits used by pns */ -static void FDKaacEnc_noiseCount( - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg - ) -{ +static void FDKaacEnc_noiseCount(SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg) { INT noisePCMFlag = TRUE; INT lastValPns = 0, deltaPns; int i, j; @@ -707,99 +598,66 @@ static void FDKaacEnc_noiseCount( if (sectionData->huffsection[i].codeBook == CODE_BOOK_PNS_NO) { int sfbStart = sectionData->huffsection[i].sfbStart; int sfbEnd = sfbStart + sectionData->huffsection[i].sfbCnt; - for (j=sfbStart; j<sfbEnd; j++) { - + for (j = sfbStart; j < sfbEnd; j++) { if (noisePCMFlag) { - sectionData->noiseNrgBits+=PNS_PCM_BITS; - lastValPns = noiseNrg[j]; + sectionData->noiseNrgBits += PNS_PCM_BITS; + lastValPns = noiseNrg[j]; noisePCMFlag = FALSE; } else { - deltaPns = noiseNrg[j]-lastValPns; - lastValPns = noiseNrg[j]; - sectionData->noiseNrgBits+=FDKaacEnc_bitCountScalefactorDelta(deltaPns); + deltaPns = noiseNrg[j] - lastValPns; + lastValPns = noiseNrg[j]; + sectionData->noiseNrgBits += + FDKaacEnc_bitCountScalefactorDelta(deltaPns); } } } } } -INT FDKaacEnc_dynBitCount( - BITCNTR_STATE* const hBC, - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const scalefac, - const INT blockType, - const INT sfbCnt, - const INT maxSfbPerGroup, - const INT sfbPerGroup, - const INT* const sfbOffset, - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg, - const INT* const isBook, - const INT* const isScale, - const UINT syntaxFlags - ) -{ - sectionData->blockType = blockType; - sectionData->sfbCnt = sfbCnt; - sectionData->sfbPerGroup = sfbPerGroup; - sectionData->noOfGroups = sfbCnt / sfbPerGroup; +INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC, + const SHORT* const quantSpectrum, + const UINT* const maxValueInSfb, + const INT* const scalefac, const INT blockType, + const INT sfbCnt, const INT maxSfbPerGroup, + const INT sfbPerGroup, const INT* const sfbOffset, + SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg, const INT* const isBook, + const INT* const isScale, const UINT syntaxFlags) { + sectionData->blockType = blockType; + sectionData->sfbCnt = sfbCnt; + sectionData->sfbPerGroup = sfbPerGroup; + sectionData->noOfGroups = sfbCnt / sfbPerGroup; sectionData->maxSfbPerGroup = maxSfbPerGroup; - FDKaacEnc_noiselessCounter( - sectionData, - hBC->mergeGainLookUp, - (lookUpTable)hBC->bitLookUp, - quantSpectrum, - maxValueInSfb, - sfbOffset, - blockType, - noiseNrg, - isBook, - (syntaxFlags & AC_ER_VCB11)?1:0); - - FDKaacEnc_scfCount( - scalefac, - maxValueInSfb, - sectionData, - isScale); - - FDKaacEnc_noiseCount(sectionData, - noiseNrg); - - return (sectionData->huffmanBits + - sectionData->sideInfoBits + - sectionData->scalefacBits + - sectionData->noiseNrgBits); + FDKaacEnc_noiselessCounter(sectionData, hBC->mergeGainLookUp, + (lookUpTable)hBC->bitLookUp, quantSpectrum, + maxValueInSfb, sfbOffset, blockType, noiseNrg, + isBook, (syntaxFlags & AC_ER_VCB11) ? 1 : 0); + + FDKaacEnc_scfCount(scalefac, maxValueInSfb, sectionData, isScale); + + FDKaacEnc_noiseCount(sectionData, noiseNrg); + + return (sectionData->huffmanBits + sectionData->sideInfoBits + + sectionData->scalefacBits + sectionData->noiseNrgBits); } -INT FDKaacEnc_BCNew(BITCNTR_STATE **phBC - ,UCHAR* dynamic_RAM - ) -{ - BITCNTR_STATE *hBC = GetRam_aacEnc_BitCntrState(); +INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM) { + BITCNTR_STATE* hBC = GetRam_aacEnc_BitCntrState(); - if (hBC) - { + if (hBC) { *phBC = hBC; - hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0,dynamic_RAM); - hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0,dynamic_RAM); - if (hBC->bitLookUp == 0 || - hBC->mergeGainLookUp == 0) - { + hBC->bitLookUp = GetRam_aacEnc_BitLookUp(0, dynamic_RAM); + hBC->mergeGainLookUp = GetRam_aacEnc_MergeGainLookUp(0, dynamic_RAM); + if (hBC->bitLookUp == 0 || hBC->mergeGainLookUp == 0) { return 1; } } return (hBC == 0) ? 1 : 0; } -void FDKaacEnc_BCClose(BITCNTR_STATE **phBC) -{ - if (*phBC!=NULL) { - +void FDKaacEnc_BCClose(BITCNTR_STATE** phBC) { + if (*phBC != NULL) { FreeRam_aacEnc_BitCntrState(phBC); } } - - - diff --git a/libAACenc/src/dyn_bits.h b/libAACenc/src/dyn_bits.h index ae78a4c..a727a30 100644 --- a/libAACenc/src/dyn_bits.h +++ b/libAACenc/src/dyn_bits.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,42 +90,40 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Noiseless coder module + Description: Noiseless coder module -******************************************************************************/ +*******************************************************************************/ -#ifndef __DYN_BITS_H -#define __DYN_BITS_H +#ifndef DYN_BITS_H +#define DYN_BITS_H #include "common_fix.h" #include "psy_const.h" #include "aacenc_tns.h" -#define MAX_SECTIONS MAX_GROUPED_SFB -#define SECT_ESC_VAL_LONG 31 -#define SECT_ESC_VAL_SHORT 7 -#define CODE_BOOK_BITS 4 -#define SECT_BITS_LONG 5 -#define SECT_BITS_SHORT 3 -#define PNS_PCM_BITS 9 +#define MAX_SECTIONS MAX_GROUPED_SFB +#define SECT_ESC_VAL_LONG 31 +#define SECT_ESC_VAL_SHORT 7 +#define CODE_BOOK_BITS 4 +#define SECT_BITS_LONG 5 +#define SECT_BITS_SHORT 3 +#define PNS_PCM_BITS 9 -typedef struct -{ +typedef struct { INT codeBook; INT sfbStart; INT sfbCnt; - INT sectionBits; /* huff + si ! */ + INT sectionBits; /* huff + si ! */ } SECTION_INFO; - -typedef struct -{ +typedef struct { INT blockType; INT noOfGroups; INT sfbCnt; @@ -122,46 +131,30 @@ typedef struct INT sfbPerGroup; INT noOfSections; SECTION_INFO huffsection[MAX_SECTIONS]; - INT sideInfoBits; /* sectioning bits */ - INT huffmanBits; /* huffman coded bits */ - INT scalefacBits; /* scalefac coded bits */ - INT noiseNrgBits; /* noiseEnergy coded bits */ - INT firstScf; /* first scf to be coded */ + INT sideInfoBits; /* sectioning bits */ + INT huffmanBits; /* huffman coded bits */ + INT scalefacBits; /* scalefac coded bits */ + INT noiseNrgBits; /* noiseEnergy coded bits */ + INT firstScf; /* first scf to be coded */ } SECTION_DATA; - -struct BITCNTR_STATE -{ - INT *bitLookUp; - INT *mergeGainLookUp; +struct BITCNTR_STATE { + INT* bitLookUp; + INT* mergeGainLookUp; }; +INT FDKaacEnc_BCNew(BITCNTR_STATE** phBC, UCHAR* dynamic_RAM); -INT FDKaacEnc_BCNew(BITCNTR_STATE **phBC - ,UCHAR* dynamic_RAM - ); - -void FDKaacEnc_BCClose(BITCNTR_STATE **phBC); - -#if defined(PNS_PRECOUNT_ENABLE) -INT noisePreCount(const INT *noiseNrg, INT maxSfb); -#endif +void FDKaacEnc_BCClose(BITCNTR_STATE** phBC); -INT FDKaacEnc_dynBitCount( - BITCNTR_STATE* const hBC, - const SHORT* const quantSpectrum, - const UINT* const maxValueInSfb, - const INT* const scalefac, - const INT blockType, - const INT sfbCnt, - const INT maxSfbPerGroup, - const INT sfbPerGroup, - const INT* const sfbOffset, - SECTION_DATA* const RESTRICT sectionData, - const INT* const noiseNrg, - const INT* const isBook, - const INT* const isScale, - const UINT syntaxFlags - ); +INT FDKaacEnc_dynBitCount(BITCNTR_STATE* const hBC, + const SHORT* const quantSpectrum, + const UINT* const maxValueInSfb, + const INT* const scalefac, const INT blockType, + const INT sfbCnt, const INT maxSfbPerGroup, + const INT sfbPerGroup, const INT* const sfbOffset, + SECTION_DATA* const RESTRICT sectionData, + const INT* const noiseNrg, const INT* const isBook, + const INT* const isScale, const UINT syntaxFlags); #endif diff --git a/libAACenc/src/grp_data.cpp b/libAACenc/src/grp_data.cpp index 465865f..bc9d85f 100644 --- a/libAACenc/src/grp_data.cpp +++ b/libAACenc/src/grp_data.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,194 +90,175 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M.Werner -/******************************** MPEG Audio Encoder ************************** + Description: Short block grouping - Initial author: M.Werner - contents/description: Short block grouping +*******************************************************************************/ -******************************************************************************/ #include "psy_const.h" #include "interface.h" /* -* this routine does not work in-place -*/ + * this routine does not work in-place + */ +/* + * Don't use fAddSaturate2() because it looses one bit accuracy which is + * usefull for quality. + */ static inline FIXP_DBL nrgAddSaturate(const FIXP_DBL a, const FIXP_DBL b) { - return ( (a>=(FIXP_DBL)MAXVAL_DBL-b) ? (FIXP_DBL)MAXVAL_DBL : (a + b) ); + return ((a >= (FIXP_DBL)MAXVAL_DBL - b) ? (FIXP_DBL)MAXVAL_DBL : (a + b)); } -void -FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ - SFB_THRESHOLD *sfbThreshold, /* in-out */ - SFB_ENERGY *sfbEnergy, /* in-out */ - SFB_ENERGY *sfbEnergyMS, /* in-out */ - SFB_ENERGY *sfbSpreadEnergy, - const INT sfbCnt, - const INT sfbActive, - const INT *sfbOffset, - const FIXP_DBL *sfbMinSnrLdData, - INT *groupedSfbOffset, /* out */ - INT *maxSfbPerGroup, /* out */ - FIXP_DBL *groupedSfbMinSnrLdData, - const INT noOfGroups, - const INT *groupLen, - const INT granuleLength) -{ - INT i,j; - INT line; /* counts through lines */ - INT sfb; /* counts through scalefactor bands */ - INT grp; /* counts through groups */ - INT wnd; /* counts through windows in a group */ - INT offset; /* needed in sfbOffset grouping */ +void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ + SFB_THRESHOLD *sfbThreshold, /* in-out */ + SFB_ENERGY *sfbEnergy, /* in-out */ + SFB_ENERGY *sfbEnergyMS, /* in-out */ + SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt, + const INT sfbActive, const INT *sfbOffset, + const FIXP_DBL *sfbMinSnrLdData, + INT *groupedSfbOffset, /* out */ + INT *maxSfbPerGroup, /* out */ + FIXP_DBL *groupedSfbMinSnrLdData, + const INT noOfGroups, const INT *groupLen, + const INT granuleLength) { + INT i, j; + INT line; /* counts through lines */ + INT sfb; /* counts through scalefactor bands */ + INT grp; /* counts through groups */ + INT wnd; /* counts through windows in a group */ + INT offset; /* needed in sfbOffset grouping */ INT highestSfb; + INT granuleLength_short = granuleLength / TRANS_FAC; - INT granuleLength_short = granuleLength/TRANS_FAC; + C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024)) /* for short blocks: regroup spectrum and */ /* group energies and thresholds according to grouping */ - C_ALLOC_SCRATCH_START(tmpSpectrum, FIXP_DBL, (1024)); /* calculate maxSfbPerGroup */ highestSfb = 0; - for (wnd = 0; wnd < TRANS_FAC; wnd++) - { - for (sfb = sfbActive-1; sfb >= highestSfb; sfb--) - { - for (line = sfbOffset[sfb+1]-1; line >= sfbOffset[sfb]; line--) - { - if ( mdctSpectrum[wnd*granuleLength_short+line] != FL2FXCONST_SPC(0.0) ) break; /* this band is not completely zero */ + for (wnd = 0; wnd < TRANS_FAC; wnd++) { + for (sfb = sfbActive - 1; sfb >= highestSfb; sfb--) { + for (line = sfbOffset[sfb + 1] - 1; line >= sfbOffset[sfb]; line--) { + if (mdctSpectrum[wnd * granuleLength_short + line] != + FL2FXCONST_SPC(0.0)) + break; /* this band is not completely zero */ } - if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */ + if (line >= sfbOffset[sfb]) break; /* this band was not completely zero */ } highestSfb = fixMax(highestSfb, sfb); } highestSfb = highestSfb > 0 ? highestSfb : 0; - *maxSfbPerGroup = highestSfb+1; + *maxSfbPerGroup = highestSfb + 1; /* calculate groupedSfbOffset */ i = 0; offset = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive+1; sfb++) - { - groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp]; - } - i += sfbCnt-sfb; - offset += groupLen[grp] * granuleLength_short; + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive + 1; sfb++) { + groupedSfbOffset[i++] = offset + sfbOffset[sfb] * groupLen[grp]; + } + i += sfbCnt - sfb; + offset += groupLen[grp] * granuleLength_short; } groupedSfbOffset[i++] = granuleLength; /* calculate groupedSfbMinSnr */ i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { groupedSfbMinSnrLdData[i++] = sfbMinSnrLdData[sfb]; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; } /* sum up sfbThresholds */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL thresh = sfbThreshold->Short[wnd][sfb]; - for (j=1; j<groupLen[grp]; j++) - { - thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + thresh = nrgAddSaturate(thresh, sfbThreshold->Short[wnd + j][sfb]); } sfbThreshold->Long[i++] = thresh; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbEnergies left/right */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbEnergy->Short[wnd][sfb]; - for (j=1; j<groupLen[grp]; j++) - { - energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbEnergy->Short[wnd + j][sfb]); } sfbEnergy->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbEnergies mid/side */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbEnergyMS->Short[wnd][sfb]; - for (j=1; j<groupLen[grp]; j++) - { - energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbEnergyMS->Short[wnd + j][sfb]); } sfbEnergyMS->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* sum up sfbSpreadEnergies */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { FIXP_DBL energy = sfbSpreadEnergy->Short[wnd][sfb]; - for (j=1; j<groupLen[grp]; j++) - { - energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd+j][sfb]); + for (j = 1; j < groupLen[grp]; j++) { + energy = nrgAddSaturate(energy, sfbSpreadEnergy->Short[wnd + j][sfb]); } sfbSpreadEnergy->Long[i++] = energy; } - i += sfbCnt-sfb; + i += sfbCnt - sfb; wnd += groupLen[grp]; } /* re-group spectrum */ wnd = 0; i = 0; - for (grp = 0; grp < noOfGroups; grp++) - { - for (sfb = 0; sfb < sfbActive; sfb++) - { - int width = sfbOffset[sfb+1]-sfbOffset[sfb]; - FIXP_DBL *pMdctSpectrum = &mdctSpectrum[sfbOffset[sfb]] + wnd*granuleLength_short; - for (j = 0; j < groupLen[grp]; j++) - { + for (grp = 0; grp < noOfGroups; grp++) { + for (sfb = 0; sfb < sfbActive; sfb++) { + int width = sfbOffset[sfb + 1] - sfbOffset[sfb]; + FIXP_DBL *pMdctSpectrum = + &mdctSpectrum[sfbOffset[sfb]] + wnd * granuleLength_short; + for (j = 0; j < groupLen[grp]; j++) { FIXP_DBL *pTmp = pMdctSpectrum; - for (line = width; line > 0; line--) - { + for (line = width; line > 0; line--) { tmpSpectrum[i++] = *pTmp++; } pMdctSpectrum += granuleLength_short; } } - i += (groupLen[grp]*(sfbOffset[sfbCnt]-sfbOffset[sfb])); + i += (groupLen[grp] * (sfbOffset[sfbCnt] - sfbOffset[sfb])); wnd += groupLen[grp]; } - FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength*sizeof(FIXP_DBL)); + FDKmemcpy(mdctSpectrum, tmpSpectrum, granuleLength * sizeof(FIXP_DBL)); C_ALLOC_SCRATCH_END(tmpSpectrum, FIXP_DBL, (1024)) } diff --git a/libAACenc/src/grp_data.h b/libAACenc/src/grp_data.h index f061855..3e1a708 100644 --- a/libAACenc/src/grp_data.h +++ b/libAACenc/src/grp_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,37 +90,34 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Short block grouping + Description: Short block grouping -******************************************************************************/ -#ifndef __GRP_DATA_H__ -#define __GRP_DATA_H__ +*******************************************************************************/ + +#ifndef GRP_DATA_H +#define GRP_DATA_H #include "common_fix.h" #include "psy_data.h" - -void -FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ - SFB_THRESHOLD *sfbThreshold, /* in-out */ - SFB_ENERGY *sfbEnergy, /* in-out */ - SFB_ENERGY *sfbEnergyMS, /* in-out */ - SFB_ENERGY *sfbSpreadEnergy, - const INT sfbCnt, - const INT sfbActive, - const INT *sfbOffset, - const FIXP_DBL *sfbMinSnrLdData, - INT *groupedSfbOffset, /* out */ - INT *maxSfbPerGroup, - FIXP_DBL *groupedSfbMinSnrLdData, - const INT noOfGroups, - const INT *groupLen, - const INT granuleLength); +void FDKaacEnc_groupShortData(FIXP_DBL *mdctSpectrum, /* in-out */ + SFB_THRESHOLD *sfbThreshold, /* in-out */ + SFB_ENERGY *sfbEnergy, /* in-out */ + SFB_ENERGY *sfbEnergyMS, /* in-out */ + SFB_ENERGY *sfbSpreadEnergy, const INT sfbCnt, + const INT sfbActive, const INT *sfbOffset, + const FIXP_DBL *sfbMinSnrLdData, + INT *groupedSfbOffset, /* out */ + INT *maxSfbPerGroup, + FIXP_DBL *groupedSfbMinSnrLdData, + const INT noOfGroups, const INT *groupLen, + const INT granuleLength); #endif /* _INTERFACE_H */ diff --git a/libAACenc/src/intensity.cpp b/libAACenc/src/intensity.cpp index b45b27b..a160a4f 100644 --- a/libAACenc/src/intensity.cpp +++ b/libAACenc/src/intensity.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,82 +90,94 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) - Initial author: A. Horndasch (code originally from lwr) / Josef Hoepfl (FDK) - contents/description: intensity stereo processing + Description: intensity stereo processing -******************************************************************************/ +*******************************************************************************/ #include "intensity.h" + #include "interface.h" #include "psy_configuration.h" #include "psy_const.h" #include "qc_main.h" #include "bit_cnt.h" -/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH */ -#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) +/* only set an IS seed it left/right channel correlation is above IS_CORR_THRESH + */ +#define IS_CORR_THRESH FL2FXCONST_DBL(0.95f) /* when expanding the IS region to more SFBs only accept an error that is * not more than IS_TOTAL_ERROR_THRESH overall and * not more than IS_LOCAL_ERROR_THRESH for the current SFB */ -#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) -#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) +#define IS_TOTAL_ERROR_THRESH FL2FXCONST_DBL(0.04f) +#define IS_LOCAL_ERROR_THRESH FL2FXCONST_DBL(0.01f) -/* the maximum allowed change of the intensity direction (unit: IS scale) - scaled with factor 0.25 - */ +/* the maximum allowed change of the intensity direction (unit: IS scale) - + * scaled with factor 0.25 - */ #define IS_DIRECTION_DEVIATION_THRESH_SF 2 -#define IS_DIRECTION_DEVIATION_THRESH FL2FXCONST_DBL(2.0f/(1<<IS_DIRECTION_DEVIATION_THRESH_SF)) +#define IS_DIRECTION_DEVIATION_THRESH \ + FL2FXCONST_DBL(2.0f / (1 << IS_DIRECTION_DEVIATION_THRESH_SF)) -/* IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ -#define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f) +/* IS regions need to have a minimal percentage of the overall loudness, e.g. + * 0.06 == 6% */ +#define IS_REGION_MIN_LOUDNESS FL2FXCONST_DBL(0.1f) /* only perform IS if IS_MIN_SFBS neighboring SFBs can be processed */ -#define IS_MIN_SFBS 6 +#define IS_MIN_SFBS 6 /* only do IS if - * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 / IS_LEFT_RIGHT_RATIO_THRESH + * if IS_LEFT_RIGHT_RATIO_THRESH < sfbEnergyLeft[sfb]/sfbEnergyRight[sfb] < 1 / + * IS_LEFT_RIGHT_RATIO_THRESH * -> no IS if the panning angle is not far from the middle, MS will do */ /* this is equivalent to a scale of +/-1.02914634566 */ -#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) +#define IS_LEFT_RIGHT_RATIO_THRESH FL2FXCONST_DBL(0.7f) /* scalefactor of realScale */ -#define REAL_SCALE_SF 1 +#define REAL_SCALE_SF 1 /* scalefactor overallLoudness */ -#define OVERALL_LOUDNESS_SF 6 +#define OVERALL_LOUDNESS_SF 6 /* scalefactor for sum over max samples per goup */ -#define MAX_SFB_PER_GROUP_SF 6 +#define MAX_SFB_PER_GROUP_SF 6 /* scalefactor for sum of mdct spectrum */ -#define MDCT_SPEC_SF 6 - - -typedef struct -{ +#define MDCT_SPEC_SF 6 - FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel correlation is above corr_thresh */ +typedef struct { + FIXP_DBL corr_thresh; /*!< Only set an IS seed it left/right channel + correlation is above corr_thresh */ - FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'total_error_thresh' overall. */ + FIXP_DBL total_error_thresh; /*!< When expanding the IS region to more SFBs + only accept an error that is not more than + 'total_error_thresh' overall. */ - FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs only accept an error that is - not more than 'local_error_thresh' for the current SFB. */ + FIXP_DBL local_error_thresh; /*!< When expanding the IS region to more SFBs + only accept an error that is not more than + 'local_error_thresh' for the current SFB. */ - FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the intensity direction (unit: IS scale) */ + FIXP_DBL direction_deviation_thresh; /*!< The maximum allowed change of the + intensity direction (unit: IS scale) + */ - FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal percentage of the overall loudness, e.g. 0.06 == 6% */ + FIXP_DBL is_region_min_loudness; /*!< IS regions need to have a minimal + percentage of the overall loudness, e.g. + 0.06 == 6% */ - INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be processed */ + INT min_is_sfbs; /*!< Only perform IS if 'min_is_sfbs' neighboring SFBs can be + processed */ - FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not far from the middle, MS will do */ + FIXP_DBL left_right_ratio_threshold; /*!< No IS if the panning angle is not + far from the middle, MS will do */ } INTENSITY_PARAMETERS; - /***************************************************************************** functionname: calcSfbMaxScale @@ -170,25 +193,22 @@ typedef struct returns: scalefactor *****************************************************************************/ -static INT -calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, - const INT l1, - const INT l2) -{ +static INT calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, const INT l1, + const INT l2) { INT i; INT sfbMaxScale; FIXP_DBL maxSpc; maxSpc = FL2FXCONST_DBL(0.0); - for (i=l1; i<l2; i++) { + for (i = l1; i < l2; i++) { FIXP_DBL tmp = fixp_abs((FIXP_DBL)mdctSpectrum[i]); maxSpc = fixMax(maxSpc, tmp); } - sfbMaxScale = (maxSpc==FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS-2) : CntLeadingZeros(maxSpc)-1; + sfbMaxScale = (maxSpc == FL2FXCONST_DBL(0.0)) ? (DFRACT_BITS - 2) + : CntLeadingZeros(maxSpc) - 1; return sfbMaxScale; - } - +} /***************************************************************************** @@ -203,19 +223,16 @@ calcSfbMaxScale(const FIXP_DBL *mdctSpectrum, returns: none *****************************************************************************/ -static void -FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) -{ - isParams->corr_thresh = IS_CORR_THRESH; - isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; - isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; +static void FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) { + isParams->corr_thresh = IS_CORR_THRESH; + isParams->total_error_thresh = IS_TOTAL_ERROR_THRESH; + isParams->local_error_thresh = IS_LOCAL_ERROR_THRESH; isParams->direction_deviation_thresh = IS_DIRECTION_DEVIATION_THRESH; - isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; - isParams->min_is_sfbs = IS_MIN_SFBS; + isParams->is_region_min_loudness = IS_REGION_MIN_LOUDNESS; + isParams->min_is_sfbs = IS_MIN_SFBS; isParams->left_right_ratio_threshold = IS_LEFT_RIGHT_RATIO_THRESH; } - /***************************************************************************** functionname: FDKaacEnc_prepareIntensityDecision @@ -238,24 +255,14 @@ FDKaacEnc_initIsParams(INTENSITY_PARAMETERS *isParams) returns: none *****************************************************************************/ -static void -FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, - const FIXP_DBL *sfbEnergyRight, - const FIXP_DBL *sfbEnergyLdDataLeft, - const FIXP_DBL *sfbEnergyLdDataRight, - const FIXP_DBL *mdctSpectrumLeft, - const FIXP_DBL *mdctSpectrumRight, - const INTENSITY_PARAMETERS *isParams, - FIXP_DBL *hrrErr, - INT *isMask, - FIXP_DBL *realScale, - FIXP_DBL *normSfbLoudness, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset) -{ - INT j,sfb,sfboffs; +static void FDKaacEnc_prepareIntensityDecision( + const FIXP_DBL *sfbEnergyLeft, const FIXP_DBL *sfbEnergyRight, + const FIXP_DBL *sfbEnergyLdDataLeft, const FIXP_DBL *sfbEnergyLdDataRight, + const FIXP_DBL *mdctSpectrumLeft, const FIXP_DBL *mdctSpectrumRight, + const INTENSITY_PARAMETERS *isParams, FIXP_DBL *hrrErr, INT *isMask, + FIXP_DBL *realScale, FIXP_DBL *normSfbLoudness, const INT sfbCnt, + const INT sfbPerGroup, const INT maxSfbPerGroup, const INT *sfbOffset) { + INT j, sfb, sfboffs; INT grpCounter; /* temporary variables to compute loudness */ @@ -269,149 +276,192 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, FIXP_DBL tmp_l, tmp_r; FIXP_DBL inv_n; - FDKmemclear(channelCorr, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS*sizeof(FIXP_DBL)); - FDKmemclear(realScale, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); + FDKmemclear(channelCorr, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemclear(normSfbLoudness, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemclear(overallLoudness, MAX_NO_OF_GROUPS * sizeof(FIXP_DBL)); + FDKmemclear(realScale, MAX_GROUPED_SFB * sizeof(FIXP_DBL)); - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { + for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; + sfboffs += sfbPerGroup, grpCounter++) { overallLoudness[grpCounter] = FL2FXCONST_DBL(0.0f); for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { - INT sL,sR,s; - FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb+sfboffs]-sfbEnergyLdDataRight[sfb+sfboffs]; + INT sL, sR, s; + FIXP_DBL isValue = sfbEnergyLdDataLeft[sfb + sfboffs] - + sfbEnergyLdDataRight[sfb + sfboffs]; /* delimitate intensity scale value to representable range */ - realScale[sfb + sfboffs] = fixMin(FL2FXCONST_DBL(60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), fixMax(FL2FXCONST_DBL(-60.f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT))), isValue)); - - sL = fixMax(0,(CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs])-1)); - sR = fixMax(0,(CntLeadingZeros(sfbEnergyRight[sfb + sfboffs])-1)); - s = (fixMin(sL,sR)>>2)<<2; - normSfbLoudness[sfb + sfboffs] = sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs]<<s) >> 1) + ((sfbEnergyRight[sfb + sfboffs]<<s) >> 1))) >> (s>>2); - - overallLoudness[grpCounter] += normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; + realScale[sfb + sfboffs] = fixMin( + FL2FXCONST_DBL(60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))), + fixMax(FL2FXCONST_DBL(-60.f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT))), + isValue)); + + sL = fixMax(0, (CntLeadingZeros(sfbEnergyLeft[sfb + sfboffs]) - 1)); + sR = fixMax(0, (CntLeadingZeros(sfbEnergyRight[sfb + sfboffs]) - 1)); + s = (fixMin(sL, sR) >> 2) << 2; + normSfbLoudness[sfb + sfboffs] = + sqrtFixp(sqrtFixp(((sfbEnergyLeft[sfb + sfboffs] << s) >> 1) + + ((sfbEnergyRight[sfb + sfboffs] << s) >> 1))) >> + (s >> 2); + + overallLoudness[grpCounter] += + normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF; /* don't do intensity if * - panning angle is too close to the middle or * - one channel is non-existent or * - if it is dual mono */ - if( (sfbEnergyLeft[sfb + sfboffs] >= fMult(isParams->left_right_ratio_threshold,sfbEnergyRight[sfb + sfboffs])) - && (fMult(isParams->left_right_ratio_threshold,sfbEnergyLeft[sfb + sfboffs]) <= sfbEnergyRight[sfb + sfboffs]) ) { - - /* this will prevent post processing from considering this SFB for merging */ - hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0/8.0); + if ((sfbEnergyLeft[sfb + sfboffs] >= + fMult(isParams->left_right_ratio_threshold, + sfbEnergyRight[sfb + sfboffs])) && + (fMult(isParams->left_right_ratio_threshold, + sfbEnergyLeft[sfb + sfboffs]) <= + sfbEnergyRight[sfb + sfboffs])) { + /* this will prevent post processing from considering this SFB for + * merging */ + hrrErr[sfb + sfboffs] = FL2FXCONST_DBL(1.0 / 8.0); } } } - for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; sfboffs += sfbPerGroup, grpCounter++) { + for (grpCounter = 0, sfboffs = 0; sfboffs < sfbCnt; + sfboffs += sfbPerGroup, grpCounter++) { INT invOverallLoudnessSF; FIXP_DBL invOverallLoudness; if (overallLoudness[grpCounter] == FL2FXCONST_DBL(0.0)) { invOverallLoudness = FL2FXCONST_DBL(0.0); invOverallLoudnessSF = 0; + } else { + invOverallLoudness = + fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter], + &invOverallLoudnessSF); + invOverallLoudnessSF = + invOverallLoudnessSF - OVERALL_LOUDNESS_SF + + 1; /* +1: compensate fMultDiv2() in subsequent loop */ } - else { - invOverallLoudness = fDivNorm((FIXP_DBL)MAXVAL_DBL, overallLoudness[grpCounter],&invOverallLoudnessSF); - invOverallLoudnessSF = invOverallLoudnessSF - OVERALL_LOUDNESS_SF + 1; /* +1: compensate fMultDiv2() in subsequent loop */ - } - invOverallLoudnessSF = fixMin(fixMax(invOverallLoudnessSF,-(DFRACT_BITS-1)),DFRACT_BITS-1); + invOverallLoudnessSF = fixMin( + fixMax(invOverallLoudnessSF, -(DFRACT_BITS - 1)), DFRACT_BITS - 1); for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { FIXP_DBL tmp; - tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs]>>OVERALL_LOUDNESS_SF)<<OVERALL_LOUDNESS_SF,invOverallLoudness); + tmp = fMultDiv2((normSfbLoudness[sfb + sfboffs] >> OVERALL_LOUDNESS_SF) + << OVERALL_LOUDNESS_SF, + invOverallLoudness); normSfbLoudness[sfb + sfboffs] = scaleValue(tmp, invOverallLoudnessSF); channelCorr[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); /* max width of scalefactorband is 96; width's are always even */ - /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent loops */ - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); + /* inv_n is scaled with factor 2 to compensate fMultDiv2() in subsequent + * loops */ + inv_n = GetInvInt( + (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> 1); if (inv_n > FL2FXCONST_DBL(0.0f)) { - INT s,sL,sR; + INT s, sL, sR; /* correlation := Pearson's product-moment coefficient */ - /* compute correlation between channels and check if it is over threshold */ - ml = FL2FXCONST_DBL(0.0f); - mr = FL2FXCONST_DBL(0.0f); - prod_lr = FL2FXCONST_DBL(0.0f); + /* compute correlation between channels and check if it is over + * threshold */ + ml = FL2FXCONST_DBL(0.0f); + mr = FL2FXCONST_DBL(0.0f); + prod_lr = FL2FXCONST_DBL(0.0f); square_l = FL2FXCONST_DBL(0.0f); square_r = FL2FXCONST_DBL(0.0f); - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - s = fixMin(sL,sR); - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - ml += fMultDiv2((mdctSpectrumLeft[j] << s),inv_n); // scaled with mdctScale - s + inv_n - mr += fMultDiv2((mdctSpectrumRight[j] << s),inv_n); // scaled with mdctScale - s + inv_n + sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + s = fixMin(sL, sR); + + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + ml += fMultDiv2((mdctSpectrumLeft[j] << s), + inv_n); // scaled with mdctScale - s + inv_n + mr += fMultDiv2((mdctSpectrumRight[j] << s), + inv_n); // scaled with mdctScale - s + inv_n } - ml = fMultDiv2(ml,inv_n); // scaled with mdctScale - s + inv_n - mr = fMultDiv2(mr,inv_n); // scaled with mdctScale - s + inv_n - - for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) { - tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s),inv_n) - ml; // scaled with mdctScale - s + inv_n - tmp_r = fMultDiv2((mdctSpectrumRight[j] << s),inv_n) - mr; // scaled with mdctScale - s + inv_n - - prod_lr += fMultDiv2(tmp_l,tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_l += fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 - square_r += fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 + ml = fMultDiv2(ml, inv_n); // scaled with mdctScale - s + inv_n + mr = fMultDiv2(mr, inv_n); // scaled with mdctScale - s + inv_n + + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + tmp_l = fMultDiv2((mdctSpectrumLeft[j] << s), inv_n) - + ml; // scaled with mdctScale - s + inv_n + tmp_r = fMultDiv2((mdctSpectrumRight[j] << s), inv_n) - + mr; // scaled with mdctScale - s + inv_n + + prod_lr += fMultDiv2( + tmp_l, tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 + square_l += + fPow2Div2(tmp_l); // scaled with 2*(mdctScale - s + inv_n) + 1 + square_r += + fPow2Div2(tmp_r); // scaled with 2*(mdctScale - s + inv_n) + 1 } - prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) - square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) - square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) + prod_lr = prod_lr << 1; // scaled with 2*(mdctScale - s + inv_n) + square_l = square_l << 1; // scaled with 2*(mdctScale - s + inv_n) + square_r = square_r << 1; // scaled with 2*(mdctScale - s + inv_n) - if (square_l > FL2FXCONST_DBL(0.0f) && square_r > FL2FXCONST_DBL(0.0f)) { + if (square_l > FL2FXCONST_DBL(0.0f) && + square_r > FL2FXCONST_DBL(0.0f)) { INT channelCorrSF = 0; - /* local scaling of square_l and square_r is compensated after sqrt calculation */ - sL = fixMax(0,(CntLeadingZeros(square_l)-1)); - sR = fixMax(0,(CntLeadingZeros(square_r)-1)); - s = ((sL + sR)>>1)<<1; - sL = fixMin(sL,s); - sR = s-sL; - tmp = fMult(square_l<<sL,square_r<<sR); + /* local scaling of square_l and square_r is compensated after sqrt + * calculation */ + sL = fixMax(0, (CntLeadingZeros(square_l) - 1)); + sR = fixMax(0, (CntLeadingZeros(square_r) - 1)); + s = ((sL + sR) >> 1) << 1; + sL = fixMin(sL, s); + sR = s - sL; + tmp = fMult(square_l << sL, square_r << sR); tmp = sqrtFixp(tmp); FDK_ASSERT(tmp > FL2FXCONST_DBL(0.0f)); /* numerator and denominator have the same scaling */ - if (prod_lr < FL2FXCONST_DBL(0.0f) ) { - channelCorr[sfb + sfboffs] = -(fDivNorm(-prod_lr,tmp,&channelCorrSF)); + if (prod_lr < FL2FXCONST_DBL(0.0f)) { + channelCorr[sfb + sfboffs] = + -(fDivNorm(-prod_lr, tmp, &channelCorrSF)); + } else { + channelCorr[sfb + sfboffs] = + (fDivNorm(prod_lr, tmp, &channelCorrSF)); } - else { - channelCorr[sfb + sfboffs] = (fDivNorm( prod_lr,tmp,&channelCorrSF)); - } - channelCorrSF = fixMin(fixMax(( channelCorrSF + ((sL+sR)>>1)),-(DFRACT_BITS-1)),DFRACT_BITS-1); + channelCorrSF = fixMin( + fixMax((channelCorrSF + ((sL + sR) >> 1)), -(DFRACT_BITS - 1)), + DFRACT_BITS - 1); if (channelCorrSF < 0) { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] >> (-channelCorrSF); - } - else { + channelCorr[sfb + sfboffs] = + channelCorr[sfb + sfboffs] >> (-channelCorrSF); + } else { /* avoid overflows due to limited computational accuracy */ - if ( fAbs(channelCorr[sfb + sfboffs]) > (((FIXP_DBL)MAXVAL_DBL)>>channelCorrSF) ) { + if (fAbs(channelCorr[sfb + sfboffs]) > + (((FIXP_DBL)MAXVAL_DBL) >> channelCorrSF)) { if (channelCorr[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) - channelCorr[sfb + sfboffs] = -(FIXP_DBL) MAXVAL_DBL; + channelCorr[sfb + sfboffs] = -(FIXP_DBL)MAXVAL_DBL; else - channelCorr[sfb + sfboffs] = (FIXP_DBL) MAXVAL_DBL; - } - else { - channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] << channelCorrSF; + channelCorr[sfb + sfboffs] = (FIXP_DBL)MAXVAL_DBL; + } else { + channelCorr[sfb + sfboffs] = channelCorr[sfb + sfboffs] + << channelCorrSF; } } } } - /* for post processing: hrrErr is the error in terms of (too little) correlation - * weighted with the loudness of the SFB; SFBs with small hrrErr can be merged */ - if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0/8.0)) { + /* for post processing: hrrErr is the error in terms of (too little) + * correlation weighted with the loudness of the SFB; SFBs with small + * hrrErr can be merged */ + if (hrrErr[sfb + sfboffs] == FL2FXCONST_DBL(1.0 / 8.0)) { continue; } - hrrErr[sfb + sfboffs] = fMultDiv2((FL2FXCONST_DBL(0.25f)-(channelCorr[sfb + sfboffs]>>2)),normSfbLoudness[sfb + sfboffs]); + hrrErr[sfb + sfboffs] = + fMultDiv2((FL2FXCONST_DBL(0.25f) - (channelCorr[sfb + sfboffs] >> 2)), + normSfbLoudness[sfb + sfboffs]); /* set IS mask/vector to 1, if correlation is high enough */ if (fAbs(channelCorr[sfb + sfboffs]) >= isParams->corr_thresh) { @@ -421,7 +471,6 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, } } - /***************************************************************************** functionname: FDKaacEnc_finalizeIntensityDecision @@ -438,17 +487,11 @@ FDKaacEnc_prepareIntensityDecision(const FIXP_DBL *sfbEnergyLeft, returns: none *****************************************************************************/ -static void -FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, - INT *isMask, - const FIXP_DBL *realIsScale, - const FIXP_DBL *normSfbLoudness, - const INTENSITY_PARAMETERS *isParams, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup) -{ - INT sfb,sfboffs, j; +static void FDKaacEnc_finalizeIntensityDecision( + const FIXP_DBL *hrrErr, INT *isMask, const FIXP_DBL *realIsScale, + const FIXP_DBL *normSfbLoudness, const INTENSITY_PARAMETERS *isParams, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup) { + INT sfb, sfboffs, j; FIXP_DBL isScaleLast = FL2FXCONST_DBL(0.0f); INT isStartValueFound = 0; @@ -464,26 +507,30 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, if (currentIsSfbCount == 0) { startIsSfb = sfboffs + sfb; } - if (isStartValueFound==0) { + if (isStartValueFound == 0) { isScaleLast = realIsScale[sfboffs + sfb]; isStartValueFound = 1; } inIsBlock = 1; currentIsSfbCount++; - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - } - else { + overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3); + isRegionLoudness += + normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; + } else { /* based on correlation, IS should not be used * -> use it anyway, if overall error is below threshold * and if local error does not exceed threshold * otherwise: check if there are enough IS SFBs */ if (inIsBlock) { - overallHrrError += hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF-3); - isRegionLoudness += normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; - - if ( (hrrErr[sfboffs + sfb] < (isParams->local_error_thresh>>3)) && (overallHrrError < (isParams->total_error_thresh>>MAX_SFB_PER_GROUP_SF)) ) { + overallHrrError += + hrrErr[sfboffs + sfb] >> (MAX_SFB_PER_GROUP_SF - 3); + isRegionLoudness += + normSfbLoudness[sfboffs + sfb] >> MAX_SFB_PER_GROUP_SF; + + if ((hrrErr[sfboffs + sfb] < (isParams->local_error_thresh >> 3)) && + (overallHrrError < + (isParams->total_error_thresh >> MAX_SFB_PER_GROUP_SF))) { currentIsSfbCount++; /* overwrite correlation based decision */ isMask[sfboffs + sfb] = 1; @@ -494,10 +541,12 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, } /* check for large direction deviation */ if (inIsBlock) { - if( fAbs(isScaleLast-realIsScale[sfboffs + sfb]) < (isParams->direction_deviation_thresh>>(REAL_SCALE_SF+LD_DATA_SHIFT-IS_DIRECTION_DEVIATION_THRESH_SF)) ) { + if (fAbs(isScaleLast - realIsScale[sfboffs + sfb]) < + (isParams->direction_deviation_thresh >> + (REAL_SCALE_SF + LD_DATA_SHIFT - + IS_DIRECTION_DEVIATION_THRESH_SF))) { isScaleLast = realIsScale[sfboffs + sfb]; - } - else{ + } else { isMask[sfboffs + sfb] = 0; inIsBlock = 0; currentIsSfbCount--; @@ -506,14 +555,16 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, if (currentIsSfbCount > 0 && (!inIsBlock || sfb == maxSfbPerGroup - 1)) { /* not enough SFBs -> do not use IS */ - if (currentIsSfbCount < isParams->min_is_sfbs || (isRegionLoudness < isParams->is_region_min_loudness>>MAX_SFB_PER_GROUP_SF)) { - for(j = startIsSfb; j <= sfboffs + sfb; j++) { + if (currentIsSfbCount < isParams->min_is_sfbs || + (isRegionLoudness<isParams->is_region_min_loudness>> + MAX_SFB_PER_GROUP_SF)) { + for (j = startIsSfb; j <= sfboffs + sfb; j++) { isMask[j] = 0; } isScaleLast = FL2FXCONST_DBL(0.0f); isStartValueFound = 0; - for (j=0; j < startIsSfb; j++) { - if (isMask[j]!=0) { + for (j = 0; j < startIsSfb; j++) { + if (isMask[j] != 0) { isScaleLast = realIsScale[j]; isStartValueFound = 1; } @@ -527,7 +578,6 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, } } - /***************************************************************************** functionname: FDKaacEnc_IntensityStereoProcessing @@ -555,36 +605,23 @@ FDKaacEnc_finalizeIntensityDecision(const FIXP_DBL *hrrErr, sfbSpreadEnRight zeroed where isBook!=0 sfbThresholdRight zeroed where isBook!=0 sfbEnergyLdDataRight FL2FXCONST_DBL(-1.0) where isBook!=0 - sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where isBook!=0 + sfbThresholdLdDataRight FL2FXCONST_DBL(-0.515625f) where +isBook!=0 returns: none *****************************************************************************/ void FDKaacEnc_IntensityStereoProcessing( - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *mdctSpectrumLeft, - FIXP_DBL *mdctSpectrumRight, - FIXP_DBL *sfbThresholdLeft, - FIXP_DBL *sfbThresholdRight, - FIXP_DBL *sfbThresholdLdDataRight, - FIXP_DBL *sfbSpreadEnLeft, - FIXP_DBL *sfbSpreadEnRight, - FIXP_DBL *sfbEnergyLdDataLeft, - FIXP_DBL *sfbEnergyLdDataRight, - INT *msDigest, - INT *msMask, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset, - const INT allowIS, - INT *isBook, - INT *isScale, - PNS_DATA *RESTRICT pnsData[2] - ) -{ - INT sfb,sfboffs, j; + FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight, + FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight, + FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft, + FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft, + FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale, + PNS_DATA *RESTRICT pnsData[2]) { + INT sfb, sfboffs, j; FIXP_DBL scale; FIXP_DBL lr; FIXP_DBL hrrErr[MAX_GROUPED_SFB]; @@ -593,14 +630,13 @@ void FDKaacEnc_IntensityStereoProcessing( INTENSITY_PARAMETERS isParams; INT isMask[MAX_GROUPED_SFB]; - FDKmemclear((void*)isBook,sfbCnt*sizeof(INT)); - FDKmemclear((void*)isMask,sfbCnt*sizeof(INT)); - FDKmemclear((void*)realIsScale,sfbCnt*sizeof(FIXP_DBL)); - FDKmemclear((void*)isScale,sfbCnt*sizeof(INT)); - FDKmemclear((void*)hrrErr,sfbCnt*sizeof(FIXP_DBL)); + FDKmemclear((void *)isBook, sfbCnt * sizeof(INT)); + FDKmemclear((void *)isMask, sfbCnt * sizeof(INT)); + FDKmemclear((void *)realIsScale, sfbCnt * sizeof(FIXP_DBL)); + FDKmemclear((void *)isScale, sfbCnt * sizeof(INT)); + FDKmemclear((void *)hrrErr, sfbCnt * sizeof(FIXP_DBL)); - if (!allowIS) - return; + if (!allowIS) return; FDKaacEnc_initIsParams(&isParams); @@ -611,150 +647,164 @@ void FDKaacEnc_IntensityStereoProcessing( * + normalization: division by sum of all SFB loudnesses * - isMask (is set to 0 if channels are the same or one is 0) */ - FDKaacEnc_prepareIntensityDecision(sfbEnergyLeft, - sfbEnergyRight, - sfbEnergyLdDataLeft, - sfbEnergyLdDataRight, - mdctSpectrumLeft, - mdctSpectrumRight, - &isParams, - hrrErr, - isMask, - realIsScale, - normSfbLoudness, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup, - sfbOffset); - - FDKaacEnc_finalizeIntensityDecision(hrrErr, - isMask, - realIsScale, - normSfbLoudness, - &isParams, - sfbCnt, - sfbPerGroup, - maxSfbPerGroup); - - for (sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) { - for (sfboffs=0; sfboffs<maxSfbPerGroup; sfboffs++) { + FDKaacEnc_prepareIntensityDecision( + sfbEnergyLeft, sfbEnergyRight, sfbEnergyLdDataLeft, sfbEnergyLdDataRight, + mdctSpectrumLeft, mdctSpectrumRight, &isParams, hrrErr, isMask, + realIsScale, normSfbLoudness, sfbCnt, sfbPerGroup, maxSfbPerGroup, + sfbOffset); + + FDKaacEnc_finalizeIntensityDecision(hrrErr, isMask, realIsScale, + normSfbLoudness, &isParams, sfbCnt, + sfbPerGroup, maxSfbPerGroup); + + for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { + for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { INT sL, sR; FIXP_DBL inv_n; - msMask[sfb+sfboffs] = 0; - if (isMask[sfb+sfboffs] == 0) { + msMask[sfb + sfboffs] = 0; + if (isMask[sfb + sfboffs] == 0) { continue; } - if ( (sfbEnergyLeft[sfb+sfboffs] < sfbThresholdLeft[sfb+sfboffs]) - &&(fMult(FL2FXCONST_DBL(1.0f/1.5f),sfbEnergyRight[sfb+sfboffs]) > sfbThresholdRight[sfb+sfboffs]) ) { + if ((sfbEnergyLeft[sfb + sfboffs] < sfbThresholdLeft[sfb + sfboffs]) && + (fMult(FL2FXCONST_DBL(1.0f / 1.5f), sfbEnergyRight[sfb + sfboffs]) > + sfbThresholdRight[sfb + sfboffs])) { continue; } /* NEW: if there is a big-enough IS region, switch off PNS */ if (pnsData[0]) { - if(pnsData[0]->pnsFlag[sfb+sfboffs]) { - pnsData[0]->pnsFlag[sfb+sfboffs] = 0; + if (pnsData[0]->pnsFlag[sfb + sfboffs]) { + pnsData[0]->pnsFlag[sfb + sfboffs] = 0; } - if(pnsData[1]->pnsFlag[sfb+sfboffs]) { - pnsData[1]->pnsFlag[sfb+sfboffs] = 0; + if (pnsData[1]->pnsFlag[sfb + sfboffs]) { + pnsData[1]->pnsFlag[sfb + sfboffs] = 0; } } - inv_n = GetInvInt((sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs])>>1); // scaled with 2 to compensate fMultDiv2() in subsequent loop - sL = calcSfbMaxScale(mdctSpectrumLeft,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); - sR = calcSfbMaxScale(mdctSpectrumRight,sfbOffset[sfb+sfboffs],sfbOffset[sfb+sfboffs+1]); + inv_n = GetInvInt( + (sfbOffset[sfb + sfboffs + 1] - sfbOffset[sfb + sfboffs]) >> + 1); // scaled with 2 to compensate fMultDiv2() in subsequent loop + sL = calcSfbMaxScale(mdctSpectrumLeft, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); + sR = calcSfbMaxScale(mdctSpectrumRight, sfbOffset[sfb + sfboffs], + sfbOffset[sfb + sfboffs + 1]); lr = FL2FXCONST_DBL(0.0f); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) - lr += fMultDiv2(fMultDiv2(mdctSpectrumLeft[j]<<sL,mdctSpectrumRight[j]<<sR),inv_n); - lr = lr<<1; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; j++) + lr += fMultDiv2( + fMultDiv2(mdctSpectrumLeft[j] << sL, mdctSpectrumRight[j] << sR), + inv_n); + lr = lr << 1; if (lr < FL2FXCONST_DBL(0.0f)) { /* This means OUT OF phase intensity stereo, cf. standard */ INT s0, s1, s2; FIXP_DBL tmp, d, ed = FL2FXCONST_DBL(0.0f); - s0 = fixMin(sL,sR); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - d = ((mdctSpectrumLeft[j]<<s0)>>1) - ((mdctSpectrumRight[j]<<s0)>>1); - ed += fMultDiv2(d,d)>>(MDCT_SPEC_SF-1); + s0 = fixMin(sL, sR); + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + d = ((mdctSpectrumLeft[j] << s0) >> 1) - + ((mdctSpectrumRight[j] << s0) >> 1); + ed += fMultDiv2(d, d) >> (MDCT_SPEC_SF - 1); } - msMask[sfb+sfboffs] = 1; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],ed,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; + msMask[sfb + sfboffs] = 1; + tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], ed, &s1); + s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF; if (s2 & 1) { - tmp = tmp>>1; - s2 = s2+1; + tmp = tmp >> 1; + s2 = s2 + 1; } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); + s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop + s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1)); scale = sqrtFixp(tmp); if (s2 < 0) { s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) - + fMultDiv2(mdctSpectrumRight[j], scale)) >> + s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) - fMultDiv2(mdctSpectrumRight[j],scale)) << s2; + } else { + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) - + fMultDiv2(mdctSpectrumRight[j], scale)) + << s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } } - } - else { + } else { /* This means IN phase intensity stereo, cf. standard */ - INT s0,s1,s2; + INT s0, s1, s2; FIXP_DBL tmp, s, es = FL2FXCONST_DBL(0.0f); - s0 = fixMin(sL,sR); - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - s = ((mdctSpectrumLeft[j]<<s0)>>1) + ((mdctSpectrumRight[j]<<s0)>>1); - es += fMultDiv2(s,s)>>(MDCT_SPEC_SF-1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF + s0 = fixMin(sL, sR); + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + s = ((mdctSpectrumLeft[j] << s0) >> 1) + + ((mdctSpectrumRight[j] << s0) >> 1); + es += fMultDiv2(s, s) >> + (MDCT_SPEC_SF - + 1); // scaled 2*(mdctScale - s0 + 1) + MDCT_SPEC_SF } - msMask[sfb+sfboffs] = 0; - tmp = fDivNorm(sfbEnergyLeft[sfb+sfboffs],es,&s1); - s2 = (s1) + (2*s0) - 2 - MDCT_SPEC_SF; + msMask[sfb + sfboffs] = 0; + tmp = fDivNorm(sfbEnergyLeft[sfb + sfboffs], es, &s1); + s2 = (s1) + (2 * s0) - 2 - MDCT_SPEC_SF; if (s2 & 1) { - tmp = tmp>>1; + tmp = tmp >> 1; s2 = s2 + 1; } - s2 = (s2>>1) + 1; // +1 compensate fMultDiv2() in subsequent loop - s2 = fixMin(fixMax(s2,-(DFRACT_BITS-1)),(DFRACT_BITS-1)); + s2 = (s2 >> 1) + 1; // +1 compensate fMultDiv2() in subsequent loop + s2 = fixMin(fixMax(s2, -(DFRACT_BITS - 1)), (DFRACT_BITS - 1)); scale = sqrtFixp(tmp); if (s2 < 0) { s2 = -s2; - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) >> s2; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) + + fMultDiv2(mdctSpectrumRight[j], scale)) >> + s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } - } - else { - for (j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j],scale) + fMultDiv2(mdctSpectrumRight[j],scale)) << s2; + } else { + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + mdctSpectrumLeft[j] = (fMultDiv2(mdctSpectrumLeft[j], scale) + + fMultDiv2(mdctSpectrumRight[j], scale)) + << s2; mdctSpectrumRight[j] = FL2FXCONST_DBL(0.0f); } } } - isBook[sfb+sfboffs] = CODE_BOOK_IS_IN_PHASE_NO; - - if ( realIsScale[sfb+sfboffs] < FL2FXCONST_DBL(0.0f) ) { - isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)-FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)) + 1; - } - else { - isScale[sfb+sfboffs] = (INT)(((realIsScale[sfb+sfboffs]>>1)+FL2FXCONST_DBL(0.5f/(1<<(REAL_SCALE_SF+LD_DATA_SHIFT+1))))>>(DFRACT_BITS-1-REAL_SCALE_SF-LD_DATA_SHIFT-1)); + isBook[sfb + sfboffs] = CODE_BOOK_IS_IN_PHASE_NO; + + if (realIsScale[sfb + sfboffs] < FL2FXCONST_DBL(0.0f)) { + isScale[sfb + sfboffs] = + (INT)(((realIsScale[sfb + sfboffs] >> 1) - + FL2FXCONST_DBL( + 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >> + (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)) + + 1; + } else { + isScale[sfb + sfboffs] = + (INT)(((realIsScale[sfb + sfboffs] >> 1) + + FL2FXCONST_DBL( + 0.5f / (1 << (REAL_SCALE_SF + LD_DATA_SHIFT + 1)))) >> + (DFRACT_BITS - 1 - REAL_SCALE_SF - LD_DATA_SHIFT - 1)); } - sfbEnergyRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbEnergyLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-1.0f); - sfbThresholdRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); - sfbThresholdLdDataRight[sfb+sfboffs] = FL2FXCONST_DBL(-0.515625f); - sfbSpreadEnRight[sfb+sfboffs] = FL2FXCONST_DBL(0.0f); + sfbEnergyRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); + sfbEnergyLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-1.0f); + sfbThresholdRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); + sfbThresholdLdDataRight[sfb + sfboffs] = FL2FXCONST_DBL(-0.515625f); + sfbSpreadEnRight[sfb + sfboffs] = FL2FXCONST_DBL(0.0f); *msDigest = MS_SOME; } } } - diff --git a/libAACenc/src/intensity.h b/libAACenc/src/intensity.h index 2acc292..70f23d5 100644 --- a/libAACenc/src/intensity.h +++ b/libAACenc/src/intensity.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,44 +90,32 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: A. Horndasch (code originally from lwr and rtb) / Josef Höpfl (FDK) - contents/description: intensity stereo prototype + Author(s): A. Horndasch (code originally from lwr and rtb) / Josef Hoepfl +(FDK) -******************************************************************************/ + Description: intensity stereo prototype -#ifndef _INTENSITY_H -#define _INTENSITY_H +*******************************************************************************/ -#include "aacenc_pns.h" +#ifndef INTENSITY_H +#define INTENSITY_H +#include "aacenc_pns.h" +#include "common_fix.h" void FDKaacEnc_IntensityStereoProcessing( - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *mdctSpectrumLeft, - FIXP_DBL *mdctSpectrumRight, - FIXP_DBL *sfbThresholdLeft, - FIXP_DBL *sfbThresholdRight, - FIXP_DBL *sfbThresholdLdDataRight, - FIXP_DBL *sfbSpreadEnLeft, - FIXP_DBL *sfbSpreadEnRight, - FIXP_DBL *sfbEnergyLdDataLeft, - FIXP_DBL *sfbEnergyLdDataRight, - INT *msDigest, - INT *msMask, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset, - const INT allowIS, - INT *isBook, - INT *isScale, - PNS_DATA *RESTRICT pnsData[2] - ); - -#endif /* _INTENSITY_H */ - + FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *mdctSpectrumLeft, FIXP_DBL *mdctSpectrumRight, + FIXP_DBL *sfbThresholdLeft, FIXP_DBL *sfbThresholdRight, + FIXP_DBL *sfbThresholdLdDataRight, FIXP_DBL *sfbSpreadEnLeft, + FIXP_DBL *sfbSpreadEnRight, FIXP_DBL *sfbEnergyLdDataLeft, + FIXP_DBL *sfbEnergyLdDataRight, INT *msDigest, INT *msMask, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + const INT *sfbOffset, const INT allowIS, INT *isBook, INT *isScale, + PNS_DATA *RESTRICT pnsData[2]); + +#endif /* INTENSITY_H */ diff --git a/libAACenc/src/interface.h b/libAACenc/src/interface.h index 51fb72a..b1a31ef 100644 --- a/libAACenc/src/interface.h +++ b/libAACenc/src/interface.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Interface psychoaccoustic/quantizer + Description: Interface psychoaccoustic/quantizer -******************************************************************************/ +*******************************************************************************/ -#ifndef _INTERFACE_H -#define _INTERFACE_H +#ifndef INTERFACE_H +#define INTERFACE_H #include "common_fix.h" #include "FDK_audio.h" @@ -97,73 +109,60 @@ amm-info@iis.fraunhofer.de #include "psy_data.h" #include "aacenc_tns.h" -enum -{ - MS_NONE = 0, - MS_SOME = 1, - MS_ALL = 2 -}; +enum { MS_NONE = 0, MS_SOME = 1, MS_ALL = 2 }; -enum -{ - MS_ON = 1 -}; +enum { MS_ON = 1 }; struct TOOLSINFO { - INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */ + INT msDigest; /* 0 = no MS; 1 = some MS, 2 = all MS */ INT msMask[MAX_GROUPED_SFB]; }; - -typedef struct { - INT sfbCnt; - INT sfbPerGroup; - INT maxSfbPerGroup; - INT lastWindowSequence; - INT windowShape; - INT groupingMask; - INT sfbOffsets[MAX_GROUPED_SFB+1]; - - INT mdctScale; /* number of transform shifts */ - INT groupLen[MAX_NO_OF_GROUPS]; - - TNS_INFO tnsInfo; - INT noiseNrg[MAX_GROUPED_SFB]; - INT isBook[MAX_GROUPED_SFB]; - INT isScale[MAX_GROUPED_SFB]; +typedef struct { + INT sfbCnt; + INT sfbPerGroup; + INT maxSfbPerGroup; + INT lastWindowSequence; + INT windowShape; + INT groupingMask; + INT sfbOffsets[MAX_GROUPED_SFB + 1]; + + INT mdctScale; /* number of transform shifts */ + INT groupLen[MAX_NO_OF_GROUPS]; + + TNS_INFO tnsInfo; + INT noiseNrg[MAX_GROUPED_SFB]; + INT isBook[MAX_GROUPED_SFB]; + INT isScale[MAX_GROUPED_SFB]; /* memory located in QC_OUT_CHANNEL */ - FIXP_DBL *mdctSpectrum; - FIXP_DBL *sfbEnergy; - FIXP_DBL *sfbSpreadEnergy; - FIXP_DBL *sfbThresholdLdData; - FIXP_DBL *sfbMinSnrLdData; - FIXP_DBL *sfbEnergyLdData; - + FIXP_DBL *mdctSpectrum; + FIXP_DBL *sfbEnergy; + FIXP_DBL *sfbSpreadEnergy; + FIXP_DBL *sfbThresholdLdData; + FIXP_DBL *sfbMinSnrLdData; + FIXP_DBL *sfbEnergyLdData; - }PSY_OUT_CHANNEL; +} PSY_OUT_CHANNEL; typedef struct { - /* information specific to each channel */ - PSY_OUT_CHANNEL* psyOutChannel[(2)]; + PSY_OUT_CHANNEL *psyOutChannel[(2)]; /* information shared by both channels */ - INT commonWindow; + INT commonWindow; struct TOOLSINFO toolsInfo; } PSY_OUT_ELEMENT; typedef struct { + PSY_OUT_ELEMENT *psyOutElement[((8))]; + PSY_OUT_CHANNEL *pPsyOutChannels[(8)]; - PSY_OUT_ELEMENT* psyOutElement[(8)]; - PSY_OUT_CHANNEL* pPsyOutChannels[(8)]; - -}PSY_OUT; +} PSY_OUT; -inline int isLowDelay( AUDIO_OBJECT_TYPE aot ) -{ - return (aot==AOT_ER_AAC_LD || aot==AOT_ER_AAC_ELD); +inline int isLowDelay(AUDIO_OBJECT_TYPE aot) { + return (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD); } -#endif /* _INTERFACE_H */ +#endif /* INTERFACE_H */ diff --git a/libAACenc/src/line_pe.cpp b/libAACenc/src/line_pe.cpp index f3c0dab..47734e5 100644 --- a/libAACenc/src/line_pe.cpp +++ b/libAACenc/src/line_pe.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Perceptual entropie module + Description: Perceptual entropie module -******************************************************************************/ +*******************************************************************************/ #include "line_pe.h" #include "sf_estim.h" @@ -94,42 +106,47 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" -static const FIXP_DBL C1LdData = FL2FXCONST_DBL(3.0/LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */ -static const FIXP_DBL C2LdData = FL2FXCONST_DBL(1.3219281/LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */ -static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */ - +static const FIXP_DBL C1LdData = + FL2FXCONST_DBL(3.0 / LD_DATA_SCALING); /* C1 = 3.0 = log(8.0)/log(2) */ +static const FIXP_DBL C2LdData = FL2FXCONST_DBL( + 1.3219281 / LD_DATA_SCALING); /* C2 = 1.3219281 = log(2.5)/log(2) */ +static const FIXP_DBL C3LdData = FL2FXCONST_DBL(0.5593573); /* 1-C2/C1 */ /* constants that do not change during successive pe calculations */ -void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, - const FIXP_DBL *sfbEnergyLdData, - const FIXP_DBL *sfbThresholdLdData, - const FIXP_DBL *sfbFormFactorLdData, - const INT *sfbOffset, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup) -{ - INT sfbGrp,sfb; - INT sfbWidth; - FIXP_DBL avgFormFactorLdData; - const FIXP_DBL formFacScaling = FL2FXCONST_DBL((float)FORM_FAC_SHIFT/LD_DATA_SCALING); - - for (sfbGrp = 0;sfbGrp < sfbCnt;sfbGrp+=sfbPerGroup) { - for (sfb=0; sfb<maxSfbPerGroup; sfb++) { - if ((FIXP_DBL)sfbEnergyLdData[sfbGrp+sfb] > (FIXP_DBL)sfbThresholdLdData[sfbGrp+sfb]) { - sfbWidth = sfbOffset[sfbGrp+sfb+1] - sfbOffset[sfbGrp+sfb]; - /* estimate number of active lines */ - avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp+sfb]>>1) + (CalcLdInt(sfbWidth)>>1))>>1; - peChanData->sfbNLines[sfbGrp+sfb] = - (INT)CalcInvLdData( (sfbFormFactorLdData[sfbGrp+sfb] + formFacScaling) + avgFormFactorLdData); - /* Make sure sfbNLines is never greater than sfbWidth due to unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */ - peChanData->sfbNLines[sfbGrp+sfb] = fMin(sfbWidth, peChanData->sfbNLines[sfbGrp+sfb]); - } - else { - peChanData->sfbNLines[sfbGrp+sfb] = 0; +void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const FIXP_DBL *RESTRICT const sfbFormFactorLdData, + const INT *RESTRICT const sfbOffset, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup) { + INT sfbGrp, sfb; + INT sfbWidth; + FIXP_DBL avgFormFactorLdData; + const FIXP_DBL formFacScaling = + FL2FXCONST_DBL((float)FORM_FAC_SHIFT / LD_DATA_SCALING); + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + if ((FIXP_DBL)sfbEnergyLdData[sfbGrp + sfb] > + (FIXP_DBL)sfbThresholdLdData[sfbGrp + sfb]) { + sfbWidth = sfbOffset[sfbGrp + sfb + 1] - sfbOffset[sfbGrp + sfb]; + /* estimate number of active lines */ + avgFormFactorLdData = ((-sfbEnergyLdData[sfbGrp + sfb] >> 1) + + (CalcLdInt(sfbWidth) >> 1)) >> + 1; + peChanData->sfbNLines[sfbGrp + sfb] = (INT)CalcInvLdData( + (sfbFormFactorLdData[sfbGrp + sfb] + formFacScaling) + + avgFormFactorLdData); + /* Make sure sfbNLines is never greater than sfbWidth due to + * unaccuracies (e.g. sfbEnergyLdData[sfbGrp+sfb] = 0x80000000) */ + peChanData->sfbNLines[sfbGrp + sfb] = + fMin(sfbWidth, peChanData->sfbNLines[sfbGrp + sfb]); + } else { + peChanData->sfbNLines[sfbGrp + sfb] = 0; } } - } + } } /* @@ -141,69 +158,77 @@ void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, constPart is sfbPe without the threshold part n*ld(thr) or n*C3*ld(thr) */ -void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT peChanData, - const FIXP_DBL *RESTRICT sfbEnergyLdData, - const FIXP_DBL *RESTRICT sfbThresholdLdData, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *isBook, - const INT *isScale) -{ - INT sfbGrp,sfb; - INT nLines; - FIXP_DBL logDataRatio; - INT lastValIs = 0; - - peChanData->pe = 0; - peChanData->constPart = 0; - peChanData->nActiveLines = 0; - - for(sfbGrp = 0;sfbGrp < sfbCnt;sfbGrp+=sfbPerGroup){ - for (sfb=0; sfb<maxSfbPerGroup; sfb++) { - if ((FIXP_DBL)sfbEnergyLdData[sfbGrp+sfb] > (FIXP_DBL)sfbThresholdLdData[sfbGrp+sfb]) { - logDataRatio = (FIXP_DBL)(sfbEnergyLdData[sfbGrp+sfb] - sfbThresholdLdData[sfbGrp+sfb]); - nLines = peChanData->sfbNLines[sfbGrp+sfb]; - if (logDataRatio >= C1LdData) { - /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ - peChanData->sfbPe[sfbGrp+sfb] = fMultDiv2(logDataRatio, (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); - peChanData->sfbConstPart[sfbGrp+sfb] = - fMultDiv2(sfbEnergyLdData[sfbGrp+sfb], (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); ; - - } - else { - /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ - peChanData->sfbPe[sfbGrp+sfb] = - fMultDiv2(((FIXP_DBL)C2LdData + fMult(C3LdData,logDataRatio)), (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))); - - peChanData->sfbConstPart[sfbGrp+sfb] = - fMultDiv2(((FIXP_DBL)C2LdData + fMult(C3LdData,sfbEnergyLdData[sfbGrp+sfb])), - (FIXP_DBL)(nLines<<(LD_DATA_SHIFT+PE_CONSTPART_SHIFT+1))) ; - - nLines = fMultI(C3LdData, nLines); - } - peChanData->sfbNActiveLines[sfbGrp+sfb] = nLines; - } - else if( isBook[sfbGrp+sfb] ) { +void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *RESTRICT const isBook, + const INT *RESTRICT const isScale) { + INT sfbGrp, sfb, thisSfb; + INT nLines; + FIXP_DBL logDataRatio; + FIXP_DBL scaleLd = (FIXP_DBL)0; + INT lastValIs = 0; + + FIXP_DBL pe = 0; + FIXP_DBL constPart = 0; + FIXP_DBL nActiveLines = 0; + + FIXP_DBL tmpPe, tmpConstPart, tmpNActiveLines; + + for (sfbGrp = 0; sfbGrp < sfbCnt; sfbGrp += sfbPerGroup) { + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + tmpPe = (FIXP_DBL)0; + tmpConstPart = (FIXP_DBL)0; + tmpNActiveLines = (FIXP_DBL)0; + + thisSfb = sfbGrp + sfb; + + if (sfbEnergyLdData[thisSfb] > sfbThresholdLdData[thisSfb]) { + logDataRatio = sfbEnergyLdData[thisSfb] - sfbThresholdLdData[thisSfb]; + nLines = peChanData->sfbNLines[thisSfb]; + + FIXP_DBL factor = nLines << (LD_DATA_SHIFT + PE_CONSTPART_SHIFT + 1); + if (logDataRatio >= C1LdData) { + /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ + tmpPe = fMultDiv2(logDataRatio, factor); + tmpConstPart = fMultDiv2(sfbEnergyLdData[thisSfb] + scaleLd, factor); + } else { + /* scale sfbPe and sfbConstPart with PE_CONSTPART_SHIFT */ + tmpPe = fMultDiv2( + ((FIXP_DBL)C2LdData + fMult(C3LdData, logDataRatio)), factor); + tmpConstPart = + fMultDiv2(((FIXP_DBL)C2LdData + + fMult(C3LdData, sfbEnergyLdData[thisSfb] + scaleLd)), + factor); + + nLines = fMultI(C3LdData, nLines); + } + tmpNActiveLines = (FIXP_DBL)nLines; + } else if (isBook[thisSfb]) { /* provide for cost of scale factor for Intensity */ - INT delta = isScale[sfbGrp+sfb] - lastValIs; - lastValIs = isScale[sfbGrp+sfb]; - peChanData->sfbPe[sfbGrp+sfb] = FDKaacEnc_bitCountScalefactorDelta(delta)<<PE_CONSTPART_SHIFT; - peChanData->sfbConstPart[sfbGrp+sfb] = 0; - peChanData->sfbNActiveLines[sfbGrp+sfb] = 0; - } - else { - peChanData->sfbPe[sfbGrp+sfb] = 0; - peChanData->sfbConstPart[sfbGrp+sfb] = 0; - peChanData->sfbNActiveLines[sfbGrp+sfb] = 0; + INT delta = isScale[thisSfb] - lastValIs; + lastValIs = isScale[thisSfb]; + peChanData->sfbPe[thisSfb] = FDKaacEnc_bitCountScalefactorDelta(delta) + << PE_CONSTPART_SHIFT; + peChanData->sfbConstPart[thisSfb] = 0; + peChanData->sfbNActiveLines[thisSfb] = 0; } + peChanData->sfbPe[thisSfb] = tmpPe; + peChanData->sfbConstPart[thisSfb] = tmpConstPart; + peChanData->sfbNActiveLines[thisSfb] = tmpNActiveLines; + /* sum up peChanData values */ - peChanData->pe += peChanData->sfbPe[sfbGrp+sfb]; - peChanData->constPart += peChanData->sfbConstPart[sfbGrp+sfb]; - peChanData->nActiveLines += peChanData->sfbNActiveLines[sfbGrp+sfb]; + pe += tmpPe; + constPart += tmpConstPart; + nActiveLines += tmpNActiveLines; } - } - /* correct scaled pe and constPart values */ - peChanData->pe>>=PE_CONSTPART_SHIFT; - peChanData->constPart>>=PE_CONSTPART_SHIFT; + } + + /* correct scaled pe and constPart values */ + peChanData->pe = pe >> PE_CONSTPART_SHIFT; + peChanData->constPart = constPart >> PE_CONSTPART_SHIFT; + + peChanData->nActiveLines = nActiveLines; } diff --git a/libAACenc/src/line_pe.h b/libAACenc/src/line_pe.h index 3d5cfd5..ecc2388 100644 --- a/libAACenc/src/line_pe.h +++ b/libAACenc/src/line_pe.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,61 +90,59 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Perceptual entropie module + Description: Perceptual entropie module -******************************************************************************/ -#ifndef __LINE_PE_H -#define __LINE_PE_H +*******************************************************************************/ +#ifndef LINE_PE_H +#define LINE_PE_H #include "common_fix.h" #include "psy_const.h" -#define PE_CONSTPART_SHIFT FRACT_BITS +#define PE_CONSTPART_SHIFT FRACT_BITS typedef struct { - /* calculated by FDKaacEnc_prepareSfbPe */ - INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */ - /* the rest is calculated by FDKaacEnc_calcSfbPe */ - INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */ - INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */ - INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */ - INT pe; /* sum of sfbPe */ - INT constPart; /* sum of sfbConstPart */ - INT nActiveLines; /* sum of sfbNActiveLines */ + /* calculated by FDKaacEnc_prepareSfbPe */ + INT sfbNLines[MAX_GROUPED_SFB]; /* number of relevant lines in sfb */ + /* the rest is calculated by FDKaacEnc_calcSfbPe */ + INT sfbPe[MAX_GROUPED_SFB]; /* pe for each sfb */ + INT sfbConstPart[MAX_GROUPED_SFB]; /* constant part for each sfb */ + INT sfbNActiveLines[MAX_GROUPED_SFB]; /* number of active lines in sfb */ + INT pe; /* sum of sfbPe */ + INT constPart; /* sum of sfbConstPart */ + INT nActiveLines; /* sum of sfbNActiveLines */ } PE_CHANNEL_DATA; typedef struct { - PE_CHANNEL_DATA peChannelData[(2)]; - INT pe; - INT constPart; - INT nActiveLines; - INT offset; + PE_CHANNEL_DATA peChannelData[(2)]; + INT pe; + INT constPart; + INT nActiveLines; + INT offset; } PE_DATA; - -void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *peChanData, - const FIXP_DBL *sfbEnergyLdData, - const FIXP_DBL *sfbThresholdLdData, - const FIXP_DBL *sfbFormFactorLdData, - const INT *sfbOffset, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup); - -void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT peChanData, - const FIXP_DBL *RESTRICT sfbEnergyLdData, - const FIXP_DBL *RESTRICT sfbThresholdLdData, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *isBook, - const INT *isScale); +void FDKaacEnc_prepareSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const FIXP_DBL *RESTRICT const sfbFormFactorLdData, + const INT *RESTRICT const sfbOffset, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup); + +void FDKaacEnc_calcSfbPe(PE_CHANNEL_DATA *RESTRICT const peChanData, + const FIXP_DBL *RESTRICT const sfbEnergyLdData, + const FIXP_DBL *RESTRICT const sfbThresholdLdData, + const INT sfbCnt, const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *RESTRICT const isBook, + const INT *RESTRICT const isScale); #endif diff --git a/libAACenc/src/metadata_compressor.cpp b/libAACenc/src/metadata_compressor.cpp index 68a64ae..bdac80a 100644 --- a/libAACenc/src/metadata_compressor.cpp +++ b/libAACenc/src/metadata_compressor.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,50 +90,39 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): M. Neusinger - Description: Compressor for AAC Metadata Generator + Author(s): M. Neusinger -******************************************************************************/ + Description: Compressor for AAC Metadata Generator +*******************************************************************************/ #include "metadata_compressor.h" #include "channel_map.h" - -#define LOG2 0.69314718056f /* natural logarithm of 2 */ -#define ILOG2 1.442695041f /* 1/LOG2 */ -#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2/2)) +#define LOG2 0.69314718056f /* natural logarithm of 2 */ +#define ILOG2 1.442695041f /* 1/LOG2 */ +#define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2)) /*----------------- defines ----------------------*/ -#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */ -#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ -#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ +#define MAX_DRC_CHANNELS (8) /*!< Max number of audio input channels. */ +#define DOWNMIX_SHIFT (3) /*!< Max 8 channel. */ +#define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */ -#define METADATA_INT_BITS 10 -#define METADATA_LINT_BITS 20 -#define METADATA_INT_SCALE (INT64(1)<<(METADATA_INT_BITS)) -#define METADATA_FRACT_BITS (DFRACT_BITS-1-METADATA_INT_BITS) -#define METADATA_FRACT_SCALE (INT64(1)<<(METADATA_FRACT_BITS)) +#define METADATA_INT_BITS 10 +#define METADATA_LINT_BITS 20 +#define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS)) +#define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS) +#define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS)) /** * Enum for channel assignment. */ -enum { - L = 0, - R = 1, - C = 2, - LFE = 3, - LS = 4, - RS = 5, - S = 6, - LS2 = 7, - RS2 = 8 -}; +enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 }; /*--------------- structure definitions --------------------*/ @@ -130,61 +130,62 @@ enum { * Structure holds weighting filter filter states. */ struct WEIGHTING_STATES { - FIXP_DBL x1; - FIXP_DBL x2; - FIXP_DBL y1; - FIXP_DBL y2; + FIXP_DBL x1; + FIXP_DBL x2; + FIXP_DBL y1; + FIXP_DBL y2; }; /** * Dynamic Range Control compressor structure. */ struct DRC_COMP { - - FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */ - FIXP_DBL boostThr[2]; /*!< Boost threshold. */ - FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */ - FIXP_DBL cutThr[2]; /*!< Cut threshold. */ - FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */ - - FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */ - FIXP_DBL earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */ - FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */ - - FIXP_DBL maxBoost[2]; /*!< Maximum boost. */ - FIXP_DBL maxCut[2]; /*!< Maximum cut. */ - FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */ - - FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */ - FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */ - FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */ - FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */ - UINT holdOff[2]; /*!< Hold time in blocks. */ - - FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */ - FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */ - - DRC_PROFILE profile[2]; /*!< DRC profile. */ - INT blockLength; /*!< Block length in samples. */ - UINT sampleRate; /*!< Sample rate. */ - CHANNEL_MODE chanConfig; /*!< Channel configuration. */ - - UCHAR useWeighting; /*!< Use weighting filter. */ - - UINT channels; /*!< Number of channels. */ - UINT fullChannels; /*!< Number of full range channels. */ - INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, Ls, Rs, S, Ls2, Rs2). */ - - FIXP_DBL smoothLevel[2]; /*!< level smoothing states */ - FIXP_DBL smoothGain[2]; /*!< gain smoothing states */ - UINT holdCnt[2]; /*!< hold counter */ - - FIXP_DBL limGain[2]; /*!< limiter gain */ - FIXP_DBL limDecay; /*!< limiter decay (linear) */ - FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/ - - WEIGHTING_STATES filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */ - + FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */ + FIXP_DBL boostThr[2]; /*!< Boost threshold. */ + FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */ + FIXP_DBL cutThr[2]; /*!< Cut threshold. */ + FIXP_DBL maxCutThr[2]; /*!< Max cut threshold. */ + + FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */ + FIXP_DBL + earlyCutFac[2]; /*!< Precalculated factor for early cut compression. */ + FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */ + + FIXP_DBL maxBoost[2]; /*!< Maximum boost. */ + FIXP_DBL maxCut[2]; /*!< Maximum cut. */ + FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */ + + FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */ + FIXP_DBL fastDecay[2]; /*!< Fast release coefficient. */ + FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */ + FIXP_DBL slowDecay[2]; /*!< Slow release coefficient. */ + UINT holdOff[2]; /*!< Hold time in blocks. */ + + FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */ + FIXP_DBL decayThr[2]; /*!< Slow/fast release threshold. */ + + DRC_PROFILE profile[2]; /*!< DRC profile. */ + INT blockLength; /*!< Block length in samples. */ + UINT sampleRate; /*!< Sample rate. */ + CHANNEL_MODE chanConfig; /*!< Channel configuration. */ + + UCHAR useWeighting; /*!< Use weighting filter. */ + + UINT channels; /*!< Number of channels. */ + UINT fullChannels; /*!< Number of full range channels. */ + INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE, + Ls, Rs, S, Ls2, Rs2). */ + + FIXP_DBL smoothLevel[2]; /*!< level smoothing states */ + FIXP_DBL smoothGain[2]; /*!< gain smoothing states */ + UINT holdCnt[2]; /*!< hold counter */ + + FIXP_DBL limGain[2]; /*!< limiter gain */ + FIXP_DBL limDecay; /*!< limiter decay (linear) */ + FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/ + + WEIGHTING_STATES + filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */ }; /*---------------- constants -----------------------*/ @@ -193,143 +194,110 @@ struct DRC_COMP { * Profile tables. */ static const FIXP_DBL tabMaxBoostThr[] = { - (FIXP_DBL)(int)((unsigned)-43<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-53<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-55<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-65<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-50<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-40<<METADATA_FRACT_BITS) -}; + (FIXP_DBL)(-(43 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(53 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(55 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(65 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(50 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(40 << METADATA_FRACT_BITS))}; static const FIXP_DBL tabBoostThr[] = { - (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-41<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-31<<METADATA_FRACT_BITS) -}; + (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(31 << METADATA_FRACT_BITS))}; static const FIXP_DBL tabEarlyCutThr[] = { - (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-26<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-20<<METADATA_FRACT_BITS) -}; -static const FIXP_DBL tabCutThr[] = { - (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-11<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-21<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-16<<METADATA_FRACT_BITS), - (FIXP_DBL)(int)((unsigned)-10<<METADATA_FRACT_BITS) -}; -static const FIXP_DBL tabMaxCutThr[] = { - (FIXP_DBL)(4<<METADATA_FRACT_BITS), - (FIXP_DBL)(9<<METADATA_FRACT_BITS), - (FIXP_DBL)(4<<METADATA_FRACT_BITS), - (FIXP_DBL)(9<<METADATA_FRACT_BITS), - (FIXP_DBL)(4<<METADATA_FRACT_BITS), - (FIXP_DBL)(4<<METADATA_FRACT_BITS) -}; + (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(20 << METADATA_FRACT_BITS))}; +static const FIXP_DBL tabCutThr[] = {(FIXP_DBL)(-(16 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(11 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)), + (FIXP_DBL)(-(10 << METADATA_FRACT_BITS))}; +static const FIXP_DBL tabMaxCutThr[] = { + (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS), + (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS), + (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(4 << METADATA_FRACT_BITS)}; static const FIXP_DBL tabBoostRatio[] = { - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/5.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/5.f) - 1.f) ) -}; + FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 5.f) - 1.f)), FL2FXCONST_DBL(((1.f / 5.f) - 1.f))}; static const FIXP_DBL tabEarlyCutRatio[] = { - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/1.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ) -}; -static const FIXP_DBL tabCutRatio[] = { - FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/ 2.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ), - FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ) -}; -static const FIXP_DBL tabMaxBoost[] = { - (FIXP_DBL)( 6<<METADATA_FRACT_BITS), - (FIXP_DBL)( 6<<METADATA_FRACT_BITS), - (FIXP_DBL)(12<<METADATA_FRACT_BITS), - (FIXP_DBL)(12<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS) -}; -static const FIXP_DBL tabMaxCut[] = { - (FIXP_DBL)(24<<METADATA_FRACT_BITS), - (FIXP_DBL)(24<<METADATA_FRACT_BITS), - (FIXP_DBL)(24<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(24<<METADATA_FRACT_BITS), - (FIXP_DBL)(24<<METADATA_FRACT_BITS) -}; + FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 1.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f))}; +static const FIXP_DBL tabCutRatio[] = { + FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), + FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f))}; +static const FIXP_DBL tabMaxBoost[] = {(FIXP_DBL)(6 << METADATA_FRACT_BITS), + (FIXP_DBL)(6 << METADATA_FRACT_BITS), + (FIXP_DBL)(12 << METADATA_FRACT_BITS), + (FIXP_DBL)(12 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS)}; +static const FIXP_DBL tabMaxCut[] = {(FIXP_DBL)(24 << METADATA_FRACT_BITS), + (FIXP_DBL)(24 << METADATA_FRACT_BITS), + (FIXP_DBL)(24 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(24 << METADATA_FRACT_BITS), + (FIXP_DBL)(24 << METADATA_FRACT_BITS)}; static const FIXP_DBL tabFastAttack[] = { - FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) -}; -static const FIXP_DBL tabFastDecay[] = { - FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (200.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) -}; + FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)}; +static const FIXP_DBL tabFastDecay[] = { + FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((200.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)}; static const FIXP_DBL tabSlowAttack[] = { - FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) -}; -static const FIXP_DBL tabSlowDecay[] = { - FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL((10000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (1000.f/1000.f)/METADATA_INT_SCALE), - FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE) -}; - -static const INT tabHoldOff[] = { 10, 10, 10, 10, 10, 0 }; - -static const FIXP_DBL tabAttackThr[] = { - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(15<<METADATA_FRACT_BITS), - (FIXP_DBL)(10<<METADATA_FRACT_BITS), - (FIXP_DBL)(0<<METADATA_FRACT_BITS) -}; -static const FIXP_DBL tabDecayThr[] = { - (FIXP_DBL)(20<<METADATA_FRACT_BITS), - (FIXP_DBL)(20<<METADATA_FRACT_BITS), - (FIXP_DBL)(20<<METADATA_FRACT_BITS), - (FIXP_DBL)(20<<METADATA_FRACT_BITS), - (FIXP_DBL)(10<<METADATA_FRACT_BITS), - (FIXP_DBL)( 0<<METADATA_FRACT_BITS) -}; + FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)}; +static const FIXP_DBL tabSlowDecay[] = { + FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((10000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE), + FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)}; + +static const INT tabHoldOff[] = {10, 10, 10, 10, 10, 0}; + +static const FIXP_DBL tabAttackThr[] = {(FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(15 << METADATA_FRACT_BITS), + (FIXP_DBL)(10 << METADATA_FRACT_BITS), + (FIXP_DBL)(0 << METADATA_FRACT_BITS)}; +static const FIXP_DBL tabDecayThr[] = {(FIXP_DBL)(20 << METADATA_FRACT_BITS), + (FIXP_DBL)(20 << METADATA_FRACT_BITS), + (FIXP_DBL)(20 << METADATA_FRACT_BITS), + (FIXP_DBL)(20 << METADATA_FRACT_BITS), + (FIXP_DBL)(10 << METADATA_FRACT_BITS), + (FIXP_DBL)(0 << METADATA_FRACT_BITS)}; /** * Weighting filter coefficients (biquad bandpass). */ -static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */ -static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f), a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */ - +static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */ +static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f), + a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */ /*------------- function definitions ----------------*/ @@ -340,14 +308,12 @@ static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f), a2 = FL2FXCONST_DBL(-0. * * \return shiftFactor */ -static UINT getShiftFactor( - const UINT length - ) -{ - UINT ldN; - for(ldN=1;(((UINT)1)<<ldN) < length;ldN++); - - return ldN; +static UINT getShiftFactor(const UINT length) { + UINT ldN; + for (ldN = 1; (((UINT)1) << ldN) < length; ldN++) + ; + + return ldN; } /** @@ -355,28 +321,26 @@ static UINT getShiftFactor( * * \param value1 First input value. * \param q1 Scaling factor of first input value. - * \param pValue2 Pointer to second input value, will be modified on return. - * \param pQ2 Pointer to second scaling factor, will be modified on return. + * \param pValue2 Pointer to second input value, will be modified on + * return. + * \param pQ2 Pointer to second scaling factor, will be modified on + * return. * * \return void */ -static void fixpAdd( - const FIXP_DBL value1, - const int q1, - FIXP_DBL *const pValue2, - int *const pQ2 - ) -{ - const int headroom1 = fNormz(fixp_abs(value1))-1; - const int headroom2 = fNormz(fixp_abs(*pValue2))-1; - int resultScale = fixMax(q1-headroom1, (*pQ2)-headroom2); - - if ( (value1!=FL2FXCONST_DBL(0.f)) && (*pValue2!=FL2FXCONST_DBL(0.f)) ) { +static void fixpAdd(const FIXP_DBL value1, const int q1, + FIXP_DBL* const pValue2, int* const pQ2) { + const int headroom1 = fNormz(fixp_abs(value1)) - 1; + const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1; + int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2); + + if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) { resultScale++; } - *pValue2 = scaleValue(value1, q1-resultScale) + scaleValue(*pValue2, (*pQ2)-resultScale); - *pQ2 = (*pValue2!=(FIXP_DBL)0) ? resultScale : DFRACT_BITS-1; + *pValue2 = scaleValue(value1, q1 - resultScale) + + scaleValue(*pValue2, (*pQ2) - resultScale); + *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1; } /** @@ -388,651 +352,1228 @@ static void fixpAdd( * * \return result = 1.0 - exp(-1.0/((t) * (f))) */ -static FIXP_DBL tc2Coeff( - const FIXP_DBL t, - const INT sampleRate, - const INT blockLength - ) -{ - FIXP_DBL sampleRateFract; - FIXP_DBL blockLengthFract; - FIXP_DBL f, product; - FIXP_DBL exponent, result; - INT e_res; - - /* f = sampleRate/blockLength */ - sampleRateFract = (FIXP_DBL)(sampleRate<<(DFRACT_BITS-1-METADATA_LINT_BITS)); - blockLengthFract = (FIXP_DBL)(blockLength<<(DFRACT_BITS-1-METADATA_LINT_BITS)); - f = fDivNorm(sampleRateFract, blockLengthFract, &e_res); - f = scaleValue(f, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */ - - /* product = t*f */ - product = fMultNorm(t, f, &e_res); - product = scaleValue(product, e_res+METADATA_INT_BITS); /* convert to METADATA_FRACT */ - - /* exponent = (-1.0/((t) * (f))) */ - exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res); - exponent = scaleValue(exponent, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */ - - /* exponent * ld(e) */ - exponent = fMult(exponent,FIXP_ILOG2_DIV2)<<1; /* e^(x) = 2^(x*ld(e)) */ - - /* exp(-1.0/((t) * (f))) */ - result = f2Pow(-exponent, DFRACT_BITS-1-METADATA_FRACT_BITS, &e_res); - - /* result = 1.0 - exp(-1.0/((t) * (f))) */ - result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res); - - return result; +static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate, + const INT blockLength) { + FIXP_DBL sampleRateFract; + FIXP_DBL blockLengthFract; + FIXP_DBL f, product; + FIXP_DBL exponent, result; + INT e_res; + + /* f = sampleRate/blockLength */ + sampleRateFract = + (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS)); + blockLengthFract = + (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS)); + f = fDivNorm(sampleRateFract, blockLengthFract, &e_res); + f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */ + + /* product = t*f */ + product = fMultNorm(t, f, &e_res); + product = scaleValue( + product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */ + + /* exponent = (-1.0/((t) * (f))) */ + exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res); + exponent = scaleValue( + exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */ + + /* exponent * ld(e) */ + exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */ + + /* exp(-1.0/((t) * (f))) */ + result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res); + + /* result = 1.0 - exp(-1.0/((t) * (f))) */ + result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res); + + return result; } -INT FDK_DRC_Generator_Open( - HDRC_COMP *phDrcComp - ) -{ - INT err = 0; - HDRC_COMP hDcComp = NULL; - - if (phDrcComp == NULL) { - err = -1; - goto bail; +static void findPeakLevels(HDRC_COMP drcComp, const INT_PCM* const inSamples, + const FIXP_DBL clev, const FIXP_DBL slev, + const FIXP_DBL ext_leva, const FIXP_DBL ext_levb, + const FIXP_DBL lfe_lev, const FIXP_DBL dmxGain5, + const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) { + int i, c; + FIXP_DBL tmp = FL2FXCONST_DBL(0.f); + INT_PCM maxSample = 0; + + /* find peak level */ + peak[0] = peak[1] = FL2FXCONST_DBL(0.f); + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* single channels */ + for (c = 0; c < (int)drcComp->channels; c++) { + maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c])); } + } + peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT); + + /* 7.1/6.1 to 5.1 downmixes */ + if (drcComp->fullChannels > 5) { + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* channel 1 (L, Ls,...) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* channel 2 (R, Rs,...) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* channel 3 (C) */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + DOWNMIX_SHIFT); /* C */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + break; + default: + break; + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); - /* allocate memory */ - hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); + } /* for (blocklength) */ - if (hDcComp == NULL) { - err = -1; - goto bail; + /* take downmix gain into accout */ + peak[0] = fMult(dmxGain5, peak[0]) + << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + + /* 7.1 / 5.1 to stereo downmixes */ + if (drcComp->fullChannels > 2) { + /* Lt/Rt downmix */ + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* Lt */ + tmp = FL2FXCONST_DBL(0.f); + if (drcComp->channelIdx[LS] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* Rt */ + tmp = FL2FXCONST_DBL(0.f); + if (drcComp->channelIdx[LS] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), + (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); } - FDKmemclear(hDcComp, sizeof(DRC_COMP)); + /* Lo/Ro downmix */ + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + /* Lo */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc - second path*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[LS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += + fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMultDiv2(lfe_lev, + (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + break; + } - /* Return drc compressor instance */ - *phDrcComp = hDcComp; - return err; -bail: - FDK_DRC_Generator_Close(&hDcComp); - return err; -} + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + /* Ro */ + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc - second path*/ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += + fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[RS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += + fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMultDiv2(lfe_lev, + (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + } -INT FDK_DRC_Generator_Close( - HDRC_COMP *phDrcComp - ) -{ - if (phDrcComp == NULL) { - return -1; + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[0] = fixMax(peak[0], fixp_abs(tmp)); } - if (*phDrcComp != NULL) { - FDKfree(*phDrcComp); - *phDrcComp = NULL; + } + + peak[1] = fixMax(peak[0], peak[1]); + + /* Mono Downmix - for comp_val only */ + if (drcComp->fullChannels > 1) { + for (i = 0; i < drcComp->blockLength; i++) { + const INT_PCM* pSamples = &inSamples[i * drcComp->channels]; + + tmp = FL2FXCONST_DBL(0.f); + switch (drcComp->chanConfig) { + case MODE_6_1: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >> + (DOWNMIX_SHIFT - 1); /* Cs */ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_BACK: + case MODE_7_1_REAR_SURROUND: + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(fMult(slev, ext_leva), + (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/ + tmp += fMultDiv2(fMult(slev, ext_levb), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_1_2_2_2_1: + case MODE_7_1_FRONT_CENTER: + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + DOWNMIX_SHIFT); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc */ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lc - second path*/ + tmp += fMultDiv2(fMult(ext_leva, clev), + (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rc - second path*/ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + case MODE_7_1_TOP_FRONT: + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >> + (DOWNMIX_SHIFT - 1); /* L */ + tmp += + fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >> + (DOWNMIX_SHIFT - 1); /* R */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >> + (DOWNMIX_SHIFT - 1); /* Lvh */ + tmp += + fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >> + (DOWNMIX_SHIFT - 1); /* Rvh */ + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >> + (DOWNMIX_SHIFT - 1); /* C */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + break; + default: + if (drcComp->channelIdx[LS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >> + (DOWNMIX_SHIFT - 1); /* Ls */ + if (drcComp->channelIdx[LS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >> + (DOWNMIX_SHIFT - 1); /* Ls2 */ + if (drcComp->channelIdx[RS] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >> + (DOWNMIX_SHIFT - 1); /* Rs */ + if (drcComp->channelIdx[RS2] >= 0) + tmp += + fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >> + (DOWNMIX_SHIFT - 1); /* Rs2 */ + if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) + tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ + /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ + if (drcComp->channelIdx[S] >= 0) + tmp += + fMultDiv2(slev, + fMult(FL2FXCONST_DBL(0.7f), + (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >> + (DOWNMIX_SHIFT - 1); /* S */ + if (drcComp->channelIdx[C] >= 0) + tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >> + (DOWNMIX_SHIFT - 1); /* C (2*clev) */ + if (drcComp->channelIdx[3] >= 0) + tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >> + (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >> + DOWNMIX_SHIFT); /* L */ + tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >> + DOWNMIX_SHIFT); /* R */ + } + + /* apply scaling of downmix gains */ + /* only for positive values only, as legacy decoders might not know this + * parameter */ + if (dmxGain2 > FL2FXCONST_DBL(0.f)) { + if (drcComp->fullChannels > 5) { + tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS); + } + peak[1] = fixMax(peak[1], fixp_abs(tmp)); } - return 0; + } } +INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) { + INT err = 0; + HDRC_COMP hDcComp = NULL; -INT FDK_DRC_Generator_Initialize( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF, - const INT blockLength, - const UINT sampleRate, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder, - const UCHAR useWeighting - ) -{ - int i; - CHANNEL_MAPPING channelMapping; - - drcComp->limDecay = FL2FXCONST_DBL( ((0.006f / 256) * blockLength) / METADATA_INT_SCALE ); - - /* Save parameters. */ - drcComp->blockLength = blockLength; - drcComp->sampleRate = sampleRate; - drcComp->chanConfig = channelMode; - drcComp->useWeighting = useWeighting; - - if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF)!=0) { /* expects initialized blockLength and sampleRate */ - return (-1); - } + if (phDrcComp == NULL) { + err = -1; + goto bail; + } - /* Set number of channels and channel offsets. */ - if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, &channelMapping)!=AAC_ENC_OK) { - return (-2); - } + /* allocate memory */ + hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP)); + + if (hDcComp == NULL) { + err = -1; + goto bail; + } - for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; + FDKmemclear(hDcComp, sizeof(DRC_COMP)); - switch (channelMode) { + /* Return drc compressor instance */ + *phDrcComp = hDcComp; + return err; +bail: + FDK_DRC_Generator_Close(&hDcComp); + return err; +} + +INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) { + if (phDrcComp == NULL) { + return -1; + } + if (*phDrcComp != NULL) { + FDKfree(*phDrcComp); + *phDrcComp = NULL; + } + return 0; +} + +INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF, + const INT blockLength, const UINT sampleRate, + const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder, + const UCHAR useWeighting) { + int i; + CHANNEL_MAPPING channelMapping; + + drcComp->limDecay = + FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE); + + /* Save parameters. */ + drcComp->blockLength = blockLength; + drcComp->sampleRate = sampleRate; + drcComp->chanConfig = channelMode; + drcComp->useWeighting = useWeighting; + + if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) != + 0) { /* expects initialized blockLength and sampleRate */ + return (-1); + } + + /* Set number of channels and channel offsets. */ + if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, + &channelMapping) != AAC_ENC_OK) { + return (-2); + } + + for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1; + + switch (channelMode) { case MODE_1: /* mono */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - break; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + break; case MODE_2: /* stereo */ - drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1]; + break; case MODE_1_2: /* 3ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + break; case MODE_1_2_1: /* 4ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0]; + break; case MODE_1_2_2: /* 5ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; - drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; - break; - case MODE_1_2_2_1: /* 5.1 ch */ - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; - drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; - drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; - drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; - break; + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; + drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; + break; + case MODE_1_2_2_1: /* 5.1 ch */ + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; + drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0]; + drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0]; + drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1]; + break; case MODE_1_2_2_2_1: /* 7.1 ch */ case MODE_7_1_FRONT_CENTER: - drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ - drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ - drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ - drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ - drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ - drcComp->channelIdx[LS2] = channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ - drcComp->channelIdx[RS2] = channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ - break; + drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[3].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[3].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[1].ChannelIndex[0]; /* lc */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[1].ChannelIndex[1]; /* rc */ + break; + case MODE_7_1_BACK: case MODE_7_1_REAR_SURROUND: - drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ - drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ - drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ - drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ - drcComp->channelIdx[LS] = channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ - drcComp->channelIdx[RS] = channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ - drcComp->channelIdx[LS2] = channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ - drcComp->channelIdx[RS2] = channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ - break; - case MODE_1_1: - case MODE_1_1_1_1: - case MODE_1_1_1_1_1_1: - case MODE_1_1_1_1_1_1_1_1: - case MODE_1_1_1_1_1_1_1_1_1_1_1_1: - case MODE_2_2: - case MODE_2_2_2: - case MODE_2_2_2_2: - case MODE_2_2_2_2_2_2: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + break; + case MODE_6_1: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */ + break; + case MODE_7_1_TOP_FRONT: + drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */ + drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */ + drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */ + drcComp->channelIdx[LFE] = + channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */ + drcComp->channelIdx[LS] = + channelMapping.elInfo[2].ChannelIndex[0]; /* ls */ + drcComp->channelIdx[RS] = + channelMapping.elInfo[2].ChannelIndex[1]; /* rs */ + drcComp->channelIdx[LS2] = + channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */ + drcComp->channelIdx[RS2] = + channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */ + break; default: - return (-1); - } + return (-1); + } - drcComp->fullChannels = channelMapping.nChannelsEff; - drcComp->channels = channelMapping.nChannels; + drcComp->fullChannels = channelMapping.nChannelsEff; + drcComp->channels = channelMapping.nChannels; - /* Init states. */ - drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(int)((unsigned)-135<<METADATA_FRACT_BITS); + /* Init states. */ + drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = + (FIXP_DBL)(-(135 << METADATA_FRACT_BITS)); - FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); - FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); - FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); - FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); - FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); + FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain)); + FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt)); + FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain)); + FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak)); + FDKmemclear(drcComp->filter, sizeof(drcComp->filter)); - return (0); + return (0); } +INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF) { + int profileIdx, i; + + drcComp->profile[0] = profileLine; + drcComp->profile[1] = profileRF; + + for (i = 0; i < 2; i++) { + /* get profile index */ + switch (drcComp->profile[i]) { + case DRC_NONE: + case DRC_NOT_PRESENT: + case DRC_FILMSTANDARD: + profileIdx = 0; + break; + case DRC_FILMLIGHT: + profileIdx = 1; + break; + case DRC_MUSICSTANDARD: + profileIdx = 2; + break; + case DRC_MUSICLIGHT: + profileIdx = 3; + break; + case DRC_SPEECH: + profileIdx = 4; + break; + case DRC_DELAY_TEST: + profileIdx = 5; + break; + default: + return (-1); + } -INT FDK_DRC_Generator_setDrcProfile( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF - ) -{ - int profileIdx, i; + /* get parameters for selected profile */ + if (profileIdx >= 0) { + drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; + drcComp->boostThr[i] = tabBoostThr[profileIdx]; + drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; + drcComp->cutThr[i] = tabCutThr[profileIdx]; + drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; + + drcComp->boostFac[i] = tabBoostRatio[profileIdx]; + drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; + drcComp->cutFac[i] = tabCutRatio[profileIdx]; + + drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; + drcComp->maxCut[i] = tabMaxCut[profileIdx]; + drcComp->maxEarlyCut[i] = + -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), + drcComp->earlyCutFac[i]); /* no scaling after mult needed, + earlyCutFac is in FIXP_DBL */ + + drcComp->fastAttack[i] = tc2Coeff( + tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->fastDecay[i] = tc2Coeff( + tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->slowAttack[i] = tc2Coeff( + tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->slowDecay[i] = tc2Coeff( + tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); + drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; + + drcComp->attackThr[i] = tabAttackThr[profileIdx]; + drcComp->decayThr[i] = tabDecayThr[profileIdx]; + } - drcComp->profile[0] = profileLine; - drcComp->profile[1] = profileRF; + drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); + } + return (0); +} - for (i = 0; i < 2; i++) { - /* get profile index */ - switch (drcComp->profile[i]) { - case DRC_NONE: - case DRC_FILMSTANDARD: profileIdx = 0; break; - case DRC_FILMLIGHT: profileIdx = 1; break; - case DRC_MUSICSTANDARD: profileIdx = 2; break; - case DRC_MUSICLIGHT: profileIdx = 3; break; - case DRC_SPEECH: profileIdx = 4; break; - case DRC_DELAY_TEST: profileIdx = 5; break; - default: return (-1); - } +INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples, + const UINT inSamplesBufSize, const INT dialnorm, + const INT drc_TargetRefLevel, + const INT comp_TargetRefLevel, const FIXP_DBL clev, + const FIXP_DBL slev, const FIXP_DBL ext_leva, + const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev, + const INT dmxGain5, const INT dmxGain2, + INT* const pDynrng, INT* const pCompr) { + int i, c; + FIXP_DBL peak[2]; + + /************************************************************************** + * compressor + **************************************************************************/ + if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { + /* Calc loudness level */ + FIXP_DBL level_b = FL2FXCONST_DBL(0.f); + int level_e = DFRACT_BITS - 1; + + /* Increase energy time resolution with shorter processing blocks. 16 is an + * empiric value. */ + const int granuleLength = fixMin(16, drcComp->blockLength); + + if (drcComp->useWeighting) { + FIXP_DBL x1, x2, y, y1, y2; + /* sum of filter coefficients about 2.5 -> squared value is 6.25 + WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce + granuleShift by 1. + */ + const int granuleShift = getShiftFactor(granuleLength) - 1; - /* get parameters for selected profile */ - if (profileIdx >= 0) { - drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx]; - drcComp->boostThr[i] = tabBoostThr[profileIdx]; - drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx]; - drcComp->cutThr[i] = tabCutThr[profileIdx]; - drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx]; - - drcComp->boostFac[i] = tabBoostRatio[profileIdx]; - drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx]; - drcComp->cutFac[i] = tabCutRatio[profileIdx]; - - drcComp->maxBoost[i] = tabMaxBoost[profileIdx]; - drcComp->maxCut[i] = tabMaxCut[profileIdx]; - drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */ - - drcComp->fastAttack[i] = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->fastDecay[i] = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->slowAttack[i] = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->slowDecay[i] = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength); - drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength; - - drcComp->attackThr[i] = tabAttackThr[profileIdx]; - drcComp->decayThr[i] = tabDecayThr[profileIdx]; + for (c = 0; c < (int)drcComp->channels; c++) { + const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; + + if (c == drcComp->channelIdx[LFE]) { + continue; /* skip LFE */ } - drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); - } - return (0); -} + /* get filter states */ + x1 = drcComp->filter[c].x1; + x2 = drcComp->filter[c].x2; + y1 = drcComp->filter[c].y1; + y2 = drcComp->filter[c].y2; + i = 0; -INT FDK_DRC_Generator_Calc( - HDRC_COMP drcComp, - const INT_PCM * const inSamples, - const INT dialnorm, - const INT drc_TargetRefLevel, - const INT comp_TargetRefLevel, - FIXP_DBL clev, - FIXP_DBL slev, - INT * const pDynrng, - INT * const pCompr - ) -{ - int i, c; - FIXP_DBL peak[2]; + do { + int offset = i; + FIXP_DBL accu = FL2FXCONST_DBL(0.f); + for (i = offset; + i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { + /* apply weighting filter */ + FIXP_DBL x = + FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT; - /************************************************************************** - * compressor - **************************************************************************/ - if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) { - /* Calc loudness level */ - FIXP_DBL level_b = FL2FXCONST_DBL(0.f); - int level_e = DFRACT_BITS-1; + /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ + y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2); - /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */ - const int granuleLength = fixMin(32, drcComp->blockLength); - - if (drcComp->useWeighting) { - FIXP_DBL x1, x2, y, y1, y2; - /* sum of filter coefficients about 2.5 -> squared value is 6.25 - WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1. - */ - const int granuleShift = getShiftFactor(granuleLength)-1; - - for (c = 0; c < (int)drcComp->channels; c++) { - const INT_PCM* pSamples = &inSamples[c]; - - if (c == drcComp->channelIdx[LFE]) { - continue; /* skip LFE */ - } - - /* get filter states */ - x1 = drcComp->filter[c].x1; - x2 = drcComp->filter[c].x2; - y1 = drcComp->filter[c].y1; - y2 = drcComp->filter[c].y2; - - i = 0; - - do { - - int offset = i; - FIXP_DBL accu = FL2FXCONST_DBL(0.f); - - for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { - /* apply weighting filter */ - FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT; - - /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */ - y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2); - - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - - accu += fPow2Div2(y)>>(granuleShift-1); /* partial energy */ - } /* i */ - - fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */ - - } while ( i < drcComp->blockLength ); - - - /* save filter states */ - drcComp->filter[c].x1 = x1; - drcComp->filter[c].x2 = x2; - drcComp->filter[c].y1 = y1; - drcComp->filter[c].y2 = y2; - } /* c */ - } /* weighting */ - else { - const int granuleShift = getShiftFactor(granuleLength); - - for (c = 0; c < (int)drcComp->channels; c++) { - const INT_PCM* pSamples = &inSamples[c]; - - if ((int)c == drcComp->channelIdx[LFE]) { - continue; /* skip LFE */ - } - - i = 0; - - do { - int offset = i; - FIXP_DBL accu = FL2FXCONST_DBL(0.f); - - for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) { - /* partial energy */ - accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1); - } /* i */ - - fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */ - - } while ( i < drcComp->blockLength ); - } - } /* weighting */ - - /* - * Convert to dBFS, apply dialnorm - */ - /* level scaling */ - - /* descaled level in ld64 representation */ - FIXP_DBL ldLevel = CalcLdData(level_b) + (FIXP_DBL)((level_e-12)<<(DFRACT_BITS-1-LD_DATA_SHIFT)) - CalcLdData((FIXP_DBL)(drcComp->blockLength<<(DFRACT_BITS-1-12))); - - /* if (level < 1e-10) level = 1e-10f; */ - ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); - - /* level = 10 * log(level)/log(10) + 3; - * = 10*log(2)/log(10) * ld(level) + 3; - * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 - * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 - * - * additional scaling with METADATA_FRACT_BITS: - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS) - * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) - * = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) - * */ - FIXP_DBL level = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + (FIXP_DBL)(FL2FXCONST_DBL(0.3f)>>LD_DATA_SHIFT) ); - - /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */ - level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16)) + (FIXP_DBL)(31<<METADATA_FRACT_BITS)); - - for (i = 0; i < 2; i++) { - if (drcComp->profile[i] == DRC_NONE) { - /* no compression */ - drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); - } - else { - FIXP_DBL gain, alpha, lvl2smthlvl; - - /* calc static gain */ - if (level <= drcComp->maxBoostThr[i]) { - /* max boost */ - gain = drcComp->maxBoost[i]; - } - else if (level < drcComp->boostThr[i]) { - /* boost range */ - gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]); - } - else if (level <= drcComp->earlyCutThr[i]) { - /* null band */ - gain = FL2FXCONST_DBL(0.f); - } - else if (level <= drcComp->cutThr[i]) { - /* early cut range */ - gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); - } - else if (level < drcComp->maxCutThr[i]) { - /* cut range */ - gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i]; - } - else { - /* max cut */ - gain = -drcComp->maxCut[i]; - } - - /* choose time constant */ - lvl2smthlvl = level - drcComp->smoothLevel[i]; - if (gain < drcComp->smoothGain[i]) { - /* attack */ - if (lvl2smthlvl > drcComp->attackThr[i]) { - /* fast attack */ - alpha = drcComp->fastAttack[i]; - } - else { - /* slow attack */ - alpha = drcComp->slowAttack[i]; - } - } - else { - /* release */ - if (lvl2smthlvl < -drcComp->decayThr[i]) { - /* fast release */ - alpha = drcComp->fastDecay[i]; - } - else { - /* slow release */ - alpha = drcComp->slowDecay[i]; - } - } - - /* smooth gain & level */ - if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */ - FIXP_DBL accu; - - /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */ - accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothLevel[i]); - accu += fMult(alpha,level); - drcComp->smoothLevel[i] = accu; - - /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */ - accu = fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothGain[i]); - accu += fMult(alpha,gain); - drcComp->smoothGain[i] = accu; - } - - /* hold counter */ - if (drcComp->holdCnt[i]) { - drcComp->holdCnt[i]--; - } - if (gain < drcComp->smoothGain[i]) { - drcComp->holdCnt[i] = drcComp->holdOff[i]; - } - } /* profile != DRC_NONE */ - } /* for i=1..2 */ - } else { - /* no compression */ - drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); - drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); - } + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; - /************************************************************************** - * limiter - **************************************************************************/ + accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */ + } /* i */ - /* find peak level */ - peak[0] = peak[1] = FL2FXCONST_DBL(0.f); - for (i = 0; i < drcComp->blockLength; i++) { - FIXP_DBL tmp; - const INT_PCM* pSamples = &inSamples[i*drcComp->channels]; - INT_PCM maxSample = 0; + fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b, + &level_e); /* sup up partial energies */ + + } while (i < drcComp->blockLength); + + /* save filter states */ + drcComp->filter[c].x1 = x1; + drcComp->filter[c].x2 = x2; + drcComp->filter[c].y1 = y1; + drcComp->filter[c].y2 = y2; + } /* c */ + } /* weighting */ + else { + const int granuleShift = getShiftFactor(granuleLength); - /* single channels */ - for (c = 0; c < (int)drcComp->channels; c++) { - maxSample = FDKmax(maxSample, fAbs(pSamples[c])); + for (c = 0; c < (int)drcComp->channels; c++) { + const INT_PCM* pSamples = inSamples + c * inSamplesBufSize; + + if ((int)c == drcComp->channelIdx[LFE]) { + continue; /* skip LFE */ } - peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT); - - /* Lt/Rt downmix */ - if (drcComp->fullChannels > 2) { - /* Lt */ - tmp = FL2FXCONST_DBL(0.f); - - if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); - - /* Rt */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); + + i = 0; + + do { + int offset = i; + FIXP_DBL accu = FL2FXCONST_DBL(0.f); + + for (i = offset; + i < fixMin(offset + granuleLength, drcComp->blockLength); i++) { + /* partial energy */ + accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1); + } /* i */ + + fixpAdd(accu, granuleShift, &level_b, + &level_e); /* sup up partial energies */ + + } while (i < drcComp->blockLength); + } + } /* weighting */ + + /* + * Convert to dBFS, apply dialnorm + */ + /* level scaling */ + + /* descaled level in ld64 representation */ + FIXP_DBL ldLevel = + CalcLdData(level_b) + + (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) - + CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12))); + + /* if (level < 1e-10) level = 1e-10f; */ + ldLevel = + fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f)); + + /* level = 10 * log(level)/log(10) + 3; + * = 10*log(2)/log(10) * ld(level) + 3; + * = 10 * 0.30102999566398119521373889472449 * ld(level) + 3 + * = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3) + * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) + * * 64 + * + * additional scaling with METADATA_FRACT_BITS: + * = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) + * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449 + * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) = + * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( + * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 ) + * */ + FIXP_DBL level = fMult( + (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), + fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + + (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT)); + + /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as + compressor profiles are defined relative to + this */ + level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) + + (FIXP_DBL)(31 << METADATA_FRACT_BITS)); + + for (i = 0; i < 2; i++) { + if (drcComp->profile[i] == DRC_NONE) { + /* no compression */ + drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f); + } else { + FIXP_DBL gain, alpha, lvl2smthlvl; + + /* calc static gain */ + if (level <= drcComp->maxBoostThr[i]) { + /* max boost */ + gain = drcComp->maxBoost[i]; + } else if (level < drcComp->boostThr[i]) { + /* boost range */ + gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]); + } else if (level <= drcComp->earlyCutThr[i]) { + /* null band */ + gain = FL2FXCONST_DBL(0.f); + } else if (level <= drcComp->cutThr[i]) { + /* early cut range */ + gain = + fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); + } else if (level < drcComp->maxCutThr[i]) { + /* cut range */ + gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - + drcComp->maxEarlyCut[i]; + } else { + /* max cut */ + gain = -drcComp->maxCut[i]; } - /* Lo/Ro downmix */ - if (drcComp->fullChannels > 2) { - /* Lo */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); - - /* Ro */ - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[0] = fixMax(peak[0], fixp_abs(tmp)); + /* choose time constant */ + lvl2smthlvl = level - drcComp->smoothLevel[i]; + if (gain < drcComp->smoothGain[i]) { + /* attack */ + if (lvl2smthlvl > drcComp->attackThr[i]) { + /* fast attack */ + alpha = drcComp->fastAttack[i]; + } else { + /* slow attack */ + alpha = drcComp->slowAttack[i]; + } + } else { + /* release */ + if (lvl2smthlvl < -drcComp->decayThr[i]) { + /* fast release */ + alpha = drcComp->fastDecay[i]; + } else { + /* slow release */ + alpha = drcComp->slowDecay[i]; + } } - peak[1] = fixMax(peak[0], peak[1]); - - /* Mono Downmix - for comp_val only */ - if (drcComp->fullChannels > 1) { - tmp = FL2FXCONST_DBL(0.f); - if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1); /* Ls */ - if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1); /* Ls2 */ - if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1); /* Rs */ - if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1); /* Rs2 */ - if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */ - /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */ - if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */ - if (drcComp->channelIdx[C] >= 0) tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1); /* C (2*clev) */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT); /* L */ - tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT); /* R */ - - peak[1] = fixMax(peak[1], fixp_abs(tmp)); + /* smooth gain & level */ + if ((gain < drcComp->smoothGain[i]) || + (drcComp->holdCnt[i] == + 0)) { /* hold gain unless we have an attack or hold + period is over */ + FIXP_DBL accu; + + /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + + * alpha * level; */ + accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]); + accu += fMult(alpha, level); + drcComp->smoothLevel[i] = accu; + + /* drcComp->smoothGain[i] = (1-alpha) * drcComp->smoothGain[i] + + * alpha * gain; */ + accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]); + accu += fMult(alpha, gain); + drcComp->smoothGain[i] = accu; } - } - for (i=0; i<2; i++) { - FIXP_DBL tmp = drcComp->prevPeak[i]; - drcComp->prevPeak[i] = peak[i]; - peak[i] = fixMax(peak[i], tmp); + /* hold counter */ + if (drcComp->holdCnt[i]) { + drcComp->holdCnt[i]--; + } + if (gain < drcComp->smoothGain[i]) { + drcComp->holdCnt[i] = drcComp->holdOff[i]; + } + } /* profile != DRC_NONE */ + } /* for i=1..2 */ + } else { + /* no compression */ + drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f); + drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f); + } - /* - * Convert to dBFS, apply dialnorm - */ - /* descaled peak in ld64 representation */ - FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT)); - - /* if (peak < 1e-6) level = 1e-6f; */ - ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); - - /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) - * - * additional scaling with METADATA_FRACT_BITS: - * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) - * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i]) - * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] - */ - peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak)); - peak[i] += (FL2FX_DBL(0.5f)>>METADATA_INT_BITS); /* add a little bit headroom */ - peak[i] += drcComp->smoothGain[i]; - } + /************************************************************************** + * limiter + **************************************************************************/ + + findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev, + (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)), + (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)), + peak); + + for (i = 0; i < 2; i++) { + FIXP_DBL tmp = drcComp->prevPeak[i]; + drcComp->prevPeak[i] = peak[i]; + peak[i] = fixMax(peak[i], tmp); + + /* + * Convert to dBFS, apply dialnorm + */ + /* descaled peak in ld64 representation */ + FIXP_DBL ld_peak = + CalcLdData(peak[i]) + + (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT)); + + /* if (peak < 1e-6) level = 1e-6f; */ + ld_peak = + fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f)); + + /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 * + * log(2)/log(10) * ld(peak[i]) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 * + * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) + * + * additional scaling with METADATA_FRACT_BITS: + * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + * + 0.2f + + * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS) + * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * + * 2*0.30102999566398119521373889472449 * ld64(peak[i]) + * + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i] + */ + peak[i] = fMult( + (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)), + fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak)); + peak[i] += + (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */ + peak[i] += drcComp->smoothGain[i]; + } - /* peak -= dialnorm + 31; */ /* this is Dolby style only */ - peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ + /* peak -= dialnorm + 31; */ /* this is Dolby style only */ + peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel) + << (METADATA_FRACT_BITS - + 16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */ - /* peak += 11; */ /* this is Dolby style only */ /* RF mode output is 11dB higher */ - /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ - peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ + /* peak += 11; */ + /* this is Dolby style only */ /* RF mode output is 11dB higher */ + /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/ + peak[1] -= + (FIXP_DBL)((dialnorm - comp_TargetRefLevel) + << (METADATA_FRACT_BITS - + 16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */ - /* limiter gain */ - drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ - drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); + /* limiter gain */ + drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */ + drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]); - drcComp->limGain[1] += 2*drcComp->limDecay; /* linear limiter release */ - drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); + drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */ + drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]); - /*************************************************************************/ + /*************************************************************************/ - /* apply limiting, return DRC gains*/ - { - FIXP_DBL tmp; + /* apply limiting, return DRC gains*/ + { + FIXP_DBL tmp; - tmp = drcComp->smoothGain[0]; - if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { - tmp += drcComp->limGain[0]; - } - *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); + tmp = drcComp->smoothGain[0]; + if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) { + tmp += drcComp->limGain[0]; + } + *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); - tmp = drcComp->smoothGain[1]; - if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { - tmp += drcComp->limGain[1]; - } - *pCompr = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16)); + tmp = drcComp->smoothGain[1]; + if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) { + tmp += drcComp->limGain[1]; } + *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16)); + } - return 0; + return 0; } - -DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) -{ - return drcComp->profile[0]; +DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) { + return drcComp->profile[0]; } -DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) -{ - return drcComp->profile[1]; +DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) { + return drcComp->profile[1]; } - - diff --git a/libAACenc/src/metadata_compressor.h b/libAACenc/src/metadata_compressor.h index ff639b5..1d0aa42 100644 --- a/libAACenc/src/metadata_compressor.h +++ b/libAACenc/src/metadata_compressor.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,75 +90,73 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): M. Neusinger - Description: Compressor for AAC Metadata Generator + Author(s): M. Neusinger -******************************************************************************/ + Description: Compressor for AAC Metadata Generator -#ifndef _METADATA_COMPRESSOR_H -#define _METADATA_COMPRESSOR_H +*******************************************************************************/ +#ifndef METADATA_COMPRESSOR_H +#define METADATA_COMPRESSOR_H #include "FDK_audio.h" #include "common_fix.h" #include "aacenc.h" +#define LFE_LEV_SCALE 2 /** * DRC compression profiles. */ typedef enum DRC_PROFILE { - DRC_NONE = 0, - DRC_FILMSTANDARD = 1, - DRC_FILMLIGHT = 2, + DRC_NONE = 0, + DRC_FILMSTANDARD = 1, + DRC_FILMLIGHT = 2, DRC_MUSICSTANDARD = 3, - DRC_MUSICLIGHT = 4, - DRC_SPEECH = 5, - DRC_DELAY_TEST = 6 + DRC_MUSICLIGHT = 4, + DRC_SPEECH = 5, + DRC_DELAY_TEST = 6, + DRC_NOT_PRESENT = -2 } DRC_PROFILE; - /** * DRC Compressor handle. */ -typedef struct DRC_COMP DRC_COMP, *HDRC_COMP; +typedef struct DRC_COMP DRC_COMP, *HDRC_COMP; /** * \brief Open a DRC Compressor instance. * * Allocate memory for a compressor instance. * - * \param phDrcComp A pointer to a compressor handle. Initialized on return. + * \param phDrcComp A pointer to a compressor handle. Initialized on + * return. * * \return * - 0, on succes. * - unequal 0, on failure. */ -INT FDK_DRC_Generator_Open( - HDRC_COMP *phDrcComp - ); - +INT FDK_DRC_Generator_Open(HDRC_COMP *phDrcComp); /** * \brief Close the DRC Compressor instance. * * Deallocate instance and free whole memory. * - * \param phDrcComp Pointer to the compressor handle to be deallocated. + * \param phDrcComp Pointer to the compressor handle to be + * deallocated. * * \return * - 0, on succes. * - unequal 0, on failure. */ -INT FDK_DRC_Generator_Close( - HDRC_COMP *phDrcComp - ); +INT FDK_DRC_Generator_Close(HDRC_COMP *phDrcComp); /** * \brief Configure DRC Compressor. @@ -155,7 +164,8 @@ INT FDK_DRC_Generator_Close( * \param drcComp Compressor handle. * \param profileLine DRC profile for line mode. * \param profileRF DRC profile for RF mode. - * \param blockLength Length of processing block in samples per channel. + * \param blockLength Length of processing block in samples per + * channel. * \param sampleRate Sampling rate in Hz. * \param channelMode Channel configuration. * \param channelOrder Channel order, MPEG or WAV. @@ -165,46 +175,49 @@ INT FDK_DRC_Generator_Close( * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_Initialize( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF, - const INT blockLength, - const UINT sampleRate, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder, - const UCHAR useWeighting - ); +INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF, + const INT blockLength, const UINT sampleRate, + const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder, + const UCHAR useWeighting); /** * \brief Calculate DRC Compressor Gain. * * \param drcComp Compressor handle. * \param inSamples Pointer to interleaved input audio samples. + * \param inSamplesBufSize Size of inSamples for one channel. * \param dialnorm Dialog Level in dB (typically -31...-1). * \param drc_TargetRefLevel * \param comp_TargetRefLevel - * \param clev Downmix center mix factor (typically 0.707, 0.595 or 0.5) - * \param slev Downmix surround mix factor (typically 0.707, 0.5, or 0) - * \param dynrng Pointer to variable receiving line mode DRC gain in dB - * \param compr Pointer to variable receiving RF mode DRC gain in dB + * \param clev Downmix center mix factor (typically 0.707, + * 0.595 or 0.5) + * \param slev Downmix surround mix factor (typically 0.707, + * 0.5, or 0) + * \param ext_leva Downmix gain factor A + * \param ext_levb Downmix gain factor B + * \param lfe_lev LFE gain factor + * \param dmxGain5 Gain factor for downmix to 5 channels + * \param dmxGain2 Gain factor for downmix to 2 channels + * \param dynrng Pointer to variable receiving line mode DRC gain + * in dB + * \param compr Pointer to variable receiving RF mode DRC gain + * in dB * * \return * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_Calc( - HDRC_COMP drcComp, - const INT_PCM * const inSamples, - const INT dialnorm, - const INT drc_TargetRefLevel, - const INT comp_TargetRefLevel, - FIXP_DBL clev, - FIXP_DBL slev, - INT * const dynrng, - INT * const compr - ); - +INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM *const inSamples, + const UINT inSamplesBufSize, const INT dialnorm, + const INT drc_TargetRefLevel, + const INT comp_TargetRefLevel, const FIXP_DBL clev, + const FIXP_DBL slev, const FIXP_DBL ext_leva, + const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev, + const INT dmxGain5, const INT dmxGain2, + INT *const dynrng, INT *const compr); /** * \brief Configure DRC Compressor Profile. @@ -217,12 +230,9 @@ INT FDK_DRC_Generator_Calc( * - 0, on success, * - unequal 0, on failure */ -INT FDK_DRC_Generator_setDrcProfile( - HDRC_COMP drcComp, - const DRC_PROFILE profileLine, - const DRC_PROFILE profileRF - ); - +INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp, + const DRC_PROFILE profileLine, + const DRC_PROFILE profileRF); /** * \brief Get DRC profile for line mode. @@ -231,10 +241,7 @@ INT FDK_DRC_Generator_setDrcProfile( * * \return Current Profile. */ -DRC_PROFILE FDK_DRC_Generator_getDrcProfile( - const HDRC_COMP drcComp - ); - +DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp); /** * \brief Get DRC profile for RF mode. @@ -243,10 +250,6 @@ DRC_PROFILE FDK_DRC_Generator_getDrcProfile( * * \return Current Profile. */ -DRC_PROFILE FDK_DRC_Generator_getCompProfile( - const HDRC_COMP drcComp - ); - - -#endif /* _METADATA_COMPRESSOR_H */ +DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp); +#endif /* METADATA_COMPRESSOR_H */ diff --git a/libAACenc/src/metadata_main.cpp b/libAACenc/src/metadata_main.cpp index 90f8f4e..edd3831 100644 --- a/libAACenc/src/metadata_main.cpp +++ b/libAACenc/src/metadata_main.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,15 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): V. Bacigalupo - Description: Metadata Encoder library interface functions + Author(s): V. Bacigalupo -******************************************************************************/ + Description: Metadata Encoder library interface functions +*******************************************************************************/ #include "metadata_main.h" #include "metadata_compressor.h" @@ -96,551 +107,697 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" /*----------------- defines ----------------------*/ -#define MAX_DRC_BANDS (1<<4) -#define MAX_DRC_CHANNELS (8) -#define MAX_DRC_FRAMELEN (2*1024) +#define MAX_DRC_BANDS (1 << 4) +#define MAX_DRC_FRAMELEN (2 * 1024) +#define MAX_DELAY_FRAMES (3) /*--------------- structure definitions --------------------*/ -typedef struct AAC_METADATA -{ +typedef struct AAC_METADATA { /* MPEG: Dynamic Range Control */ struct { - UCHAR prog_ref_level_present; - SCHAR prog_ref_level; + UCHAR prog_ref_level_present; + SCHAR prog_ref_level; - UCHAR dyn_rng_sgn[MAX_DRC_BANDS]; - UCHAR dyn_rng_ctl[MAX_DRC_BANDS]; + UCHAR dyn_rng_sgn[MAX_DRC_BANDS]; + UCHAR dyn_rng_ctl[MAX_DRC_BANDS]; - UCHAR drc_bands_present; - UCHAR drc_band_incr; - UCHAR drc_band_top[MAX_DRC_BANDS]; - UCHAR drc_interpolation_scheme; - AACENC_METADATA_DRC_PROFILE drc_profile; - INT drc_TargetRefLevel; /* used for Limiter */ + UCHAR drc_bands_present; + UCHAR drc_band_incr; + UCHAR drc_band_top[MAX_DRC_BANDS]; + UCHAR drc_interpolation_scheme; + AACENC_METADATA_DRC_PROFILE drc_profile; + INT drc_TargetRefLevel; /* used for Limiter */ /* excluded channels */ - UCHAR excluded_chns_present; - UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */ + UCHAR excluded_chns_present; + UCHAR exclude_mask[2]; /* MAX_NUMBER_CHANNELS/8 */ } mpegDrc; /* ETSI: addtl ancillary data */ struct { /* Heavy Compression */ - UCHAR compression_on; /* flag, if compression value should be written */ - UCHAR compression_value; /* compression value */ - AACENC_METADATA_DRC_PROFILE comp_profile; - INT comp_TargetRefLevel; /* used for Limiter */ - INT timecode_coarse_status; - INT timecode_fine_status; + UCHAR compression_on; /* flag, if compression value should be written */ + UCHAR compression_value; /* compression value */ + AACENC_METADATA_DRC_PROFILE comp_profile; + INT comp_TargetRefLevel; /* used for Limiter */ + INT timecode_coarse_status; + INT timecode_fine_status; + + UCHAR extAncDataStatus; + + struct { + UCHAR ext_downmix_lvl_status; + UCHAR ext_downmix_gain_status; + UCHAR ext_lfe_downmix_status; + UCHAR + ext_dmix_a_idx; /* extended downmix level (0..7, according to table) + */ + UCHAR + ext_dmix_b_idx; /* extended downmix level (0..7, according to table) + */ + UCHAR dmx_gain_5_sgn; + UCHAR dmx_gain_5_idx; + UCHAR dmx_gain_2_sgn; + UCHAR dmx_gain_2_idx; + UCHAR ext_dmix_lfe_idx; /* extended downmix level for lfe (0..15, + according to table) */ + + } extAncData; + } etsiAncData; - SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */ - SCHAR surroundMixLevel; /* surround downmix level (0...7, according to table) */ - UCHAR WritePCEMixDwnIdx; /* flag */ - UCHAR DmxLvl_On; /* flag */ + SCHAR centerMixLevel; /* center downmix level (0...7, according to table) */ + SCHAR + surroundMixLevel; /* surround downmix level (0...7, according to table) */ + UCHAR WritePCEMixDwnIdx; /* flag */ + UCHAR DmxLvl_On; /* flag */ - UCHAR dolbySurroundMode; + UCHAR dolbySurroundMode; + UCHAR drcPresentationMode; - UCHAR metadataMode; /* indicate meta data mode in current frame (delay line) */ + UCHAR + metadataMode; /* indicate meta data mode in current frame (delay line) */ } AAC_METADATA; -struct FDK_METADATA_ENCODER -{ - INT metadataMode; - HDRC_COMP hDrcComp; - AACENC_MetaData submittedMetaData; +typedef struct FDK_METADATA_ENCODER { + INT metadataMode; + HDRC_COMP hDrcComp; + AACENC_MetaData submittedMetaData; - INT nAudioDataDelay; - INT nMetaDataDelay; - INT nChannels; + INT nAudioDataDelay; /* Additional delay to round up to next frame border (in + samples) */ + INT nMetaDataDelay; /* Meta data delay (in frames) */ + INT nChannels; + CHANNEL_MODE channelMode; - INT_PCM audioDelayBuffer[MAX_DRC_CHANNELS*MAX_DRC_FRAMELEN]; - int audioDelayIdx; + INT_PCM* pAudioDelayBuffer; - AAC_METADATA metaDataBuffer[3]; - int metaDataDelayIdx; + AAC_METADATA metaDataBuffer[MAX_DELAY_FRAMES]; + INT metaDataDelayIdx; - UCHAR drcInfoPayload[12]; - UCHAR drcDsePayload[8]; + UCHAR drcInfoPayload[12]; + UCHAR drcDsePayload[8]; + + INT matrix_mixdown_idx; - INT matrix_mixdown_idx; AACENC_EXT_PAYLOAD exPayload[2]; - INT nExtensions; + INT nExtensions; - INT finalizeMetaData; /* Delay switch off by one frame and write default configuration to - finalize the metadata setup. */ -}; + UINT maxChannels; /* Maximum number of audio channels to be supported. */ + INT finalizeMetaData; /* Delay switch off by one frame and write default + configuration to finalize the metadata setup. */ + INT initializeMetaData; /* Fill up delay line with first meta data info. This + is required to have meta data already in first + frame. */ +} FDK_METADATA_ENCODER; /*---------------- constants -----------------------*/ static const AACENC_MetaData defaultMetaDataSetup = { - AACENC_METADATA_DRC_NONE, - AACENC_METADATA_DRC_NONE, - -(31<<16), - -(31<<16), - 0, - -(31<<16), - 0, - 0, - 0, - 0, - 0 + AACENC_METADATA_DRC_NONE, /* drc_profile */ + AACENC_METADATA_DRC_NOT_PRESENT, /* comp_profile */ + -(31 << 16), /* drc_TargetRefLevel */ + -(23 << 16), /* comp_TargetRefLevel */ + 0, /* prog_ref_level_present */ + -(23 << 16), /* prog_ref_level */ + 0, /* PCE_mixdown_idx_present */ + 0, /* ETSI_DmxLvl_present */ + 0, /* centerMixLevel */ + 0, /* surroundMixLevel */ + 0, /* dolbySurroundMode */ + 0, /* drcPresentationMode */ + {0, 0, 0, 0, 0, 0, 0, 0, 0} /* ExtMetaData */ }; static const FIXP_DBL dmxTable[8] = { - ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), FL2FXCONST_DBL(0.596f), - FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f) -}; + ((FIXP_DBL)MAXVAL_DBL), FL2FXCONST_DBL(0.841f), FL2FXCONST_DBL(0.707f), + FL2FXCONST_DBL(0.596f), FL2FXCONST_DBL(0.500f), FL2FXCONST_DBL(0.422f), + FL2FXCONST_DBL(0.355f), FL2FXCONST_DBL(0.000f)}; -static const UCHAR surmix2matrix_mixdown_idx[8] = { - 0, 0, 0, 1, 1, 2, 2, 3 -}; +#define FL2DMXLFE(a) FL2FXCONST_DBL((a) / (1 << LFE_LEV_SCALE)) +static const FIXP_DBL dmxLfeTable[16] = { + FL2DMXLFE(3.162f), FL2DMXLFE(2.000f), FL2DMXLFE(1.679f), FL2DMXLFE(1.413f), + FL2DMXLFE(1.189f), FL2DMXLFE(1.000f), FL2DMXLFE(0.841f), FL2DMXLFE(0.707f), + FL2DMXLFE(0.596f), FL2DMXLFE(0.500f), FL2DMXLFE(0.316f), FL2DMXLFE(0.178f), + FL2DMXLFE(0.100f), FL2DMXLFE(0.032f), FL2DMXLFE(0.010f), FL2DMXLFE(0.000f)}; +static const UCHAR surmix2matrix_mixdown_idx[8] = {0, 0, 0, 1, 1, 2, 2, 3}; /*--------------- function declarations --------------------*/ static FDK_METADATA_ERROR WriteMetadataPayload( - const HANDLE_FDK_METADATA_ENCODER hMetaData, - const AAC_METADATA * const pMetadata - ); + const HANDLE_FDK_METADATA_ENCODER hMetaData, + const AAC_METADATA* const pMetadata); -static INT WriteDynamicRangeInfoPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ); +static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload); -static INT WriteEtsiAncillaryDataPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ); +static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload); static FDK_METADATA_ERROR CompensateAudioDelay( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples - ); + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples); static FDK_METADATA_ERROR LoadSubmittedMetadata( - const AACENC_MetaData * const hMetadata, - const INT nChannels, - const INT metadataMode, - AAC_METADATA * const pAacMetaData - ); - -static FDK_METADATA_ERROR ProcessCompressor( - AAC_METADATA *pMetadata, - HDRC_COMP hDrcComp, - const INT_PCM * const pSamples, - const INT nSamples - ); + const AACENC_MetaData* const hMetadata, const INT nChannels, + const INT metadataMode, AAC_METADATA* const pAacMetaData); + +static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata, + HDRC_COMP hDrcComp, + const INT_PCM* const pSamples, + const UINT samplesBufSize, + const INT nSamples); /*------------- function definitions ----------------*/ -static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) -{ - DRC_PROFILE drcProfile = DRC_NONE; - - switch(aacProfile) { - case AACENC_METADATA_DRC_NONE: drcProfile = DRC_NONE; break; - case AACENC_METADATA_DRC_FILMSTANDARD: drcProfile = DRC_FILMSTANDARD; break; - case AACENC_METADATA_DRC_FILMLIGHT: drcProfile = DRC_FILMLIGHT; break; - case AACENC_METADATA_DRC_MUSICSTANDARD: drcProfile = DRC_MUSICSTANDARD; break; - case AACENC_METADATA_DRC_MUSICLIGHT: drcProfile = DRC_MUSICLIGHT; break; - case AACENC_METADATA_DRC_SPEECH: drcProfile = DRC_SPEECH; break; - default: drcProfile = DRC_NONE; break; - } - return drcProfile; +static DRC_PROFILE convertProfile(AACENC_METADATA_DRC_PROFILE aacProfile) { + DRC_PROFILE drcProfile = DRC_NONE; + + switch (aacProfile) { + case AACENC_METADATA_DRC_NONE: + drcProfile = DRC_NONE; + break; + case AACENC_METADATA_DRC_FILMSTANDARD: + drcProfile = DRC_FILMSTANDARD; + break; + case AACENC_METADATA_DRC_FILMLIGHT: + drcProfile = DRC_FILMLIGHT; + break; + case AACENC_METADATA_DRC_MUSICSTANDARD: + drcProfile = DRC_MUSICSTANDARD; + break; + case AACENC_METADATA_DRC_MUSICLIGHT: + drcProfile = DRC_MUSICLIGHT; + break; + case AACENC_METADATA_DRC_SPEECH: + drcProfile = DRC_SPEECH; + break; + case AACENC_METADATA_DRC_NOT_PRESENT: + drcProfile = DRC_NOT_PRESENT; + break; + default: + drcProfile = DRC_NONE; + break; + } + return drcProfile; } - /* convert dialog normalization to program reference level */ -/* NOTE: this only is correct, if the decoder target level is set to -31dB for line mode / -20dB for RF mode */ -static UCHAR dialnorm2progreflvl(const INT d) -{ - return ((UCHAR)FDKmax(0, FDKmin((-d + (1<<13)) >> 14, 127))); +/* NOTE: this only is correct, if the decoder target level is set to -31dB for + * line mode / -20dB for RF mode */ +static UCHAR dialnorm2progreflvl(const INT d) { + return ((UCHAR)fMax(0, fMin((-d + (1 << 13)) >> 14, 127))); } /* convert program reference level to dialog normalization */ -static INT progreflvl2dialnorm(const UCHAR p) -{ - return -((INT)(p<<(16-2))); +static INT progreflvl2dialnorm(const UCHAR p) { + return -((INT)(p << (16 - 2))); } /* encode downmix levels to Downmixing_levels_MPEG4 */ -static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) -{ - SCHAR dmxLvls = 0; - dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */ - dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */ +static SCHAR encodeDmxLvls(const SCHAR cmixlev, const SCHAR surmixlev) { + SCHAR dmxLvls = 0; + dmxLvls |= 0x80 | (cmixlev << 4); /* center_mix_level_on */ + dmxLvls |= 0x08 | surmixlev; /* surround_mix_level_on */ - return dmxLvls; + return dmxLvls; } /* encode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */ -static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, UCHAR* const dyn_rng_sgn ) -{ - if(gain < 0) - { - *dyn_rng_sgn = 1; - gain = -gain; - } - else - { - *dyn_rng_sgn = 0; - } - gain = FDKmin(gain,(127<<14)); - - *dyn_rng_ctl = (UCHAR)((gain + (1<<13)) >> 14); +static void encodeDynrng(INT gain, UCHAR* const dyn_rng_ctl, + UCHAR* const dyn_rng_sgn) { + if (gain < 0) { + *dyn_rng_sgn = 1; + gain = -gain; + } else { + *dyn_rng_sgn = 0; + } + gain = fMin(gain, (127 << 14)); + + *dyn_rng_ctl = (UCHAR)((gain + (1 << 13)) >> 14); } /* decode AAC DRC gain (ISO/IEC 14496-3:2005 4.5.2.7) */ -static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) -{ - INT tmp = ((INT)dyn_rng_ctl << (16-2)); - if (dyn_rng_sgn) tmp = -tmp; +static INT decodeDynrng(const UCHAR dyn_rng_ctl, const UCHAR dyn_rng_sgn) { + INT tmp = ((INT)dyn_rng_ctl << (16 - 2)); + if (dyn_rng_sgn) tmp = -tmp; - return tmp; + return tmp; } /* encode AAC compression value (ETSI TS 101 154 page 99) */ -static UCHAR encodeCompr(INT gain) -{ - UCHAR x, y; - INT tmp; - - /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */ - tmp = ((3156476 - gain) * 15 + 197283) / 394566; - - if (tmp >= 240) { - return 0xFF; - } - else if (tmp < 0) { - return 0; - } - else { - x = tmp / 15; - y = tmp % 15; - } - - return (x << 4) | y; +static UCHAR encodeCompr(INT gain) { + UCHAR x, y; + INT tmp; + + /* tmp = (int)((48.164f - gain) / 6.0206f * 15 + 0.5f); */ + tmp = ((3156476 - gain) * 15 + 197283) / 394566; + + if (tmp >= 240) { + return 0xFF; + } else if (tmp < 0) { + return 0; + } else { + x = tmp / 15; + y = tmp % 15; + } + + return (x << 4) | y; } /* decode AAC compression value (ETSI TS 101 154 page 99) */ -static INT decodeCompr(const UCHAR compr) -{ - INT gain; - SCHAR x = compr >> 4; /* 4 MSB of compr */ - UCHAR y = (compr & 0x0F); /* 4 LSB of compr */ - - /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */ - gain = (INT)( scaleValue(((LONG)FL2FXCONST_DBL(6.0206f/128.f)*(8-x) - (LONG)FL2FXCONST_DBL(0.4014f/128.f)*y), -(DFRACT_BITS-1-7-16)) ); - - return gain; +static INT decodeCompr(const UCHAR compr) { + INT gain; + SCHAR x = compr >> 4; /* 4 MSB of compr */ + UCHAR y = (compr & 0x0F); /* 4 LSB of compr */ + + /* gain = (INT)((48.164f - 6.0206f * x - 0.4014f * y) ); */ + gain = (INT)( + scaleValue((FIXP_DBL)(((LONG)FL2FXCONST_DBL(6.0206f / 128.f) * (8 - x) - + (LONG)FL2FXCONST_DBL(0.4014f / 128.f) * y)), + -(DFRACT_BITS - 1 - 7 - 16))); + + return gain; } - -FDK_METADATA_ERROR FDK_MetadataEnc_Open( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - HANDLE_FDK_METADATA_ENCODER hMetaData = NULL; - - if (phMetaData == NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - /* allocate memory */ - hMetaData = (HANDLE_FDK_METADATA_ENCODER) FDKcalloc(1, sizeof(FDK_METADATA_ENCODER) ); - - if (hMetaData == NULL) { - err = METADATA_MEMORY_ERROR; - goto bail; - } - - FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER)); - - /* Allocate DRC Compressor. */ - if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp)!=0) { - err = METADATA_MEMORY_ERROR; - goto bail; - } - - /* Return metadata instance */ - *phMetaData = hMetaData; - - return err; +FDK_METADATA_ERROR FDK_MetadataEnc_Open(HANDLE_FDK_METADATA_ENCODER* phMetaData, + const UINT maxChannels) { + FDK_METADATA_ERROR err = METADATA_OK; + HANDLE_FDK_METADATA_ENCODER hMetaData = NULL; + + if (phMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + /* allocate memory */ + if (NULL == (hMetaData = (HANDLE_FDK_METADATA_ENCODER)FDKcalloc( + 1, sizeof(FDK_METADATA_ENCODER)))) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMetaData, sizeof(FDK_METADATA_ENCODER)); + + if (NULL == (hMetaData->pAudioDelayBuffer = (INT_PCM*)FDKcalloc( + maxChannels * MAX_DRC_FRAMELEN, sizeof(INT_PCM)))) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMetaData->pAudioDelayBuffer, + maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM)); + hMetaData->maxChannels = maxChannels; + + /* Allocate DRC Compressor. */ + if (FDK_DRC_Generator_Open(&hMetaData->hDrcComp) != 0) { + err = METADATA_MEMORY_ERROR; + goto bail; + } + hMetaData->channelMode = MODE_UNKNOWN; + + /* Return metadata instance */ + *phMetaData = hMetaData; + + return err; bail: - FDK_MetadataEnc_Close(&hMetaData); - return err; + FDK_MetadataEnc_Close(&hMetaData); + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Close( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (phMetaData == NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - if (*phMetaData != NULL) { - FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp); - FDKfree(*phMetaData); - *phMetaData = NULL; - } + HANDLE_FDK_METADATA_ENCODER* phMetaData) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (phMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + if (*phMetaData != NULL) { + FDK_DRC_Generator_Close(&(*phMetaData)->hDrcComp); + FDKfree((*phMetaData)->pAudioDelayBuffer); + FDKfree(*phMetaData); + *phMetaData = NULL; + } bail: - return err; + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Init( - HANDLE_FDK_METADATA_ENCODER hMetaData, - const INT resetStates, - const INT metadataMode, - const INT audioDelay, - const UINT frameLength, - const UINT sampleRate, - const UINT nChannels, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - int i, nFrames, delay; - - if (hMetaData==NULL) { - err = METADATA_INVALID_HANDLE; - goto bail; - } - - /* Determine values for delay compensation. */ - for (nFrames=0, delay=audioDelay-frameLength; delay>0; delay-=frameLength, nFrames++); - - if ( (hMetaData->nChannels>MAX_DRC_CHANNELS) || ((-delay)>MAX_DRC_FRAMELEN) ) { - err = METADATA_INIT_ERROR; - goto bail; - } - - /* Initialize with default setup. */ - FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData)); - - hMetaData->finalizeMetaData = 0; /* finalize meta data only while on/off switching, else disabled */ - - /* Reset delay lines. */ - if ( resetStates || (hMetaData->nAudioDataDelay!=-delay) || (hMetaData->nChannels!=(INT)nChannels) ) - { - FDKmemclear(hMetaData->audioDelayBuffer, sizeof(hMetaData->audioDelayBuffer)); - FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer)); - hMetaData->audioDelayIdx = 0; - hMetaData->metaDataDelayIdx = 0; - } - else { - /* Enable meta data. */ - if ( (hMetaData->metadataMode==0) && (metadataMode!=0) ) { - /* disable meta data in all delay lines */ - for (i=0; i<(int)(sizeof(hMetaData->metaDataBuffer)/sizeof(AAC_METADATA)); i++) { - LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, &hMetaData->metaDataBuffer[i]); - } + HANDLE_FDK_METADATA_ENCODER hMetaData, const INT resetStates, + const INT metadataMode, const INT audioDelay, const UINT frameLength, + const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder) { + FDK_METADATA_ERROR err = METADATA_OK; + int i, nFrames, delay; + + if (hMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + goto bail; + } + + /* Determine values for delay compensation. */ + for (nFrames = 0, delay = audioDelay - (INT)frameLength; delay > 0; + delay -= (INT)frameLength, nFrames++) + ; + + if ((nChannels > (8)) || (nChannels > hMetaData->maxChannels) || + ((-delay) > MAX_DRC_FRAMELEN) || nFrames >= MAX_DELAY_FRAMES) { + err = METADATA_INIT_ERROR; + goto bail; + } + + /* Initialize with default setup. */ + FDKmemcpy(&hMetaData->submittedMetaData, &defaultMetaDataSetup, + sizeof(AACENC_MetaData)); + + hMetaData->finalizeMetaData = + 0; /* finalize meta data only while on/off switching, else disabled */ + hMetaData->initializeMetaData = + 0; /* fill up meta data delay line only at a reset otherwise disabled */ + + /* Reset delay lines. */ + if (resetStates || (hMetaData->nAudioDataDelay != -delay) || + (hMetaData->channelMode != channelMode)) { + if (resetStates || (hMetaData->channelMode == MODE_UNKNOWN)) { + /* clear delay buffer */ + FDKmemclear(hMetaData->pAudioDelayBuffer, + hMetaData->maxChannels * MAX_DRC_FRAMELEN * sizeof(INT_PCM)); + } else { + /* if possible, keep static audio channels for seamless channel + * reconfiguration */ + FDK_channelMapDescr mapDescrPrev, mapDescr; + int c, src[2] = {-1, -1}, dst[2] = {-1, -1}; + + FDK_chMapDescr_init(&mapDescrPrev, NULL, 0, + (channelOrder == CH_ORDER_MPEG) ? 1 : 0); + FDK_chMapDescr_init(&mapDescr, NULL, 0, + (channelOrder == CH_ORDER_MPEG) ? 1 : 0); + + switch (channelMode) { + case MODE_1: + if ((INT)nChannels != 2) { + /* preserve center channel */ + src[0] = FDK_chMapDescr_getMapValue(&mapDescrPrev, 0, + hMetaData->channelMode); + dst[0] = FDK_chMapDescr_getMapValue(&mapDescr, 0, channelMode); + } + break; + case MODE_2: + case MODE_1_2: + case MODE_1_2_1: + case MODE_1_2_2: + case MODE_1_2_2_1: + if (hMetaData->nChannels >= 2) { + /* preserve left/right channel */ + src[0] = FDK_chMapDescr_getMapValue( + &mapDescrPrev, ((hMetaData->channelMode == 2) ? 0 : 1), + hMetaData->channelMode); + src[1] = FDK_chMapDescr_getMapValue( + &mapDescrPrev, ((hMetaData->channelMode == 2) ? 1 : 2), + hMetaData->channelMode); + dst[0] = FDK_chMapDescr_getMapValue( + &mapDescr, ((channelMode == 2) ? 0 : 1), channelMode); + dst[1] = FDK_chMapDescr_getMapValue( + &mapDescr, ((channelMode == 2) ? 1 : 2), channelMode); + } + break; + default:; } + C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, (8)); + FDKmemclear(scratch_audioDelayBuffer, (8) * sizeof(INT_PCM)); + + i = (hMetaData->nChannels > (INT)nChannels) + ? 0 + : hMetaData->nAudioDataDelay - 1; + do { + for (c = 0; c < 2; c++) { + if (src[c] != -1 && dst[c] != -1) { + scratch_audioDelayBuffer[dst[c]] = + hMetaData->pAudioDelayBuffer[i * hMetaData->nChannels + src[c]]; + } + } + FDKmemcpy(&hMetaData->pAudioDelayBuffer[i * nChannels], + scratch_audioDelayBuffer, nChannels * sizeof(INT_PCM)); + i += (hMetaData->nChannels > (INT)nChannels) ? 1 : -1; + } while ((i < hMetaData->nAudioDataDelay) && (i >= 0)); - /* Disable meta data.*/ - if ( (hMetaData->metadataMode!=0) && (metadataMode==0) ) { - hMetaData->finalizeMetaData = hMetaData->metadataMode; + C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, (8)); + } + FDKmemclear(hMetaData->metaDataBuffer, sizeof(hMetaData->metaDataBuffer)); + hMetaData->metaDataDelayIdx = 0; + hMetaData->initializeMetaData = + 1; /* fill up delay line with first meta data info */ + } else { + /* Enable meta data. */ + if ((hMetaData->metadataMode == 0) && (metadataMode != 0)) { + /* disable meta data in all delay lines */ + for (i = 0; + i < (int)(sizeof(hMetaData->metaDataBuffer) / sizeof(AAC_METADATA)); + i++) { + LoadSubmittedMetadata(&hMetaData->submittedMetaData, nChannels, 0, + &hMetaData->metaDataBuffer[i]); } } - /* Initialize delay. */ - hMetaData->nAudioDataDelay = -delay; - hMetaData->nMetaDataDelay = nFrames; - hMetaData->nChannels = nChannels; - hMetaData->metadataMode = metadataMode; - - /* Initialize compressor. */ - if (metadataMode != 0) { - if ( FDK_DRC_Generator_Initialize( - hMetaData->hDrcComp, - DRC_NONE, - DRC_NONE, - frameLength, - sampleRate, - channelMode, - channelOrder, - 1) != 0) - { - err = METADATA_INIT_ERROR; - } + /* Disable meta data.*/ + if ((hMetaData->metadataMode != 0) && (metadataMode == 0)) { + hMetaData->finalizeMetaData = hMetaData->metadataMode; + } + } + + /* Initialize delay. */ + hMetaData->nAudioDataDelay = -delay; + hMetaData->nMetaDataDelay = nFrames; + hMetaData->nChannels = nChannels; + hMetaData->channelMode = channelMode; + hMetaData->metadataMode = metadataMode; + + /* Initialize compressor. */ + if ((metadataMode == 1) || (metadataMode == 2)) { + if (FDK_DRC_Generator_Initialize(hMetaData->hDrcComp, DRC_NONE, DRC_NONE, + frameLength, sampleRate, channelMode, + channelOrder, 1) != 0) { + err = METADATA_INIT_ERROR; } + } bail: - return err; + return err; } -static FDK_METADATA_ERROR ProcessCompressor( - AAC_METADATA *pMetadata, - HDRC_COMP hDrcComp, - const INT_PCM * const pSamples, - const INT nSamples - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if ( (pMetadata==NULL) || (hDrcComp==NULL) ) { - err = METADATA_INVALID_HANDLE; - return err; - } - DRC_PROFILE profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile); - DRC_PROFILE profileComp = convertProfile(pMetadata->etsiAncData.comp_profile); +static FDK_METADATA_ERROR ProcessCompressor(AAC_METADATA* pMetadata, + HDRC_COMP hDrcComp, + const INT_PCM* const pSamples, + const UINT samplesBufSize, + const INT nSamples) { + FDK_METADATA_ERROR err = METADATA_OK; - /* first, check if profile is same as last frame - * otherwise, update setup */ - if ( (profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) - || (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp)) ) - { - FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp); - } + INT dynrng, compr; + INT dmxGain5, dmxGain2; + DRC_PROFILE profileDrc; + DRC_PROFILE profileComp; - /* Sanity check */ - if (profileComp == DRC_NONE) { - pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external values will be written if not configured */ - } - - /* in case of embedding external values, copy this now (limiter may overwrite them) */ - INT dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], pMetadata->mpegDrc.dyn_rng_sgn[0]); - INT compr = decodeCompr(pMetadata->etsiAncData.compression_value); - - /* Call compressor */ - if (FDK_DRC_Generator_Calc(hDrcComp, - pSamples, - progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level), - pMetadata->mpegDrc.drc_TargetRefLevel, - pMetadata->etsiAncData.comp_TargetRefLevel, - dmxTable[pMetadata->centerMixLevel], - dmxTable[pMetadata->surroundMixLevel], - &dynrng, - &compr) != 0) - { - err = METADATA_ENCODE_ERROR; - goto bail; - } - - /* Write DRC values */ - pMetadata->mpegDrc.drc_band_incr = 0; - encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, pMetadata->mpegDrc.dyn_rng_sgn); - pMetadata->etsiAncData.compression_value = encodeCompr(compr); + if ((pMetadata == NULL) || (hDrcComp == NULL)) { + err = METADATA_INVALID_HANDLE; + return err; + } + + profileDrc = convertProfile(pMetadata->mpegDrc.drc_profile); + profileComp = convertProfile(pMetadata->etsiAncData.comp_profile); + + /* first, check if profile is same as last frame + * otherwise, update setup */ + if ((profileDrc != FDK_DRC_Generator_getDrcProfile(hDrcComp)) || + (profileComp != FDK_DRC_Generator_getCompProfile(hDrcComp))) { + FDK_DRC_Generator_setDrcProfile(hDrcComp, profileDrc, profileComp); + } + + /* Sanity check */ + if (profileComp == DRC_NONE) { + pMetadata->etsiAncData.compression_value = 0x80; /* to ensure no external + values will be written + if not configured */ + } + + /* in case of embedding external values, copy this now (limiter may overwrite + * them) */ + dynrng = decodeDynrng(pMetadata->mpegDrc.dyn_rng_ctl[0], + pMetadata->mpegDrc.dyn_rng_sgn[0]); + compr = decodeCompr(pMetadata->etsiAncData.compression_value); + + dmxGain5 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_5_idx, + pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn); + dmxGain2 = decodeDynrng(pMetadata->etsiAncData.extAncData.dmx_gain_2_idx, + pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn); + + /* Call compressor */ + if (FDK_DRC_Generator_Calc( + hDrcComp, pSamples, samplesBufSize, + progreflvl2dialnorm(pMetadata->mpegDrc.prog_ref_level), + pMetadata->mpegDrc.drc_TargetRefLevel, + pMetadata->etsiAncData.comp_TargetRefLevel, + dmxTable[pMetadata->centerMixLevel], + dmxTable[pMetadata->surroundMixLevel], + dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_a_idx], + dmxTable[pMetadata->etsiAncData.extAncData.ext_dmix_b_idx], + pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status + ? dmxLfeTable[pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx] + : (FIXP_DBL)0, + dmxGain5, dmxGain2, &dynrng, &compr) != 0) { + err = METADATA_ENCODE_ERROR; + goto bail; + } + + /* Write DRC values */ + pMetadata->mpegDrc.drc_band_incr = 0; + encodeDynrng(dynrng, pMetadata->mpegDrc.dyn_rng_ctl, + pMetadata->mpegDrc.dyn_rng_sgn); + pMetadata->etsiAncData.compression_value = encodeCompr(compr); bail: - return err; + return err; } FDK_METADATA_ERROR FDK_MetadataEnc_Process( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples, - const AACENC_MetaData * const pMetadata, - AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload, - UINT * nMetaDataExtensions, - INT * matrix_mixdown_idx - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode; - - /* Where to write new meta data info */ - metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx; - - /* How to write the data */ - metadataMode = hMetaDataEnc->metadataMode; - - /* Compensate meta data delay. */ - hMetaDataEnc->metaDataDelayIdx++; - if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) hMetaDataEnc->metaDataDelayIdx = 0; - - /* Where to read pending meta data info from. */ - metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx; - - /* Submit new data if available. */ - if (pMetadata!=NULL) { - FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, sizeof(AACENC_MetaData)); + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples, + const AACENC_MetaData* const pMetadata, + AACENC_EXT_PAYLOAD** ppMetaDataExtPayload, UINT* nMetaDataExtensions, + INT* matrix_mixdown_idx) { + FDK_METADATA_ERROR err = METADATA_OK; + int metaDataDelayWriteIdx, metaDataDelayReadIdx, metadataMode; + + /* Where to write new meta data info */ + metaDataDelayWriteIdx = hMetaDataEnc->metaDataDelayIdx; + + /* How to write the data */ + metadataMode = hMetaDataEnc->metadataMode; + + /* Compensate meta data delay. */ + hMetaDataEnc->metaDataDelayIdx++; + if (hMetaDataEnc->metaDataDelayIdx > hMetaDataEnc->nMetaDataDelay) + hMetaDataEnc->metaDataDelayIdx = 0; + + /* Where to read pending meta data info from. */ + metaDataDelayReadIdx = hMetaDataEnc->metaDataDelayIdx; + + /* Submit new data if available. */ + if (pMetadata != NULL) { + FDKmemcpy(&hMetaDataEnc->submittedMetaData, pMetadata, + sizeof(AACENC_MetaData)); + } + + /* Write one additional frame with default configuration of meta data. Ensure + * defined behaviour on decoder side. */ + if ((hMetaDataEnc->finalizeMetaData != 0) && + (hMetaDataEnc->metadataMode == 0)) { + FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, + sizeof(AACENC_MetaData)); + metadataMode = hMetaDataEnc->finalizeMetaData; + hMetaDataEnc->finalizeMetaData = 0; + } + + /* Get last submitted data. */ + if ((err = LoadSubmittedMetadata( + &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels, + metadataMode, + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != + METADATA_OK) { + goto bail; + } + + /* Calculate compressor if necessary and updata meta data info */ + if ((hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 1) || + (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode == 2)) { + if ((err = ProcessCompressor( + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], + hMetaDataEnc->hDrcComp, pAudioSamples, audioSamplesBufSize, + nAudioSamples)) != METADATA_OK) { + /* Get last submitted data again. */ + LoadSubmittedMetadata( + &hMetaDataEnc->submittedMetaData, hMetaDataEnc->nChannels, + metadataMode, &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]); } - - /* Write one additional frame with default configuration of meta data. Ensure defined behaviour on decoder side. */ - if ( (hMetaDataEnc->finalizeMetaData!=0) && (hMetaDataEnc->metadataMode==0)) { - FDKmemcpy(&hMetaDataEnc->submittedMetaData, &defaultMetaDataSetup, sizeof(AACENC_MetaData)); - metadataMode = hMetaDataEnc->finalizeMetaData; - hMetaDataEnc->finalizeMetaData = 0; - } - - /* Get last submitted data. */ - if ( (err = LoadSubmittedMetadata( - &hMetaDataEnc->submittedMetaData, - hMetaDataEnc->nChannels, - metadataMode, - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])) != METADATA_OK ) - { - goto bail; - } - - /* Calculate compressor if necessary and updata meta data info */ - if (hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx].metadataMode != 0) { - if ( (err = ProcessCompressor( - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], - hMetaDataEnc->hDrcComp, - pAudioSamples, - nAudioSamples)) != METADATA_OK) - { - /* Get last submitted data again. */ - LoadSubmittedMetadata( - &hMetaDataEnc->submittedMetaData, - hMetaDataEnc->nChannels, - metadataMode, - &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx]); + } + + /* Fill up delay line with initial meta data info.*/ + if ((hMetaDataEnc->initializeMetaData != 0) && + (hMetaDataEnc->metadataMode != 0)) { + int i; + for (i = 0; + i < (int)(sizeof(hMetaDataEnc->metaDataBuffer) / sizeof(AAC_METADATA)); + i++) { + if (i != metaDataDelayWriteIdx) { + FDKmemcpy(&hMetaDataEnc->metaDataBuffer[i], + &hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx], + sizeof(hMetaDataEnc->metaDataBuffer[metaDataDelayWriteIdx])); } } - - /* Convert Meta Data side info to bitstream data. */ - if ( (err = WriteMetadataPayload(hMetaDataEnc, &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != METADATA_OK ) { - goto bail; - } - - /* Assign meta data to output */ - *ppMetaDataExtPayload = hMetaDataEnc->exPayload; - *nMetaDataExtensions = hMetaDataEnc->nExtensions; - *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx; + hMetaDataEnc->initializeMetaData = 0; + } + + /* Convert Meta Data side info to bitstream data. */ + FDK_ASSERT(metaDataDelayReadIdx < MAX_DELAY_FRAMES); + if ((err = WriteMetadataPayload( + hMetaDataEnc, + &hMetaDataEnc->metaDataBuffer[metaDataDelayReadIdx])) != + METADATA_OK) { + goto bail; + } + + /* Assign meta data to output */ + *ppMetaDataExtPayload = hMetaDataEnc->exPayload; + *nMetaDataExtensions = hMetaDataEnc->nExtensions; + *matrix_mixdown_idx = hMetaDataEnc->matrix_mixdown_idx; bail: - /* Compensate audio delay, reset err status. */ - err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, nAudioSamples); + /* Compensate audio delay, reset err status. */ + err = CompensateAudioDelay(hMetaDataEnc, pAudioSamples, audioSamplesBufSize, + nAudioSamples / hMetaDataEnc->nChannels); - return err; + return err; } - static FDK_METADATA_ERROR CompensateAudioDelay( - HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (hMetaDataEnc->nAudioDataDelay) { - int i, delaySamples = hMetaDataEnc->nAudioDataDelay*hMetaDataEnc->nChannels; - - for (i = 0; i < nAudioSamples; i++) { - INT_PCM tmp = pAudioSamples[i]; - pAudioSamples[i] = hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx]; - hMetaDataEnc->audioDelayBuffer[hMetaDataEnc->audioDelayIdx] = tmp; - - hMetaDataEnc->audioDelayIdx++; - if (hMetaDataEnc->audioDelayIdx >= delaySamples) hMetaDataEnc->audioDelayIdx = 0; - } + HANDLE_FDK_METADATA_ENCODER hMetaDataEnc, INT_PCM* const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (hMetaDataEnc->nAudioDataDelay) { + C_ALLOC_SCRATCH_START(scratch_audioDelayBuffer, INT_PCM, 1024); + + for (int c = 0; c < hMetaDataEnc->nChannels; c++) { + int M = 1024; + INT_PCM* pAudioSamples2 = pAudioSamples + c * audioSamplesBufSize; + int delayIdx = hMetaDataEnc->nAudioDataDelay; + + do { + M = fMin(M, delayIdx); + delayIdx -= M; + + FDKmemcpy(&scratch_audioDelayBuffer[0], + &pAudioSamples2[(nAudioSamples - M)], sizeof(INT_PCM) * M); + FDKmemmove(&pAudioSamples2[M], &pAudioSamples2[0], + sizeof(INT_PCM) * (nAudioSamples - M)); + FDKmemcpy( + &pAudioSamples2[0], + &hMetaDataEnc->pAudioDelayBuffer[delayIdx + + c * hMetaDataEnc->nAudioDataDelay], + sizeof(INT_PCM) * M); + FDKmemcpy( + &hMetaDataEnc->pAudioDelayBuffer[delayIdx + + c * hMetaDataEnc->nAudioDataDelay], + &scratch_audioDelayBuffer[0], sizeof(INT_PCM) * M); + + } while (delayIdx > 0); } - return err; + C_ALLOC_SCRATCH_END(scratch_audioDelayBuffer, INT_PCM, 1024); + } + + return err; } /*----------------------------------------------------------------------------- @@ -651,219 +808,377 @@ static FDK_METADATA_ERROR CompensateAudioDelay( ------------------------------------------------------------------------------*/ static FDK_METADATA_ERROR WriteMetadataPayload( - const HANDLE_FDK_METADATA_ENCODER hMetaData, - const AAC_METADATA * const pMetadata - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if ( (hMetaData==NULL) || (pMetadata==NULL) ) { - err = METADATA_INVALID_HANDLE; - goto bail; - } + const HANDLE_FDK_METADATA_ENCODER hMetaData, + const AAC_METADATA* const pMetadata) { + FDK_METADATA_ERROR err = METADATA_OK; - hMetaData->nExtensions = 0; - hMetaData->matrix_mixdown_idx = -1; + if ((hMetaData == NULL) || (pMetadata == NULL)) { + err = METADATA_INVALID_HANDLE; + goto bail; + } - /* AAC-DRC */ - if (pMetadata->metadataMode != 0) - { - hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcInfoPayload; - hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE; - hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; - - hMetaData->exPayload[hMetaData->nExtensions].dataSize = - WriteDynamicRangeInfoPayload(pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); + hMetaData->nExtensions = 0; + hMetaData->matrix_mixdown_idx = -1; - hMetaData->nExtensions++; - - /* Matrix Mixdown Coefficient in PCE */ - if (pMetadata->WritePCEMixDwnIdx) { - hMetaData->matrix_mixdown_idx = surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel]; - } + if (pMetadata->metadataMode != 0) { + /* AAC-DRC */ + if ((pMetadata->metadataMode == 1) || (pMetadata->metadataMode == 2)) { + hMetaData->exPayload[hMetaData->nExtensions].pData = + hMetaData->drcInfoPayload; + hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DYNAMIC_RANGE; + hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; + + hMetaData->exPayload[hMetaData->nExtensions].dataSize = + WriteDynamicRangeInfoPayload( + pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); + + hMetaData->nExtensions++; + } /* pMetadata->metadataMode==1 || pMetadata->metadataMode==2 */ + + /* Matrix Mixdown Coefficient in PCE */ + if (pMetadata->WritePCEMixDwnIdx) { + hMetaData->matrix_mixdown_idx = + surmix2matrix_mixdown_idx[pMetadata->surroundMixLevel]; + } - /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */ - if (pMetadata->metadataMode == 2) /* MP4_METADATA_MPEG_ETSI */ - { - hMetaData->exPayload[hMetaData->nExtensions].pData = hMetaData->drcDsePayload; - hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT; - hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; + /* ETSI TS 101 154 (DVB) - MPEG4 ancillary_data() */ + if ((pMetadata->metadataMode == 2) || + (pMetadata->metadataMode == 3)) /* MP4_METADATA_MPEG_ETSI */ + { + hMetaData->exPayload[hMetaData->nExtensions].pData = + hMetaData->drcDsePayload; + hMetaData->exPayload[hMetaData->nExtensions].dataType = EXT_DATA_ELEMENT; + hMetaData->exPayload[hMetaData->nExtensions].associatedChElement = -1; - hMetaData->exPayload[hMetaData->nExtensions].dataSize = - WriteEtsiAncillaryDataPayload(pMetadata,hMetaData->exPayload[hMetaData->nExtensions].pData); + hMetaData->exPayload[hMetaData->nExtensions].dataSize = + WriteEtsiAncillaryDataPayload( + pMetadata, hMetaData->exPayload[hMetaData->nExtensions].pData); - hMetaData->nExtensions++; - } /* metadataMode == 2 */ + hMetaData->nExtensions++; + } /* metadataMode==2 || metadataMode==3 */ - } /* metadataMode != 0 */ + } /* metadataMode != 0 */ bail: - return err; + return err; } -static INT WriteDynamicRangeInfoPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ) -{ - const INT pce_tag_present = 0; /* yet fixed setting! */ - const INT prog_ref_lev_res_bits = 0; - INT i, drc_num_bands = 1; - - FDK_BITSTREAM bsWriter; - FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); - - /* dynamic_range_info() */ - FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */ - if (pce_tag_present) { - FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */ - FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */ - } - - /* Exclude channels */ - FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, 1); /* excluded_chns_present*/ - - /* Multiband DRC */ - FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, 1); /* drc_bands_present */ - if (pMetadata->mpegDrc.drc_bands_present) - { - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, 4); /* drc_band_incr */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, 4); /* drc_interpolation_scheme */ - drc_num_bands += pMetadata->mpegDrc.drc_band_incr; - for (i=0; i<drc_num_bands; i++) { - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], 8); /* drc_band_top */ - } - } - - /* Program Reference Level */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, 1); /* prog_ref_level_present */ - if (pMetadata->mpegDrc.prog_ref_level_present) - { - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, 7); /* prog_ref_level */ - FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, 1); /* prog_ref_level_reserved_bits */ - } - - /* DRC Values */ - for (i=0; i<drc_num_bands; i++) { - FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, 1); /* dyn_rng_sgn[ */ - FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], 7); /* dyn_rng_ctl */ +static INT WriteDynamicRangeInfoPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload) { + const INT pce_tag_present = 0; /* yet fixed setting! */ + const INT prog_ref_lev_res_bits = 0; + INT i, drc_num_bands = 1; + + FDK_BITSTREAM bsWriter; + FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); + + /* dynamic_range_info() */ + FDKwriteBits(&bsWriter, pce_tag_present, 1); /* pce_tag_present */ + if (pce_tag_present) { + FDKwriteBits(&bsWriter, 0x0, 4); /* pce_instance_tag */ + FDKwriteBits(&bsWriter, 0x0, 4); /* drc_tag_reserved_bits */ + } + + /* Exclude channels */ + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.excluded_chns_present) ? 1 : 0, + 1); /* excluded_chns_present*/ + + /* Multiband DRC */ + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.drc_bands_present) ? 1 : 0, + 1); /* drc_bands_present */ + if (pMetadata->mpegDrc.drc_bands_present) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_incr, + 4); /* drc_band_incr */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_interpolation_scheme, + 4); /* drc_interpolation_scheme */ + drc_num_bands += pMetadata->mpegDrc.drc_band_incr; + for (i = 0; i < drc_num_bands; i++) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.drc_band_top[i], + 8); /* drc_band_top */ } - - /* return number of valid bits in extension payload. */ - return FDKgetValidBits(&bsWriter); + } + + /* Program Reference Level */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level_present, + 1); /* prog_ref_level_present */ + if (pMetadata->mpegDrc.prog_ref_level_present) { + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.prog_ref_level, + 7); /* prog_ref_level */ + FDKwriteBits(&bsWriter, prog_ref_lev_res_bits, + 1); /* prog_ref_level_reserved_bits */ + } + + /* DRC Values */ + for (i = 0; i < drc_num_bands; i++) { + FDKwriteBits(&bsWriter, (pMetadata->mpegDrc.dyn_rng_sgn[i]) ? 1 : 0, + 1); /* dyn_rng_sgn[ */ + FDKwriteBits(&bsWriter, pMetadata->mpegDrc.dyn_rng_ctl[i], + 7); /* dyn_rng_ctl */ + } + + /* return number of valid bits in extension payload. */ + return FDKgetValidBits(&bsWriter); } -static INT WriteEtsiAncillaryDataPayload( - const AAC_METADATA* const pMetadata, - UCHAR* const pExtensionPayload - ) -{ - FDK_BITSTREAM bsWriter; - FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); - - /* ancillary_data_sync */ - FDKwriteBits(&bsWriter, 0xBC, 8); - - /* bs_info */ - FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */ - FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, 2); /* dolby_surround_mode */ - FDKwriteBits(&bsWriter, 0x0, 4); /* reserved */ - - /* ancillary_data_status */ - FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */ - FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, 1); /* downmixing_levels_MPEG4_status */ - FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, 1); /* audio_coding_mode_and_compression status */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, 1); /* coarse_grain_timecode_status */ - FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, 1); /* fine_grain_timecode_status */ - - /* downmixing_levels_MPEG4_status */ - if (pMetadata->DmxLvl_On) { - FDKwriteBits(&bsWriter, encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), 8); - } - - /* audio_coding_mode_and_compression_status */ - if (pMetadata->etsiAncData.compression_on) { - FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */ - FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, 8); /* compression value */ +static INT WriteEtsiAncillaryDataPayload(const AAC_METADATA* const pMetadata, + UCHAR* const pExtensionPayload) { + FDK_BITSTREAM bsWriter; + FDKinitBitStream(&bsWriter, pExtensionPayload, 16, 0, BS_WRITER); + + /* ancillary_data_sync */ + FDKwriteBits(&bsWriter, 0xBC, 8); + + /* bs_info */ + FDKwriteBits(&bsWriter, 0x3, 2); /* mpeg_audio_type */ + FDKwriteBits(&bsWriter, pMetadata->dolbySurroundMode, + 2); /* dolby_surround_mode */ + FDKwriteBits(&bsWriter, pMetadata->drcPresentationMode, + 2); /* DRC presentation mode */ + FDKwriteBits(&bsWriter, 0x0, 1); /* stereo_downmix_mode */ + FDKwriteBits(&bsWriter, 0x0, 1); /* reserved */ + + /* ancillary_data_status */ + FDKwriteBits(&bsWriter, 0, 3); /* 3 bit Reserved, set to "0" */ + FDKwriteBits(&bsWriter, (pMetadata->DmxLvl_On) ? 1 : 0, + 1); /* downmixing_levels_MPEG4_status */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncDataStatus, + 1); /* ext_anc_data_status */ + FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.compression_on) ? 1 : 0, + 1); /* audio_coding_mode_and_compression status */ + FDKwriteBits(&bsWriter, + (pMetadata->etsiAncData.timecode_coarse_status) ? 1 : 0, + 1); /* coarse_grain_timecode_status */ + FDKwriteBits(&bsWriter, (pMetadata->etsiAncData.timecode_fine_status) ? 1 : 0, + 1); /* fine_grain_timecode_status */ + + /* downmixing_levels_MPEG4_status */ + if (pMetadata->DmxLvl_On) { + FDKwriteBits( + &bsWriter, + encodeDmxLvls(pMetadata->centerMixLevel, pMetadata->surroundMixLevel), + 8); + } + + /* audio_coding_mode_and_compression_status */ + if (pMetadata->etsiAncData.compression_on) { + FDKwriteBits(&bsWriter, 0x01, 8); /* audio coding mode */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.compression_value, + 8); /* compression value */ + } + + /* grain-timecode coarse/fine */ + if (pMetadata->etsiAncData.timecode_coarse_status) { + FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + } + + if (pMetadata->etsiAncData.timecode_fine_status) { + FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + } + + /* extended ancillary data structure */ + if (pMetadata->etsiAncData.extAncDataStatus) { + /* ext_ancillary_data_status */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status, + 1); /* ext_downmixing_levels_status */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_downmix_gain_status, + 1); /* ext_downmixing_global_gains_status */ + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status, + 1); /* ext_downmixing_lfe_level_status" */ + FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */ + + /* ext_downmixing_levels */ + if (pMetadata->etsiAncData.extAncData.ext_downmix_lvl_status) { + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_a_idx, + 3); /* dmix_a_idx */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.ext_dmix_b_idx, + 3); /* dmix_b_idx */ + FDKwriteBits(&bsWriter, 0, 2); /* Reserved, set to "0" */ } - /* grain-timecode coarse/fine */ - if (pMetadata->etsiAncData.timecode_coarse_status) { - FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + /* ext_downmixing_gains */ + if (pMetadata->etsiAncData.extAncData.ext_downmix_gain_status) { + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_sgn, + 1); /* dmx_gain_5_sign */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_5_idx, + 6); /* dmx_gain_5_idx */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_sgn, + 1); /* dmx_gain_2_sign */ + FDKwriteBits(&bsWriter, pMetadata->etsiAncData.extAncData.dmx_gain_2_idx, + 6); /* dmx_gain_2_idx */ + FDKwriteBits(&bsWriter, 0, 1); /* Reserved, set to "0" */ } - if (pMetadata->etsiAncData.timecode_fine_status) { - FDKwriteBits(&bsWriter, 0x0, 16); /* not yet supported */ + if (pMetadata->etsiAncData.extAncData.ext_lfe_downmix_status) { + FDKwriteBits(&bsWriter, + pMetadata->etsiAncData.extAncData.ext_dmix_lfe_idx, + 4); /* dmix_lfe_idx */ + FDKwriteBits(&bsWriter, 0, 4); /* Reserved, set to "0" */ } + } - return FDKgetValidBits(&bsWriter); + return FDKgetValidBits(&bsWriter); } - static FDK_METADATA_ERROR LoadSubmittedMetadata( - const AACENC_MetaData * const hMetadata, - const INT nChannels, - const INT metadataMode, - AAC_METADATA * const pAacMetaData - ) -{ - FDK_METADATA_ERROR err = METADATA_OK; - - if (pAacMetaData==NULL) { - err = METADATA_INVALID_HANDLE; - } - else { - /* init struct */ - FDKmemclear(pAacMetaData, sizeof(AAC_METADATA)); - - if (hMetadata!=NULL) { - /* convert data */ - pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile; - pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile; - pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel; - pAacMetaData->etsiAncData.comp_TargetRefLevel= hMetadata->comp_TargetRefLevel; - pAacMetaData->mpegDrc.prog_ref_level_present = hMetadata->prog_ref_level_present; - pAacMetaData->mpegDrc.prog_ref_level = dialnorm2progreflvl(hMetadata->prog_ref_level); - - pAacMetaData->centerMixLevel = hMetadata->centerMixLevel; - pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel; - pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present; - pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present; + const AACENC_MetaData* const hMetadata, const INT nChannels, + const INT metadataMode, AAC_METADATA* const pAacMetaData) { + FDK_METADATA_ERROR err = METADATA_OK; + + if (pAacMetaData == NULL) { + err = METADATA_INVALID_HANDLE; + } else { + /* init struct */ + FDKmemclear(pAacMetaData, sizeof(AAC_METADATA)); + + if (hMetadata != NULL) { + /* convert data */ + pAacMetaData->mpegDrc.drc_profile = hMetadata->drc_profile; + pAacMetaData->etsiAncData.comp_profile = hMetadata->comp_profile; + pAacMetaData->mpegDrc.drc_TargetRefLevel = hMetadata->drc_TargetRefLevel; + pAacMetaData->etsiAncData.comp_TargetRefLevel = + hMetadata->comp_TargetRefLevel; + pAacMetaData->mpegDrc.prog_ref_level_present = + hMetadata->prog_ref_level_present; + pAacMetaData->mpegDrc.prog_ref_level = + dialnorm2progreflvl(hMetadata->prog_ref_level); + + pAacMetaData->centerMixLevel = hMetadata->centerMixLevel; + pAacMetaData->surroundMixLevel = hMetadata->surroundMixLevel; + pAacMetaData->WritePCEMixDwnIdx = hMetadata->PCE_mixdown_idx_present; + pAacMetaData->DmxLvl_On = hMetadata->ETSI_DmxLvl_present; + + pAacMetaData->etsiAncData.compression_on = + (hMetadata->comp_profile == AACENC_METADATA_DRC_NOT_PRESENT ? 0 : 1); + + if (pAacMetaData->mpegDrc.drc_profile == + AACENC_METADATA_DRC_NOT_PRESENT) { + pAacMetaData->mpegDrc.drc_profile = + AACENC_METADATA_DRC_NONE; /* MPEG DRC gains are + always present in BS + syntax */ + /* we should give a warning, but ErrorHandler does not support this */ + } - pAacMetaData->etsiAncData.compression_on = 1; + if (nChannels == 2) { + pAacMetaData->dolbySurroundMode = + hMetadata->dolbySurroundMode; /* dolby_surround_mode */ + } else { + pAacMetaData->dolbySurroundMode = 0; + } + pAacMetaData->drcPresentationMode = hMetadata->drcPresentationMode; + /* override external values if DVB DRC presentation mode is given */ + if (pAacMetaData->drcPresentationMode == 1) { + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(-(31 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel); + pAacMetaData->etsiAncData.comp_TargetRefLevel = fMax( + -(20 << 16), + pAacMetaData->etsiAncData.comp_TargetRefLevel); /* implies -23dB */ + } + if (pAacMetaData->drcPresentationMode == 2) { + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(-(23 << 16), pAacMetaData->mpegDrc.drc_TargetRefLevel); + pAacMetaData->etsiAncData.comp_TargetRefLevel = + fMax(-(23 << 16), pAacMetaData->etsiAncData.comp_TargetRefLevel); + } + if (pAacMetaData->etsiAncData.comp_profile == + AACENC_METADATA_DRC_NOT_PRESENT) { + /* DVB defines to revert to Light DRC if heavy is not present */ + if (pAacMetaData->drcPresentationMode != 0) { + /* we exclude the "not indicated" mode as this requires the user to + * define desired levels anyway */ + pAacMetaData->mpegDrc.drc_TargetRefLevel = + fMax(pAacMetaData->etsiAncData.comp_TargetRefLevel, + pAacMetaData->mpegDrc.drc_TargetRefLevel); + } + } - if (nChannels == 2) { - pAacMetaData->dolbySurroundMode = hMetadata->dolbySurroundMode; /* dolby_surround_mode */ + pAacMetaData->etsiAncData.timecode_coarse_status = + 0; /* not yet supported - attention: Update + GetEstMetadataBytesPerFrame() if enable this! */ + pAacMetaData->etsiAncData.timecode_fine_status = + 0; /* not yet supported - attention: Update + GetEstMetadataBytesPerFrame() if enable this! */ + + /* extended ancillary data */ + pAacMetaData->etsiAncData.extAncDataStatus = + ((hMetadata->ExtMetaData.extAncDataEnable == 1) ? 1 : 0); + + if (pAacMetaData->etsiAncData.extAncDataStatus) { + pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = + (hMetadata->ExtMetaData.extDownmixLevelEnable ? 1 : 0); + pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = + (hMetadata->ExtMetaData.dmxGainEnable ? 1 : 0); + pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = + (hMetadata->ExtMetaData.lfeDmxEnable ? 1 : 0); + + pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = + hMetadata->ExtMetaData.extDownmixLevel_A; + pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = + hMetadata->ExtMetaData.extDownmixLevel_B; + + if (pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status) { + encodeDynrng(hMetadata->ExtMetaData.dmxGain5, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(hMetadata->ExtMetaData.dmxGain2, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); } else { - pAacMetaData->dolbySurroundMode = 0; + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); } - pAacMetaData->etsiAncData.timecode_coarse_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */ - pAacMetaData->etsiAncData.timecode_fine_status = 0; /* not yet supported - attention: Update GetEstMetadataBytesPerFrame() if enable this! */ - - pAacMetaData->metadataMode = metadataMode; - } - else { - pAacMetaData->metadataMode = 0; /* there is no configuration available */ + if (pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status) { + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + hMetadata->ExtMetaData.lfeDmxLevel; + } else { + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + 15; /* -inf dB */ + } + } else { + pAacMetaData->etsiAncData.extAncData.ext_downmix_lvl_status = 0; + pAacMetaData->etsiAncData.extAncData.ext_downmix_gain_status = 0; + pAacMetaData->etsiAncData.extAncData.ext_lfe_downmix_status = 0; + + pAacMetaData->etsiAncData.extAncData.ext_dmix_a_idx = 7; /* -inf dB */ + pAacMetaData->etsiAncData.extAncData.ext_dmix_b_idx = 7; /* -inf dB */ + + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_5_sgn)); + encodeDynrng(1 << 16, + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_idx), + &(pAacMetaData->etsiAncData.extAncData.dmx_gain_2_sgn)); + + pAacMetaData->etsiAncData.extAncData.ext_dmix_lfe_idx = + 15; /* -inf dB */ } + + pAacMetaData->metadataMode = metadataMode; + } else { + pAacMetaData->metadataMode = 0; /* there is no configuration available */ } + } - return err; + return err; } -INT FDK_MetadataEnc_GetDelay( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc - ) -{ - INT delay = 0; +INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc) { + INT delay = 0; - if (hMetadataEnc!=NULL) { - delay = hMetadataEnc->nAudioDataDelay; - } + if (hMetadataEnc != NULL) { + delay = hMetadataEnc->nAudioDataDelay; + } - return delay; + return delay; } - - diff --git a/libAACenc/src/metadata_main.h b/libAACenc/src/metadata_main.h index bfc8ae1..d872c77 100644 --- a/libAACenc/src/metadata_main.h +++ b/libAACenc/src/metadata_main.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,34 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/********************** Fraunhofer IIS FDK AAC Encoder lib ****************** +/**************************** AAC encoder library ****************************** - Author(s): V. Bacigalupo - Description: Metadata Encoder library interface functions + Author(s): V. Bacigalupo -******************************************************************************/ + Description: Metadata Encoder library interface functions -#ifndef _METADATA_MAIN_H -#define _METADATA_MAIN_H +*******************************************************************************/ +#ifndef METADATA_MAIN_H +#define METADATA_MAIN_H /* Includes ******************************************************************/ #include "aacenc_lib.h" #include "aacenc.h" - /* Defines *******************************************************************/ /* Data Types ****************************************************************/ typedef enum { - METADATA_OK = 0x0000, /*!< No error happened. All fine. */ - METADATA_INVALID_HANDLE = 0x0020, /*!< Handle passed to function call was invalid. */ - METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ - METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */ - METADATA_ENCODE_ERROR = 0x0060 /*!< The encoding process was interrupted by an unexpected error. */ + METADATA_OK = 0x0000, /*!< No error happened. All fine. */ + METADATA_INVALID_HANDLE = + 0x0020, /*!< Handle passed to function call was invalid. */ + METADATA_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + METADATA_INIT_ERROR = 0x0040, /*!< General initialization error. */ + METADATA_ENCODE_ERROR = + 0x0060 /*!< The encoding process was interrupted by an unexpected error. + */ } FDK_METADATA_ERROR; @@ -115,32 +128,33 @@ typedef enum { */ typedef struct FDK_METADATA_ENCODER *HANDLE_FDK_METADATA_ENCODER; - /** * \brief Open a Meta Data instance. * - * \param phMetadataEnc A pointer to a Meta Data handle to be allocated. Initialized on return. + * \param phMetadataEnc A pointer to a Meta Data handle to be allocated. + * Initialized on return. + * \param maxChannels Maximum number of supported audio channels. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, METADATA_MEMORY_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Open( - HANDLE_FDK_METADATA_ENCODER *phMetadataEnc - ); - + HANDLE_FDK_METADATA_ENCODER *phMetadataEnc, const UINT maxChannels); /** * \brief Initialize a Meta Data instance. * * \param hMetadataEnc Meta Data handle. * \param resetStates Indication for full reset of all states. - * \param metadataMode Configures metat data output format (0,1,2). + * \param metadataMode Configures meta data output format (0,1,2,3). * \param audioDelay Delay cause by the audio encoder. - * \param frameLength Number of samples to be processes within one frame. + * \param frameLength Number of samples to be processes within one + * frame. * \param sampleRate Sampling rat in Hz of audio input signal. * \param nChannels Number of audio input channels. - * \param channelMode Channel configuration which is used by the encoder. + * \param channelMode Channel configuration which is used by the + * encoder. * \param channelOrder Channel order of the input data. (WAV, MPEG) * * \return @@ -148,17 +162,10 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Open( * - METADATA_INVALID_HANDLE, METADATA_INIT_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Init( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc, - const INT resetStates, - const INT metadataMode, - const INT audioDelay, - const UINT frameLength, - const UINT sampleRate, - const UINT nChannels, - const CHANNEL_MODE channelMode, - const CHANNEL_ORDER channelOrder - ); - + HANDLE_FDK_METADATA_ENCODER hMetadataEnc, const INT resetStates, + const INT metadataMode, const INT audioDelay, const UINT frameLength, + const UINT sampleRate, const UINT nChannels, const CHANNEL_MODE channelMode, + const CHANNEL_ORDER channelOrder); /** * \brief Calculate Meta Data processing. @@ -170,43 +177,42 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Init( * - Apply audio data and meta data delay compensation. * * \param hMetadataEnc Meta Data handle. - * \param pAudioSamples Pointer to audio input data. Existing function overwrites audio data with delayed audio samples. + * \param pAudioSamples Pointer to audio input data. Existing function + * overwrites audio data with delayed audio samples. * \param nAudioSamples Number of input audio samples to be prcessed. * \param pMetadata Pointer to Metat Data input. - * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on return. - * \param nMetaDataExtensions Pointer to variable to describe number of available extension payloads. Filled on return. - * \param matrix_mixdown_idx Pointer to variable for matrix mixdown coefficient. Filled on return. + * \param ppMetaDataExtPayload Pointer to extension payload array. Filled on + * return. + * \param nMetaDataExtensions Pointer to variable to describe number of + * available extension payloads. Filled on return. + * \param matrix_mixdown_idx Pointer to variable for matrix mixdown + * coefficient. Filled on return. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, METADATA_ENCODE_ERROR, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Process( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc, - INT_PCM * const pAudioSamples, - const INT nAudioSamples, - const AACENC_MetaData * const pMetadata, - AACENC_EXT_PAYLOAD ** ppMetaDataExtPayload, - UINT * nMetaDataExtensions, - INT * matrix_mixdown_idx - ); - + HANDLE_FDK_METADATA_ENCODER hMetadataEnc, INT_PCM *const pAudioSamples, + const UINT audioSamplesBufSize, const INT nAudioSamples, + const AACENC_MetaData *const pMetadata, + AACENC_EXT_PAYLOAD **ppMetaDataExtPayload, UINT *nMetaDataExtensions, + INT *matrix_mixdown_idx); /** * \brief Close the Meta Data instance. * * Deallocate instance and free whole memory. * - * \param phMetaData Pointer to the Meta Data handle to be deallocated. + * \param phMetaData Pointer to the Meta Data handle to be + * deallocated. * * \return * - METADATA_OK, on succes. * - METADATA_INVALID_HANDLE, on failure. */ FDK_METADATA_ERROR FDK_MetadataEnc_Close( - HANDLE_FDK_METADATA_ENCODER *phMetaData - ); - + HANDLE_FDK_METADATA_ENCODER *phMetaData); /** * \brief Get Meta Data Encoder delay. @@ -215,10 +221,6 @@ FDK_METADATA_ERROR FDK_MetadataEnc_Close( * * \return Delay caused by Meta Data module. */ -INT FDK_MetadataEnc_GetDelay( - HANDLE_FDK_METADATA_ENCODER hMetadataEnc - ); - - -#endif /* _METADATA_MAIN_H */ +INT FDK_MetadataEnc_GetDelay(HANDLE_FDK_METADATA_ENCODER hMetadataEnc); +#endif /* METADATA_MAIN_H */ diff --git a/libAACenc/src/mps_main.cpp b/libAACenc/src/mps_main.cpp new file mode 100644 index 0000000..1048228 --- /dev/null +++ b/libAACenc/src/mps_main.cpp @@ -0,0 +1,529 @@ +/* ----------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. + +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): Markus Lohwasser + + Description: Mpeg Surround library interface functions + +*******************************************************************************/ + +/* Includes ******************************************************************/ +#include "mps_main.h" +#include "sacenc_lib.h" + +/* Data Types ****************************************************************/ +struct MPS_ENCODER { + HANDLE_MP4SPACE_ENCODER hSacEncoder; + + AUDIO_OBJECT_TYPE audioObjectType; + + FDK_bufDescr inBufDesc; + FDK_bufDescr outBufDesc; + SACENC_InArgs inargs; + SACENC_OutArgs outargs; + + void *pInBuffer[1]; + UINT pInBufferSize[1]; + UINT pInBufferElSize[1]; + UINT pInBufferType[1]; + + void *pOutBuffer[2]; + UINT pOutBufferSize[2]; + UINT pOutBufferElSize[2]; + UINT pOutBufferType[2]; + + UCHAR sacOutBuffer[1024]; /* Worst case memory consumption for ELDv2: 768 + bytes => 6144 bits (Core + SBR + MPS) */ +}; + +struct MPS_CONFIG_TAB { + AUDIO_OBJECT_TYPE audio_object_type; + CHANNEL_MODE channel_mode; + ULONG sbr_ratio; + ULONG sampling_rate; + ULONG bitrate_min; + ULONG bitrate_max; +}; + +/* Constants *****************************************************************/ +static const MPS_CONFIG_TAB mpsConfigTab[] = { + {AOT_ER_AAC_ELD, MODE_212, 0, 16000, 16000, 39999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 22050, 16000, 49999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 24000, 16000, 61999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 32000, 20000, 84999}, + {AOT_ER_AAC_ELD, MODE_212, 0, 44100, 50000, 192000}, + {AOT_ER_AAC_ELD, MODE_212, 0, 48000, 62000, 192000}, + + {AOT_ER_AAC_ELD, MODE_212, 1, 16000, 18000, 31999}, + {AOT_ER_AAC_ELD, MODE_212, 1, 22050, 18000, 31999}, + {AOT_ER_AAC_ELD, MODE_212, 1, 24000, 20000, 64000}, + + {AOT_ER_AAC_ELD, MODE_212, 2, 32000, 18000, 64000}, + {AOT_ER_AAC_ELD, MODE_212, 2, 44100, 21000, 64000}, + {AOT_ER_AAC_ELD, MODE_212, 2, 48000, 26000, 64000} + +}; + +/* Function / Class Declarations *********************************************/ + +/* Function / Class Definition ***********************************************/ +static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc, + UCHAR *const pOutputBuffer, + const int outputBufferSize); + +MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + HANDLE_MPS_ENCODER hMpsEnc = NULL; + + if (phMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + if (NULL == + (hMpsEnc = (HANDLE_MPS_ENCODER)FDKcalloc(1, sizeof(MPS_ENCODER)))) { + error = MPS_ENCODER_MEMORY_ERROR; + goto bail; + } + FDKmemclear(hMpsEnc, sizeof(MPS_ENCODER)); + + if (SACENC_OK != FDK_sacenc_open(&hMpsEnc->hSacEncoder)) { + error = MPS_ENCODER_MEMORY_ERROR; + goto bail; + } + + /* Return mps encoder instance */ + *phMpsEnc = hMpsEnc; + +bail: + if (error != MPS_ENCODER_OK) { + FDK_MpegsEnc_Close(&hMpsEnc); + } + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (phMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + if (*phMpsEnc != NULL) { + FDK_sacenc_close(&(*phMpsEnc)->hSacEncoder); + FDKfree(*phMpsEnc); + *phMpsEnc = NULL; + } +bail: + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc, + const AUDIO_OBJECT_TYPE audioObjectType, + const UINT samplingrate, const UINT bitrate, + const UINT sbrRatio, const UINT framelength, + const UINT inputBufferSizePerChannel, + const UINT coreCoderDelay) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + const UINT fs_low = 27713; /* low MPS sampling frequencies */ + const UINT fs_high = 55426; /* high MPS sampling frequencies */ + UINT nTimeSlots = 0, nQmfBandsLd = 0; + + if (hMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + goto bail; + } + + /* Combine MPS with SBR only if the number of QMF band fits together.*/ + switch (sbrRatio) { + case 1: /* downsampled sbr - 32 QMF bands required */ + if (!(samplingrate < fs_low)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + case 2: /* dualrate - 64 QMF bands required */ + if (!((samplingrate >= fs_low) && (samplingrate < fs_high))) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + case 0: + default:; /* time interface - no samplingrate restriction */ + } + + /* 32 QMF-Bands ( fs < 27713 ) + * 64 QMF-Bands ( 27713 >= fs <= 55426 ) + * 128 QMF-Bands ( fs > 55426 ) + */ + nQmfBandsLd = + (samplingrate < fs_low) ? 5 : ((samplingrate > fs_high) ? 7 : 6); + nTimeSlots = framelength >> nQmfBandsLd; + + /* check if number of qmf bands is usable for given framelength */ + if (framelength != (nTimeSlots << nQmfBandsLd)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + /* is given bitrate intended to be supported */ + if ((INT)bitrate != FDK_MpegsEnc_GetClosestBitRate(audioObjectType, MODE_212, + samplingrate, sbrRatio, + bitrate)) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + /* init SAC library */ + switch (audioObjectType) { + case AOT_ER_AAC_ELD: { + const UINT noInterFrameCoding = 0; + + if ((SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_LOWDELAY, + (noInterFrameCoding == 1) ? 1 : 2)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_ENC_MODE, SACENC_212)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_SAMPLERATE, samplingrate)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_FRAME_TIME_SLOTS, + nTimeSlots)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_PARAM_BANDS, + SACENC_BANDS_15)) || + (SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_TIME_DOM_DMX, 2)) || + (SACENC_OK != + FDK_sacenc_setParam(hMpsEnc->hSacEncoder, SACENC_COARSE_QUANT, 0)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_QUANT_MODE, + SACENC_QUANTMODE_FINE)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_TIME_ALIGNMENT, 0)) || + (SACENC_OK != FDK_sacenc_setParam(hMpsEnc->hSacEncoder, + SACENC_INDEPENDENCY_FACTOR, 20))) { + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + break; + } + default: + error = MPS_ENCODER_INIT_ERROR; + goto bail; + } + + if (SACENC_OK != FDK_sacenc_init(hMpsEnc->hSacEncoder, coreCoderDelay)) { + error = MPS_ENCODER_INIT_ERROR; + } + + hMpsEnc->audioObjectType = audioObjectType; + + hMpsEnc->inBufDesc.ppBase = (void **)&hMpsEnc->pInBuffer; + hMpsEnc->inBufDesc.pBufSize = hMpsEnc->pInBufferSize; + hMpsEnc->inBufDesc.pEleSize = hMpsEnc->pInBufferElSize; + hMpsEnc->inBufDesc.pBufType = hMpsEnc->pInBufferType; + hMpsEnc->inBufDesc.numBufs = 1; + + hMpsEnc->outBufDesc.ppBase = (void **)&hMpsEnc->pOutBuffer; + hMpsEnc->outBufDesc.pBufSize = hMpsEnc->pOutBufferSize; + hMpsEnc->outBufDesc.pEleSize = hMpsEnc->pOutBufferElSize; + hMpsEnc->outBufDesc.pBufType = hMpsEnc->pOutBufferType; + hMpsEnc->outBufDesc.numBufs = 2; + + hMpsEnc->pInBuffer[0] = NULL; + hMpsEnc->pInBufferSize[0] = 0; + hMpsEnc->pInBufferElSize[0] = sizeof(INT_PCM); + hMpsEnc->pInBufferType[0] = (FDK_BUF_TYPE_INPUT | FDK_BUF_TYPE_PCM_DATA); + + hMpsEnc->pOutBuffer[0] = NULL; + hMpsEnc->pOutBufferSize[0] = 0; + hMpsEnc->pOutBufferElSize[0] = sizeof(INT_PCM); + hMpsEnc->pOutBufferType[0] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_PCM_DATA); + + hMpsEnc->pOutBuffer[1] = NULL; + hMpsEnc->pOutBufferSize[1] = 0; + hMpsEnc->pOutBufferElSize[1] = sizeof(UCHAR); + hMpsEnc->pOutBufferType[1] = (FDK_BUF_TYPE_OUTPUT | FDK_BUF_TYPE_BS_DATA); + + hMpsEnc->inargs.isInputInterleaved = 0; + hMpsEnc->inargs.inputBufferSizePerChannel = inputBufferSizePerChannel; + +bail: + return error; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc, + INT_PCM *const pAudioSamples, + const INT nAudioSamples, + AACENC_EXT_PAYLOAD *pMpsExtPayload) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (hMpsEnc == NULL) { + error = MPS_ENCODER_INVALID_HANDLE; + } else { + int sacHeaderFlag = 1; + int sacOutBufferOffset = 0; + + /* In case of eld the ssc is explicit and doesn't need to be inband */ + if (hMpsEnc->audioObjectType == AOT_ER_AAC_ELD) { + sacHeaderFlag = 0; + } + + /* 4 bits nibble after extension type */ + hMpsEnc->sacOutBuffer[0] = (sacHeaderFlag == 0) ? 0x3 : 0x7; + sacOutBufferOffset += 1; + + if (sacHeaderFlag) { + sacOutBufferOffset += FDK_MpegsEnc_WriteFrameHeader( + hMpsEnc, &hMpsEnc->sacOutBuffer[sacOutBufferOffset], + sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset); + } + + /* Register input and output buffer. */ + hMpsEnc->pInBuffer[0] = (void *)pAudioSamples; + hMpsEnc->inargs.nInputSamples = nAudioSamples; + + hMpsEnc->pOutBuffer[0] = (void *)pAudioSamples; + hMpsEnc->pOutBufferSize[0] = sizeof(INT_PCM) * nAudioSamples / 2; + + hMpsEnc->pOutBuffer[1] = (void *)&hMpsEnc->sacOutBuffer[sacOutBufferOffset]; + hMpsEnc->pOutBufferSize[1] = + sizeof(hMpsEnc->sacOutBuffer) - sacOutBufferOffset; + + /* encode SAC frame */ + if (SACENC_OK != FDK_sacenc_encode(hMpsEnc->hSacEncoder, + &hMpsEnc->inBufDesc, + &hMpsEnc->outBufDesc, &hMpsEnc->inargs, + &hMpsEnc->outargs)) { + error = MPS_ENCODER_ENCODE_ERROR; + goto bail; + } + + /* export MPS payload */ + pMpsExtPayload->pData = (UCHAR *)hMpsEnc->sacOutBuffer; + pMpsExtPayload->dataSize = + hMpsEnc->outargs.nOutputBits + 8 * (sacOutBufferOffset - 1); + pMpsExtPayload->dataType = EXT_LDSAC_DATA; + pMpsExtPayload->associatedChElement = -1; + } + +bail: + return error; +} + +INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc, + HANDLE_FDK_BITSTREAM hBs) { + INT sscBits = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + + if (hBs != NULL) { + int i; + int writtenBits = 0; + for (i = 0; i<mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits>> 3; i++) { + FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], 8); + writtenBits += 8; + } + FDKwriteBits(hBs, mp4SpaceEncoderInfo.pSscBuf->pSsc[i], + mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits - writtenBits); + } /* hBS */ + + sscBits = mp4SpaceEncoderInfo.pSscBuf->nSscSizeBits; + + } /* valid hMpsEnc */ + + return sscBits; +} + +static INT FDK_MpegsEnc_WriteFrameHeader(HANDLE_MPS_ENCODER hMpsEnc, + UCHAR *const pOutputBuffer, + const int outputBufferSize) { + const int sacTimeAlignFlag = 0; + + /* Initialize variables */ + int numBits = 0; + + if ((NULL != hMpsEnc) && (NULL != pOutputBuffer)) { + UINT alignAnchor, cnt; + FDK_BITSTREAM Bs; + FDKinitBitStream(&Bs, pOutputBuffer, outputBufferSize, 0, BS_WRITER); + + /* Calculate SSC length information */ + cnt = (FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, NULL) + 7) >> 3; + + /* Write SSC */ + FDKwriteBits(&Bs, sacTimeAlignFlag, 1); + + if (cnt < 127) { + FDKwriteBits(&Bs, cnt, 7); + } else { + FDKwriteBits(&Bs, 127, 7); + FDKwriteBits(&Bs, cnt - 127, 16); + } + + alignAnchor = FDKgetValidBits(&Bs); + FDK_MpegsEnc_WriteSpatialSpecificConfig(hMpsEnc, &Bs); + FDKbyteAlign(&Bs, alignAnchor); /* bsFillBits */ + + if (sacTimeAlignFlag) { + FDK_ASSERT(1); /* time alignment not supported */ + } + + numBits = FDKgetValidBits(&Bs); + } /* valid handle */ + + return ((numBits + 7) >> 3); +} + +INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType, + const CHANNEL_MODE channelMode, + const UINT samplingrate, const UINT sbrRatio, + const UINT bitrate) { + unsigned int i; + int targetBitrate = -1; + + for (i = 0; i < sizeof(mpsConfigTab) / sizeof(MPS_CONFIG_TAB); i++) { + if ((mpsConfigTab[i].audio_object_type == audioObjectType) && + (mpsConfigTab[i].channel_mode == channelMode) && + (mpsConfigTab[i].sbr_ratio == sbrRatio) && + (mpsConfigTab[i].sampling_rate == samplingrate)) { + targetBitrate = fMin(fMax(bitrate, mpsConfigTab[i].bitrate_min), + mpsConfigTab[i].bitrate_max); + } + } + + return targetBitrate; +} + +INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc) { + INT delay = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + delay = mp4SpaceEncoderInfo.nCodecDelay; + } + + return delay; +} + +INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc) { + INT delay = 0; + + if (NULL != hMpsEnc) { + MP4SPACEENC_INFO mp4SpaceEncoderInfo; + FDK_sacenc_getInfo(hMpsEnc->hSacEncoder, &mp4SpaceEncoderInfo); + delay = mp4SpaceEncoderInfo.nDecoderDelay; + } + + return delay; +} + +MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info) { + MPS_ENCODER_ERROR error = MPS_ENCODER_OK; + + if (NULL == info) { + error = MPS_ENCODER_INVALID_HANDLE; + } else if (SACENC_OK != FDK_sacenc_getLibInfo(info)) { + error = MPS_ENCODER_INIT_ERROR; + } + + return error; +} diff --git a/libAACenc/src/mps_main.h b/libAACenc/src/mps_main.h new file mode 100644 index 0000000..f56678a --- /dev/null +++ b/libAACenc/src/mps_main.h @@ -0,0 +1,270 @@ +/* ----------------------------------------------------------------------------- +Software License for The Fraunhofer FDK AAC Codec Library for Android + +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. + + 1. INTRODUCTION +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. + +2. COPYRIGHT LICENSE + +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: + +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. + +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your +modifications thereto to recipients of copies in binary form. + +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. + +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. + +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." + +3. NO PATENT LICENSE + +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. + +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. + +4. DISCLAIMER + +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. + +5. CONTACT INFORMATION + +Fraunhofer Institute for Integrated Circuits IIS +Attention: Audio and Multimedia Departments - FDK AAC LL +Am Wolfsmantel 33 +91058 Erlangen, Germany + +www.iis.fraunhofer.de/amm +amm-info@iis.fraunhofer.de +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): Markus Lohwasser + + Description: Mpeg Surround library interface functions + +*******************************************************************************/ + +#ifndef MPS_MAIN_H +#define MPS_MAIN_H + +/* Includes ******************************************************************/ +#include "aacenc.h" +#include "FDK_audio.h" +#include "machine_type.h" + +/* Defines *******************************************************************/ +typedef enum { + MPS_ENCODER_OK = 0x0000, /*!< No error happened. All fine. */ + MPS_ENCODER_INVALID_HANDLE = + 0x0020, /*!< Handle passed to function call was invalid. */ + MPS_ENCODER_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ + MPS_ENCODER_INIT_ERROR = 0x0040, /*!< General initialization error. */ + MPS_ENCODER_ENCODE_ERROR = + 0x0060 /*!< The encoding process was interrupted by an unexpected error. + */ + +} MPS_ENCODER_ERROR; + +/* Data Types ****************************************************************/ + +/** + * MPEG Surround Encoder interface handle. + */ +typedef struct MPS_ENCODER MPS_ENCODER, *HANDLE_MPS_ENCODER; + +/* Function / Class Declarations *********************************************/ + +/** + * \brief Open a Mpeg Surround Encoder instance. + * + * \phMpsEnc A pointer to a MPS handle to be allocated. + * Initialized on return. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_MEMORY_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Open(HANDLE_MPS_ENCODER *phMpsEnc); + +/** + * \brief Close the Mpeg Surround Encoder instance. + * + * Deallocate instance and free whole memory. + * + * \param phMpsEnc Pointer to the MPS handle to be deallocated. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Close(HANDLE_MPS_ENCODER *phMpsEnc); + +/** + * \brief Initialize a Mpeg Surround Encoder instance. + * + * \param hMpsEnc MPS Encoder handle. + * \param audioObjectType Audio object type. + * \param samplingrate Sampling rate in Hz of audio input signal. + * \param bitrate Encder target bitrate. + * \param sbrRatio SBR sampling rate ratio. + * \param framelength Number of samples to be processes within one + * frame. + * \param inputBufferSizePerChannel Size of input buffer per channel. + * \param coreCoderDelay Core coder delay. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Init(HANDLE_MPS_ENCODER hMpsEnc, + const AUDIO_OBJECT_TYPE audioObjectType, + const UINT samplingrate, const UINT bitrate, + const UINT sbrRatio, const UINT framelength, + const UINT inputBufferSizePerChannel, + const UINT coreCoderDelay); + +/** + * \brief Calculate Mpeg Surround processing. + * + * This fuction applies the MPS processing. The MPS side info will be written to + * extension payload. The input audio data will be overwritten by the calculated + * downmix. + * + * \param hMpsEnc MPS Encoder handle. + * \param pAudioSamples Pointer to audio input/output data. + * \param nAudioSamples Number of input audio samples to be prcessed. + * \param pMpsExtPayload Pointer to extension payload to be filled on + * return. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_ENCODE_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_Process(HANDLE_MPS_ENCODER hMpsEnc, + INT_PCM *const pAudioSamples, + const INT nAudioSamples, + AACENC_EXT_PAYLOAD *pMpsExtPayload); + +/** + * \brief Write Spatial Specific Config. + * + * This function can be called via call back from the transport library to write + * the Spatial Specific Config to given bitstream buffer. + * + * \param hMpsEnc MPS Encoder handle. + * \param hBs Bitstream buffer handle. + * + * \return Number of written bits. + */ +INT FDK_MpegsEnc_WriteSpatialSpecificConfig(HANDLE_MPS_ENCODER hMpsEnc, + HANDLE_FDK_BITSTREAM hBs); + +/** + * \brief Get closest valid bitrate supported by given config. + * + * \param audioObjectType Audio object type. + * \param channelMode Encoder channel mode. + * \param samplingrate Sampling rate in Hz of audio input signal. + * \param sbrRatio SBR sampling rate ratio. + * \param bitrate The desired target bitrate. + * + * \return Closest valid bitrate to given bitrate.. + */ +INT FDK_MpegsEnc_GetClosestBitRate(const AUDIO_OBJECT_TYPE audioObjectType, + const CHANNEL_MODE channelMode, + const UINT samplingrate, const UINT sbrRatio, + const UINT bitrate); + +/** + * \brief Get codec delay. + * + * This function returns delay of the whole en-/decoded signal, including + * corecoder delay. + * + * \param hMpsEnc MPS Encoder handle. + * + * \return Codec delay in samples. + */ +INT FDK_MpegsEnc_GetDelay(HANDLE_MPS_ENCODER hMpsEnc); + +/** + * \brief Get Mpeg Surround Decoder delay. + * + * This function returns delay of the Mpeg Surround decoder. + * + * \param hMpsEnc MPS Encoder handle. + * + * \return Mpeg Surround Decoder delay in samples. + */ +INT FDK_MpegsEnc_GetDecDelay(HANDLE_MPS_ENCODER hMpsEnc); + +/** + * \brief Get information about encoder library build. + * + * Fill a given LIB_INFO structure with library version information. + * + * \param info Pointer to an allocated LIB_INFO struct. + * + * \return + * - MPS_ENCODER_OK, on succes. + * - MPS_ENCODER_INVALID_HANDLE, MPS_ENCODER_INIT_ERROR, on failure. + */ +MPS_ENCODER_ERROR FDK_MpegsEnc_GetLibInfo(LIB_INFO *info); + +#endif /* MPS_MAIN_H */ diff --git a/libAACenc/src/ms_stereo.cpp b/libAACenc/src/ms_stereo.cpp index 306d490..6a121b2 100644 --- a/libAACenc/src/ms_stereo.cpp +++ b/libAACenc/src/ms_stereo.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,173 +90,206 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** + + Author(s): M.Werner -/******************************** MPEG Audio Encoder ************************** + Description: MS stereo processing - Initial author: M.Werner - contents/description: MS stereo processing +*******************************************************************************/ -******************************************************************************/ #include "ms_stereo.h" #include "psy_const.h" /* static const float scaleMinThres = 1.0f; */ /* 0.75f for 3db boost */ -void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], - PSY_OUT_CHANNEL* psyOutChannel[2], - const INT *isBook, - INT *msDigest, /* output */ - INT *msMask, /* output */ - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset) -{ - FIXP_DBL *sfbEnergyLeft = psyData[0]->sfbEnergy.Long; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyRight = psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */ - const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long; - const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long; - FIXP_DBL *sfbThresholdLeft = psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */ - FIXP_DBL *sfbThresholdRight = psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */ - - FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long; - FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long; - - FIXP_DBL *sfbEnergyLeftLdData = psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyRightLdData = psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData; - FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData; - FIXP_DBL *sfbThresholdLeftLdData = psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */ - FIXP_DBL *sfbThresholdRightLdData = psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */ - - FIXP_DBL *mdctSpectrumLeft = psyData[0]->mdctSpectrum; /* modified where msMask==1 */ - FIXP_DBL *mdctSpectrumRight = psyData[1]->mdctSpectrum; /* modified where msMask==1 */ - - INT sfb,sfboffs, j; /* loop counters */ - FIXP_DBL pnlrLdData, pnmsLdData; - FIXP_DBL minThresholdLdData; - FIXP_DBL minThreshold; - INT useMS; - - INT msMaskTrueSomewhere = 0; /* to determine msDigest */ - INT numMsMaskFalse = 0; /* number of non-intensity bands where L/R coding is used */ - - for(sfb=0; sfb<sfbCnt; sfb+=sfbPerGroup) { - for(sfboffs=0;sfboffs<maxSfbPerGroup;sfboffs++) { - - if ( (isBook==NULL) ? 1 : (isBook[sfb+sfboffs] == 0) ) { - FIXP_DBL tmp; - -/* - minThreshold=min(sfbThresholdLeft[sfb+sfboffs], sfbThresholdRight[sfb+sfboffs])*scaleMinThres; - pnlr = (sfbThresholdLeft[sfb+sfboffs]/ - max(sfbEnergyLeft[sfb+sfboffs],sfbThresholdLeft[sfb+sfboffs]))* - (sfbThresholdRight[sfb+sfboffs]/ - max(sfbEnergyRight[sfb+sfboffs],sfbThresholdRight[sfb+sfboffs])); - pnms = (minThreshold/max(sfbEnergyMid[sfb+sfboffs],minThreshold))* - (minThreshold/max(sfbEnergySide[sfb+sfboffs],minThreshold)); - useMS = (pnms > pnlr); -*/ - - /* we assume that scaleMinThres == 1.0f and we can drop it */ - minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - - /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] - - max(sfbEnergyLeftLdData[sfb+sfboffs], sfbThresholdLeftLdData[sfb+sfboffs]) + - sfbThresholdRightLdData[sfb+sfboffs] - - max(sfbEnergyRightLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); */ - tmp = fixMax(sfbEnergyLeftLdData[sfb+sfboffs], sfbThresholdLeftLdData[sfb+sfboffs]); - pnlrLdData = (sfbThresholdLeftLdData[sfb+sfboffs]>>1) - (tmp>>1); - pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb+sfboffs]>>1); - tmp = fixMax(sfbEnergyRightLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - pnlrLdData = pnlrLdData - (tmp>>1); - - /* pnmsLdData = minThresholdLdData - max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) + - minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs], minThresholdLdData); */ - tmp = fixMax(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData); - pnmsLdData = minThresholdLdData - (tmp>>1); - tmp = fixMax(sfbEnergySideLdData[sfb+sfboffs], minThresholdLdData); - pnmsLdData = pnmsLdData - (tmp>>1); - useMS = (pnmsLdData > (pnlrLdData)); - - - if (useMS) { - msMask[sfb+sfboffs] = 1; - msMaskTrueSomewhere = 1; - for(j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { +void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], + PSY_OUT_CHANNEL *psyOutChannel[2], + const INT *isBook, INT *msDigest, /* output */ + INT *msMask, /* output */ + const INT allowMS, const INT sfbCnt, + const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *sfbOffset) { + FIXP_DBL *sfbEnergyLeft = + psyData[0]->sfbEnergy.Long; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyRight = + psyData[1]->sfbEnergy.Long; /* modified where msMask==1 */ + const FIXP_DBL *sfbEnergyMid = psyData[0]->sfbEnergyMS.Long; + const FIXP_DBL *sfbEnergySide = psyData[1]->sfbEnergyMS.Long; + FIXP_DBL *sfbThresholdLeft = + psyData[0]->sfbThreshold.Long; /* modified where msMask==1 */ + FIXP_DBL *sfbThresholdRight = + psyData[1]->sfbThreshold.Long; /* modified where msMask==1 */ + + FIXP_DBL *sfbSpreadEnLeft = psyData[0]->sfbSpreadEnergy.Long; + FIXP_DBL *sfbSpreadEnRight = psyData[1]->sfbSpreadEnergy.Long; + + FIXP_DBL *sfbEnergyLeftLdData = + psyOutChannel[0]->sfbEnergyLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyRightLdData = + psyOutChannel[1]->sfbEnergyLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbEnergyMidLdData = psyData[0]->sfbEnergyMSLdData; + FIXP_DBL *sfbEnergySideLdData = psyData[1]->sfbEnergyMSLdData; + FIXP_DBL *sfbThresholdLeftLdData = + psyOutChannel[0]->sfbThresholdLdData; /* modified where msMask==1 */ + FIXP_DBL *sfbThresholdRightLdData = + psyOutChannel[1]->sfbThresholdLdData; /* modified where msMask==1 */ + + FIXP_DBL *mdctSpectrumLeft = + psyData[0]->mdctSpectrum; /* modified where msMask==1 */ + FIXP_DBL *mdctSpectrumRight = + psyData[1]->mdctSpectrum; /* modified where msMask==1 */ + + INT sfb, sfboffs, j; /* loop counters */ + FIXP_DBL pnlrLdData, pnmsLdData; + FIXP_DBL minThresholdLdData; + FIXP_DBL minThreshold; + INT useMS; + + INT msMaskTrueSomewhere = 0; /* to determine msDigest */ + INT numMsMaskFalse = + 0; /* number of non-intensity bands where L/R coding is used */ + + for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { + for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { + if ((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) { + FIXP_DBL tmp; + + /* + minThreshold=min(sfbThresholdLeft[sfb+sfboffs], + sfbThresholdRight[sfb+sfboffs])*scaleMinThres; pnlr = + (sfbThresholdLeft[sfb+sfboffs]/ + max(sfbEnergyLeft[sfb+sfboffs],sfbThresholdLeft[sfb+sfboffs]))* + (sfbThresholdRight[sfb+sfboffs]/ + max(sfbEnergyRight[sfb+sfboffs],sfbThresholdRight[sfb+sfboffs])); + pnms = + (minThreshold/max(sfbEnergyMid[sfb+sfboffs],minThreshold))* + (minThreshold/max(sfbEnergySide[sfb+sfboffs],minThreshold)); + useMS = (pnms > pnlr); + */ + + /* we assume that scaleMinThres == 1.0f and we can drop it */ + minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + + /* pnlrLdData = sfbThresholdLeftLdData[sfb+sfboffs] - + max(sfbEnergyLeftLdData[sfb+sfboffs], + sfbThresholdLeftLdData[sfb+sfboffs]) + + sfbThresholdRightLdData[sfb+sfboffs] - + max(sfbEnergyRightLdData[sfb+sfboffs], + sfbThresholdRightLdData[sfb+sfboffs]); */ + tmp = fixMax(sfbEnergyLeftLdData[sfb + sfboffs], + sfbThresholdLeftLdData[sfb + sfboffs]); + pnlrLdData = (sfbThresholdLeftLdData[sfb + sfboffs] >> 1) - (tmp >> 1); + pnlrLdData = pnlrLdData + (sfbThresholdRightLdData[sfb + sfboffs] >> 1); + tmp = fixMax(sfbEnergyRightLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + pnlrLdData = pnlrLdData - (tmp >> 1); + + /* pnmsLdData = minThresholdLdData - + max(sfbEnergyMidLdData[sfb+sfboffs], minThresholdLdData) + + minThresholdLdData - max(sfbEnergySideLdData[sfb+sfboffs], + minThresholdLdData); */ + tmp = fixMax(sfbEnergyMidLdData[sfb + sfboffs], minThresholdLdData); + pnmsLdData = minThresholdLdData - (tmp >> 1); + tmp = fixMax(sfbEnergySideLdData[sfb + sfboffs], minThresholdLdData); + pnmsLdData = pnmsLdData - (tmp >> 1); + useMS = ((allowMS != 0) && (pnmsLdData > pnlrLdData)) ? 1 : 0; + + if (useMS) { + msMask[sfb + sfboffs] = 1; + msMaskTrueSomewhere = 1; + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { + FIXP_DBL specL, specR; + specL = mdctSpectrumLeft[j] >> 1; + specR = mdctSpectrumRight[j] >> 1; + mdctSpectrumLeft[j] = specL + specR; + mdctSpectrumRight[j] = specL - specR; + } + minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs], + sfbThresholdRight[sfb + sfboffs]); + sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] = + minThreshold; + sfbThresholdLeftLdData[sfb + sfboffs] = + sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData; + sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs]; + sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs]; + sfbEnergyLeftLdData[sfb + sfboffs] = + sfbEnergyMidLdData[sfb + sfboffs]; + sfbEnergyRightLdData[sfb + sfboffs] = + sfbEnergySideLdData[sfb + sfboffs]; + + sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] = + fixMin(sfbSpreadEnLeft[sfb + sfboffs], + sfbSpreadEnRight[sfb + sfboffs]) >> + 1; + + } else { + msMask[sfb + sfboffs] = 0; + numMsMaskFalse++; + } /* useMS */ + } /* isBook */ + else { + /* keep mDigest from IS module */ + if (msMask[sfb + sfboffs]) { + msMaskTrueSomewhere = 1; + } + /* prohibit MS_MASK_ALL in combination with IS */ + numMsMaskFalse = 9; + } /* isBook */ + } /* sfboffs */ + } /* sfb */ + + if (msMaskTrueSomewhere == 1) { + if ((numMsMaskFalse == 0) || + ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) { + *msDigest = SI_MS_MASK_ALL; + /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */ + for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { + for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { + if (((isBook == NULL) ? 1 : (isBook[sfb + sfboffs] == 0)) && + (msMask[sfb + sfboffs] == 0)) { + msMask[sfb + sfboffs] = 1; + /* apply M/S coding */ + for (j = sfbOffset[sfb + sfboffs]; j < sfbOffset[sfb + sfboffs + 1]; + j++) { FIXP_DBL specL, specR; - specL = mdctSpectrumLeft[j]>>1; - specR = mdctSpectrumRight[j]>>1; + specL = mdctSpectrumLeft[j] >> 1; + specR = mdctSpectrumRight[j] >> 1; mdctSpectrumLeft[j] = specL + specR; mdctSpectrumRight[j] = specL - specR; } - minThreshold = fixMin(sfbThresholdLeft[sfb+sfboffs], sfbThresholdRight[sfb+sfboffs]); - sfbThresholdLeft[sfb+sfboffs] = sfbThresholdRight[sfb+sfboffs] = minThreshold; - sfbThresholdLeftLdData[sfb+sfboffs] = sfbThresholdRightLdData[sfb+sfboffs] = minThresholdLdData; - sfbEnergyLeft[sfb+sfboffs] = sfbEnergyMid[sfb+sfboffs]; - sfbEnergyRight[sfb+sfboffs] = sfbEnergySide[sfb+sfboffs]; - sfbEnergyLeftLdData[sfb+sfboffs] = sfbEnergyMidLdData[sfb+sfboffs]; - sfbEnergyRightLdData[sfb+sfboffs] = sfbEnergySideLdData[sfb+sfboffs]; - - sfbSpreadEnLeft[sfb+sfboffs] = sfbSpreadEnRight[sfb+sfboffs] = - fixMin( sfbSpreadEnLeft[sfb+sfboffs], - sfbSpreadEnRight[sfb+sfboffs] ) >> 1; - - } - else { - msMask[sfb+sfboffs] = 0; - numMsMaskFalse++; - } /* useMS */ - } /* isBook */ - else { - /* keep mDigest from IS module */ - if (msMask[sfb+sfboffs]) { - msMaskTrueSomewhere = 1; - } - /* prohibit MS_MASK_ALL in combination with IS */ - numMsMaskFalse = 9; - } /* isBook */ - } /* sfboffs */ - } /* sfb */ - - - if(msMaskTrueSomewhere == 1) { - if ((numMsMaskFalse == 0) || ((numMsMaskFalse < maxSfbPerGroup) && (numMsMaskFalse < 9))) { - *msDigest = SI_MS_MASK_ALL; - /* loop through M/S bands; if msMask==0, set it to 1 and apply M/S */ - for (sfb = 0; sfb < sfbCnt; sfb += sfbPerGroup) { - for (sfboffs = 0; sfboffs < maxSfbPerGroup; sfboffs++) { - if (( (isBook == NULL) ? 1 : (isBook[sfb+sfboffs] == 0) ) && (msMask[sfb+sfboffs] == 0)) { - msMask[sfb+sfboffs] = 1; - /* apply M/S coding */ - for(j=sfbOffset[sfb+sfboffs]; j<sfbOffset[sfb+sfboffs+1]; j++) { - FIXP_DBL specL, specR; - specL = mdctSpectrumLeft[j]>>1; - specR = mdctSpectrumRight[j]>>1; - mdctSpectrumLeft[j] = specL + specR; - mdctSpectrumRight[j] = specL - specR; - } - minThreshold = fixMin(sfbThresholdLeft[sfb+sfboffs], sfbThresholdRight[sfb+sfboffs]); - sfbThresholdLeft[sfb+sfboffs] = sfbThresholdRight[sfb+sfboffs] = minThreshold; - minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb+sfboffs], sfbThresholdRightLdData[sfb+sfboffs]); - sfbThresholdLeftLdData[sfb+sfboffs] = sfbThresholdRightLdData[sfb+sfboffs] = minThresholdLdData; - sfbEnergyLeft[sfb+sfboffs] = sfbEnergyMid[sfb+sfboffs]; - sfbEnergyRight[sfb+sfboffs] = sfbEnergySide[sfb+sfboffs]; - sfbEnergyLeftLdData[sfb+sfboffs] = sfbEnergyMidLdData[sfb+sfboffs]; - sfbEnergyRightLdData[sfb+sfboffs] = sfbEnergySideLdData[sfb+sfboffs]; - - sfbSpreadEnLeft[sfb+sfboffs] = sfbSpreadEnRight[sfb+sfboffs] = - fixMin( sfbSpreadEnLeft[sfb+sfboffs], - sfbSpreadEnRight[sfb+sfboffs] ) >> 1; - } + minThreshold = fixMin(sfbThresholdLeft[sfb + sfboffs], + sfbThresholdRight[sfb + sfboffs]); + sfbThresholdLeft[sfb + sfboffs] = sfbThresholdRight[sfb + sfboffs] = + minThreshold; + minThresholdLdData = fixMin(sfbThresholdLeftLdData[sfb + sfboffs], + sfbThresholdRightLdData[sfb + sfboffs]); + sfbThresholdLeftLdData[sfb + sfboffs] = + sfbThresholdRightLdData[sfb + sfboffs] = minThresholdLdData; + sfbEnergyLeft[sfb + sfboffs] = sfbEnergyMid[sfb + sfboffs]; + sfbEnergyRight[sfb + sfboffs] = sfbEnergySide[sfb + sfboffs]; + sfbEnergyLeftLdData[sfb + sfboffs] = + sfbEnergyMidLdData[sfb + sfboffs]; + sfbEnergyRightLdData[sfb + sfboffs] = + sfbEnergySideLdData[sfb + sfboffs]; + + sfbSpreadEnLeft[sfb + sfboffs] = sfbSpreadEnRight[sfb + sfboffs] = + fixMin(sfbSpreadEnLeft[sfb + sfboffs], + sfbSpreadEnRight[sfb + sfboffs]) >> + 1; } } - } else { - *msDigest = SI_MS_MASK_SOME; } } else { - *msDigest = SI_MS_MASK_NONE; + *msDigest = SI_MS_MASK_SOME; } + } else { + *msDigest = SI_MS_MASK_NONE; + } } diff --git a/libAACenc/src/ms_stereo.h b/libAACenc/src/ms_stereo.h index 2f3addb..a202307 100644 --- a/libAACenc/src/ms_stereo.h +++ b/libAACenc/src/ms_stereo.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,29 +90,28 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: MS stereo processing + Author(s): M.Werner -******************************************************************************/ + Description: MS stereo processing -#ifndef __MS_STEREO_H__ -#define __MS_STEREO_H__ +*******************************************************************************/ +#ifndef MS_STEREO_H +#define MS_STEREO_H #include "interface.h" -void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], - PSY_OUT_CHANNEL* psyOutChannel[2], - const INT *isBook, - INT *msDigest, /* output */ - INT *msMask, /* output */ - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - const INT *sfbOffset); - -#endif +void FDKaacEnc_MsStereoProcessing(PSY_DATA *RESTRICT psyData[(2)], + PSY_OUT_CHANNEL *psyOutChannel[2], + const INT *isBook, INT *msDigest, /* output */ + INT *msMask, /* output */ + const INT allowMS, const INT sfbCnt, + const INT sfbPerGroup, + const INT maxSfbPerGroup, + const INT *sfbOffset); + +#endif /* MS_STEREO_H */ diff --git a/libAACenc/src/noisedet.cpp b/libAACenc/src/noisedet.cpp index f3c51de..c984304 100644 --- a/libAACenc/src/noisedet.cpp +++ b/libAACenc/src/noisedet.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,22 +90,22 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: noisedet.c - Routines for Noise Detection + Description: noisedet.c + Routines for Noise Detection -******************************************************************************/ +*******************************************************************************/ #include "noisedet.h" #include "aacenc_pns.h" #include "pnsparam.h" - /***************************************************************************** functionname: FDKaacEnc_fuzzyIsSmaller @@ -105,20 +116,16 @@ amm-info@iis.fraunhofer.de output: return fuzzy value *****************************************************************************/ -static FIXP_SGL FDKaacEnc_fuzzyIsSmaller( FIXP_DBL testVal, - FIXP_DBL refVal, - FIXP_DBL loLim, - FIXP_DBL hiLim ) -{ +static FIXP_SGL FDKaacEnc_fuzzyIsSmaller(FIXP_DBL testVal, FIXP_DBL refVal, + FIXP_DBL loLim, FIXP_DBL hiLim) { if (refVal <= FL2FXCONST_DBL(0.0)) - return( FL2FXCONST_SGL(0.0f) ); - else if (testVal >= fMult((hiLim>>1)+(loLim>>1), refVal)) - return( FL2FXCONST_SGL(0.0f) ); - else return( (FIXP_SGL)MAXVAL_SGL ); + return (FL2FXCONST_SGL(0.0f)); + else if (testVal >= fMult((hiLim >> 1) + (loLim >> 1), refVal)) + return (FL2FXCONST_SGL(0.0f)); + else + return ((FIXP_SGL)MAXVAL_SGL); } - - /***************************************************************************** functionname: FDKaacEnc_noiseDetect @@ -140,45 +147,45 @@ static FIXP_SGL FDKaacEnc_fuzzyIsSmaller( FIXP_DBL testVal, *****************************************************************************/ -void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum, - INT *RESTRICT sfbMaxScaleSpec, - INT sfbActive, - const INT *RESTRICT sfbOffset, - FIXP_SGL *RESTRICT noiseFuzzyMeasure, - NOISEPARAMS *np, - FIXP_SGL *RESTRICT sfbtonality ) +void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum, + INT *RESTRICT sfbMaxScaleSpec, INT sfbActive, + const INT *RESTRICT sfbOffset, + FIXP_SGL *RESTRICT noiseFuzzyMeasure, + NOISEPARAMS *np, FIXP_SGL *RESTRICT sfbtonality) { - int i, k, sfb, sfbWidth; + int i, k, sfb, sfbWidth; FIXP_SGL fuzzy, fuzzyTotal; FIXP_DBL refVal, testVal; /***** Start detection phase *****/ /* Start noise detection for each band based on a number of checks */ - for (sfb=0; sfb<sfbActive; sfb++) { - + for (sfb = 0; sfb < sfbActive; sfb++) { fuzzyTotal = (FIXP_SGL)MAXVAL_SGL; - sfbWidth = sfbOffset[sfb+1] - sfbOffset[sfb]; + sfbWidth = sfbOffset[sfb + 1] - sfbOffset[sfb]; /* Reset output for lower bands or too small bands */ - if (sfb < np->startSfb || sfbWidth < np->minSfbWidth) { + if (sfb < np->startSfb || sfbWidth < np->minSfbWidth) { noiseFuzzyMeasure[sfb] = FL2FXCONST_SGL(0.0f); continue; } - if ( (np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) && (fuzzyTotal > FL2FXCONST_SGL(0.5f)) ) { + if ((np->detectionAlgorithmFlags & USE_POWER_DISTRIBUTION) && + (fuzzyTotal > FL2FXCONST_SGL(0.5f))) { FIXP_DBL fhelp1, fhelp2, fhelp3, fhelp4, maxVal, minVal; - INT leadingBits = fixMax(0,(sfbMaxScaleSpec[sfb] - 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */ + INT leadingBits = fixMax( + 0, (sfbMaxScaleSpec[sfb] - + 3)); /* max sfbWidth = 96/4 ; 2^5=32 => 5/2 = 3 (spc*spc) */ /* check power distribution in four regions */ fhelp1 = fhelp2 = fhelp3 = fhelp4 = FL2FXCONST_DBL(0.0f); - k = sfbWidth >>2; /* Width of a quarter band */ + k = sfbWidth >> 2; /* Width of a quarter band */ - for (i=sfbOffset[sfb]; i<sfbOffset[sfb]+k; i++) { - fhelp1 = fPow2AddDiv2(fhelp1, mdctSpectrum[i]<<leadingBits); - fhelp2 = fPow2AddDiv2(fhelp2, mdctSpectrum[i+k]<<leadingBits); - fhelp3 = fPow2AddDiv2(fhelp3, mdctSpectrum[i+2*k]<<leadingBits); - fhelp4 = fPow2AddDiv2(fhelp4, mdctSpectrum[i+3*k]<<leadingBits); + for (i = sfbOffset[sfb]; i < sfbOffset[sfb] + k; i++) { + fhelp1 = fPow2AddDiv2(fhelp1, mdctSpectrum[i] << leadingBits); + fhelp2 = fPow2AddDiv2(fhelp2, mdctSpectrum[i + k] << leadingBits); + fhelp3 = fPow2AddDiv2(fhelp3, mdctSpectrum[i + 2 * k] << leadingBits); + fhelp4 = fPow2AddDiv2(fhelp4, mdctSpectrum[i + 3 * k] << leadingBits); } /* get max into fhelp: */ @@ -194,34 +201,34 @@ void FDKaacEnc_noiseDetect(FIXP_DBL *RESTRICT mdctSpectrum, /* Normalize min and max Val */ leadingBits = CountLeadingBits(maxVal); testVal = maxVal << leadingBits; - refVal = minVal << leadingBits; + refVal = minVal << leadingBits; /* calculate fuzzy value for power distribution */ testVal = fMultDiv2(testVal, np->powDistPSDcurve[sfb]); - fuzzy = FDKaacEnc_fuzzyIsSmaller(testVal, /* 1/2 * maxValue * PSDcurve */ - refVal, /* 1 * minValue */ - FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */ - FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */ + fuzzy = FDKaacEnc_fuzzyIsSmaller( + testVal, /* 1/2 * maxValue * PSDcurve */ + refVal, /* 1 * minValue */ + FL2FXCONST_DBL(0.495), /* 1/2 * loLim (0.99f/2) */ + FL2FXCONST_DBL(0.505)); /* 1/2 * hiLim (1.01f/2) */ fuzzyTotal = fixMin(fuzzyTotal, fuzzy); } - if ( (np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) && (fuzzyTotal > FL2FXCONST_SGL(0.5f)) ) { + if ((np->detectionAlgorithmFlags & USE_PSYCH_TONALITY) && + (fuzzyTotal > FL2FXCONST_SGL(0.5f))) { /* Detection with tonality-value of psych. acoustic (here: 1 is tonal!)*/ - testVal = FX_SGL2FX_DBL(sfbtonality[sfb])>>1; /* 1/2 * sfbTonality */ - refVal = np->refTonality; + testVal = FX_SGL2FX_DBL(sfbtonality[sfb]) >> 1; /* 1/2 * sfbTonality */ + refVal = np->refTonality; - fuzzy = FDKaacEnc_fuzzyIsSmaller(testVal, - refVal, - FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */ - FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */ + fuzzy = FDKaacEnc_fuzzyIsSmaller( + testVal, refVal, FL2FXCONST_DBL(0.45f), /* 1/2 * loLim (0.9f/2) */ + FL2FXCONST_DBL(0.55f)); /* 1/2 * hiLim (1.1f/2) */ fuzzyTotal = fixMin(fuzzyTotal, fuzzy); } - /* Output of final result */ noiseFuzzyMeasure[sfb] = fuzzyTotal; } diff --git a/libAACenc/src/noisedet.h b/libAACenc/src/noisedet.h index 8d5e365..478701f 100644 --- a/libAACenc/src/noisedet.h +++ b/libAACenc/src/noisedet.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,30 +90,27 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: noisedet.h + Description: noisedet.h -******************************************************************************/ +*******************************************************************************/ -#ifndef __NOISEDET_H -#define __NOISEDET_H +#ifndef NOISEDET_H +#define NOISEDET_H #include "common_fix.h" #include "pnsparam.h" #include "psy_data.h" +void FDKaacEnc_noiseDetect(FIXP_DBL *mdctSpectrum, INT *sfbMaxScaleSpec, + INT sfbActive, const INT *sfbOffset, + FIXP_SGL noiseFuzzyMeasure[], NOISEPARAMS *np, + FIXP_SGL *sfbtonality); -void FDKaacEnc_noiseDetect( FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - INT sfbActive, - const INT *sfbOffset, - FIXP_SGL noiseFuzzyMeasure[], - NOISEPARAMS *np, - FIXP_SGL *sfbtonality ); - -#endif +#endif /* NOISEDET_H */ diff --git a/libAACenc/src/pns_func.h b/libAACenc/src/pns_func.h index efa44ef..88f4586 100644 --- a/libAACenc/src/pns_func.h +++ b/libAACenc/src/pns_func.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,72 +90,49 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Lohwasser - contents/description: pns_func.h + Author(s): M. Lohwasser -******************************************************************************/ + Description: pns_func.h -#ifndef _PNS_FUNC_H -#define _PNS_FUNC_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef PNS_FUNC_H +#define PNS_FUNC_H +#include "common_fix.h" #include "aacenc_pns.h" #include "psy_data.h" - - -AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration(PNS_CONFIG *pnsConf, - INT bitRate, - INT sampleRate, - INT usePns, - INT sfbCnt, - const INT *sfbOffset, - const INT numChan, - const INT isLC ); - -void FDKaacEnc_PnsDetect( PNS_CONFIG *pnsConf, - PNS_DATA *pnsData, - const INT lastWindowSequence, - const INT sfbActive, - const INT maxSfbPerGroup, - FIXP_DBL *sfbThresholdLdData, - const INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT *sfbMaxScaleSpec, - FIXP_SGL *sfbtonality, - int tnsOrder, - INT tnsPredictionGain, - INT tnsActive, - FIXP_DBL *sfbEnergyLdData, - INT *noiseNrg ); - -void FDKaacEnc_CodePnsChannel( const INT sfbActive, - PNS_CONFIG *pnsConf, - INT *pnsFlag, - FIXP_DBL *sfbEnergy, - INT *noiseNrg, - FIXP_DBL *sfbThreshold ); - -void FDKaacEnc_PreProcessPnsChannelPair( const INT sfbActive, - FIXP_DBL *sfbEnergyLeft, - FIXP_DBL *sfbEnergyRight, - FIXP_DBL *sfbEnergyLeftLD, - FIXP_DBL *sfbEnergyRightLD, - FIXP_DBL *sfbEnergyMid, - PNS_CONFIG *pnsConfLeft, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight ); - -void FDKaacEnc_PostProcessPnsChannelPair( const INT sfbActive, - PNS_CONFIG *pnsConf, - PNS_DATA *pnsDataLeft, - PNS_DATA *pnsDataRight, - INT *msMask, - INT *msDigest ); - -#endif /* _PNS_FUNC_H */ +AAC_ENCODER_ERROR FDKaacEnc_InitPnsConfiguration( + PNS_CONFIG *pnsConf, INT bitRate, INT sampleRate, INT usePns, INT sfbCnt, + const INT *sfbOffset, const INT numChan, const INT isLC); + +void FDKaacEnc_PnsDetect(PNS_CONFIG *pnsConf, PNS_DATA *pnsData, + const INT lastWindowSequence, const INT sfbActive, + const INT maxSfbPerGroup, FIXP_DBL *sfbThresholdLdData, + const INT *sfbOffset, FIXP_DBL *mdctSpectrum, + INT *sfbMaxScaleSpec, FIXP_SGL *sfbtonality, + int tnsOrder, INT tnsPredictionGain, INT tnsActive, + FIXP_DBL *sfbEnergyLdData, INT *noiseNrg); + +void FDKaacEnc_CodePnsChannel(const INT sfbActive, PNS_CONFIG *pnsConf, + INT *pnsFlag, FIXP_DBL *sfbEnergy, INT *noiseNrg, + FIXP_DBL *sfbThreshold); + +void FDKaacEnc_PreProcessPnsChannelPair( + const INT sfbActive, FIXP_DBL *sfbEnergyLeft, FIXP_DBL *sfbEnergyRight, + FIXP_DBL *sfbEnergyLeftLD, FIXP_DBL *sfbEnergyRightLD, + FIXP_DBL *sfbEnergyMid, PNS_CONFIG *pnsConfLeft, PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight); + +void FDKaacEnc_PostProcessPnsChannelPair(const INT sfbActive, + PNS_CONFIG *pnsConf, + PNS_DATA *pnsDataLeft, + PNS_DATA *pnsDataRight, INT *msMask, + INT *msDigest); + +#endif /* PNS_FUNC_H */ diff --git a/libAACenc/src/pnsparam.cpp b/libAACenc/src/pnsparam.cpp index 9d59ddc..a6aab06 100644 --- a/libAACenc/src/pnsparam.cpp +++ b/libAACenc/src/pnsparam.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,31 +90,32 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Lohwasser - Initial author: M.Lohwasser - contents/description: PNS parameters depending on bitrate and bandwidth + Description: PNS parameters depending on bitrate and bandwidth -******************************************************************************/ +*******************************************************************************/ #include "pnsparam.h" + #include "psy_configuration.h" typedef struct { - SHORT startFreq; + SHORT startFreq; /* Parameters for detection */ - FIXP_SGL refPower; - FIXP_SGL refTonality; - SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ - SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ - FIXP_SGL gapFillThr; - SHORT minSfbWidth; - USHORT detectionAlgorithmFlags; + FIXP_SGL refPower; + FIXP_SGL refTonality; + SHORT tnsGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ + SHORT tnsPNSGainThreshold; /* scaled by TNS_PREDGAIN_SCALE (=1000) */ + FIXP_SGL gapFillThr; + SHORT minSfbWidth; + USHORT detectionAlgorithmFlags; } PNS_INFO_TAB; - typedef struct { ULONG brFrom; ULONG brTo; @@ -115,197 +127,448 @@ typedef struct { UCHAR S48000; } AUTO_PNS_TAB; -static const AUTO_PNS_TAB levelTable_mono[]= { - {0, 11999, 0, 1, 1, 1, 1, 1,}, - {12000, 19999, 0, 1, 1, 1, 1, 1,}, - {20000, 28999, 0, 2, 1, 1, 1, 1,}, - {29000, 40999, 0, 4, 4, 4, 2, 2,}, - {41000, 55999, 0, 9, 9, 7, 7, 7,}, - {56000, 61999, 0, 0, 0, 0, 9, 9,}, - {62000, 75999, 0, 0, 0, 0, 0, 0,}, - {76000, 92999, 0, 0, 0, 0, 0, 0,}, - {93000, 999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_mono[] = { + { + 0, + 11999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 12000, + 19999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 20000, + 28999, + 0, + 2, + 1, + 1, + 1, + 1, + }, + { + 29000, + 40999, + 0, + 4, + 4, + 4, + 2, + 2, + }, + { + 41000, + 55999, + 0, + 9, + 9, + 7, + 7, + 7, + }, + { + 56000, + 61999, + 0, + 0, + 0, + 0, + 9, + 9, + }, + { + 62000, + 75999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 76000, + 92999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 93000, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; -static const AUTO_PNS_TAB levelTable_stereo[]= { - {0, 11999, 0, 1, 1, 1, 1, 1,}, - {12000, 19999, 0, 3, 1, 1, 1, 1,}, - {20000, 28999, 0, 3, 3, 3, 2, 2,}, - {29000, 40999, 0, 7, 6, 6, 5, 5,}, - {41000, 55999, 0, 9, 9, 7, 7, 7,}, - {56000, 79999, 0, 0, 0, 0, 0, 0,}, - {80000, 99999, 0, 0, 0, 0, 0, 0,}, - {100000,999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_stereo[] = { + { + 0, + 11999, + 0, + 1, + 1, + 1, + 1, + 1, + }, + { + 12000, + 19999, + 0, + 3, + 1, + 1, + 1, + 1, + }, + { + 20000, + 28999, + 0, + 3, + 3, + 3, + 2, + 2, + }, + { + 29000, + 40999, + 0, + 7, + 6, + 6, + 5, + 5, + }, + { + 41000, + 55999, + 0, + 9, + 9, + 7, + 7, + 7, + }, + { + 56000, + 79999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 80000, + 99999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 100000, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; - static const PNS_INFO_TAB pnsInfoTab[] = { -/*0 pns off */ -/*1*/ { 4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200, FL2FXCONST_SGL(0.02), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*2*/ { 4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300, FL2FXCONST_SGL(0.05), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*3*/ { 4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400, FL2FXCONST_SGL(0.10), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*4*/ { 4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.15), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS /*| JUST_LONG_WINDOW*/ }, -/*5*/ { 4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.15), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*6*/ { 5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.25), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*7*/ { 5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400, FL2FXCONST_SGL(0.35), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*8*/ { 6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400, FL2FXCONST_SGL(0.40), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*9*/ { 6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400, FL2FXCONST_SGL(0.45), 8, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, + /*0 pns off */ + /*1*/ {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.06), 1150, 1200, + FL2FXCONST_SGL(0.02), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*2*/ + {4000, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1130, 1300, + FL2FXCONST_SGL(0.05), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*3*/ + {4100, FL2FXCONST_SGL(0.04), FL2FXCONST_SGL(0.07), 1100, 1400, + FL2FXCONST_SGL(0.10), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*4*/ + {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.15), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS /*| JUST_LONG_WINDOW*/}, + /*5*/ + {4300, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.15), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*6*/ + {5000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.25), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*7*/ + {5500, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1100, 1400, + FL2FXCONST_SGL(0.35), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*8*/ + {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.12), 1080, 1400, + FL2FXCONST_SGL(0.40), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*9*/ + {6000, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.14), 1070, 1400, + FL2FXCONST_SGL(0.45), 8, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, }; -static const AUTO_PNS_TAB levelTable_lowComplexity[]= { - {0, 27999, 0, 0, 0, 0, 0, 0,}, - {28000, 31999, 0, 2, 2, 2, 2, 2,}, - {32000, 47999, 0, 3, 3, 3, 3, 3,}, - {48000, 48000, 0, 4, 4, 4, 4, 4,}, - {48001, 999999, 0, 0, 0, 0, 0, 0,}, +static const AUTO_PNS_TAB levelTable_lowComplexity[] = { + { + 0, + 27999, + 0, + 0, + 0, + 0, + 0, + 0, + }, + { + 28000, + 31999, + 0, + 2, + 2, + 2, + 2, + 2, + }, + { + 32000, + 47999, + 0, + 3, + 3, + 3, + 3, + 3, + }, + { + 48000, + 48000, + 0, + 4, + 4, + 4, + 4, + 4, + }, + { + 48001, + 999999, + 0, + 0, + 0, + 0, + 0, + 0, + }, }; - -/* conversion of old LC tuning tables to new (LD enc) structure (only entries which are actually used were converted) */ +/* conversion of old LC tuning tables to new (LD enc) structure (only entries + * which are actually used were converted) */ static const PNS_INFO_TAB pnsInfoTab_lowComplexity[] = { -/*0 pns off */ - /* DEFAULT parameter set */ -/*1*/ { 4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*2*/ { 4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, -/*3*/ { 4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, - /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for br: 48000 - 79999) */ -/*4*/ { 4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400, FL2FXCONST_SGL(0.5), 16, - USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | USE_TNS_PNS | JUST_LONG_WINDOW }, + /*0 pns off */ + /* DEFAULT parameter set */ + /*1*/ {4100, FL2FXCONST_SGL(0.03), FL2FXCONST_SGL(0.16), 1100, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*2*/ + {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1410, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /*3*/ + {4100, FL2FXCONST_SGL(0.05), FL2FXCONST_SGL(0.10), 1100, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, + /* LOWSUBST -> PNS is used less often than with DEFAULT parameter set (for + br: 48000 - 79999) */ + /*4*/ + {4100, FL2FXCONST_SGL(0.20), FL2FXCONST_SGL(0.10), 1410, 1400, + FL2FXCONST_SGL(0.5), 16, + USE_POWER_DISTRIBUTION | USE_PSYCH_TONALITY | USE_TNS_GAIN_THR | + USE_TNS_PNS | JUST_LONG_WINDOW}, }; /**************************************************************************** function to look up used pns level ****************************************************************************/ -int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int isLC) { - - int hUsePns=0, size, i; +int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan, + const int isLC) { + int hUsePns = 0, size, i; const AUTO_PNS_TAB *levelTable; if (isLC) { levelTable = &levelTable_lowComplexity[0]; size = sizeof(levelTable_lowComplexity); - } else - { /* (E)LD */ + } else { /* (E)LD */ levelTable = (numChan > 1) ? &levelTable_stereo[0] : &levelTable_mono[0]; size = (numChan > 1) ? sizeof(levelTable_stereo) : sizeof(levelTable_mono); } - for(i = 0; i < (int) (size/sizeof(AUTO_PNS_TAB)); i++) { - if(((ULONG)bitRate >= levelTable[i].brFrom) && - ((ULONG)bitRate <= levelTable[i].brTo) ) + for (i = 0; i < (int)(size / sizeof(AUTO_PNS_TAB)); i++) { + if (((ULONG)bitRate >= levelTable[i].brFrom) && + ((ULONG)bitRate <= levelTable[i].brTo)) break; } /* sanity check */ - if ((int)(sizeof(pnsInfoTab)/sizeof(PNS_INFO_TAB)) < i ) { + if ((int)(sizeof(pnsInfoTab) / sizeof(PNS_INFO_TAB)) < i) { return (PNS_TABLE_ERROR); } switch (sampleRate) { - case 16000: hUsePns = levelTable[i].S16000; break; - case 22050: hUsePns = levelTable[i].S22050; break; - case 24000: hUsePns = levelTable[i].S24000; break; - case 32000: hUsePns = levelTable[i].S32000; break; - case 44100: hUsePns = levelTable[i].S44100; break; - case 48000: hUsePns = levelTable[i].S48000; break; - default: - if (isLC) { + case 16000: + hUsePns = levelTable[i].S16000; + break; + case 22050: + hUsePns = levelTable[i].S22050; + break; + case 24000: + hUsePns = levelTable[i].S24000; + break; + case 32000: + hUsePns = levelTable[i].S32000; + break; + case 44100: + hUsePns = levelTable[i].S44100; + break; + case 48000: hUsePns = levelTable[i].S48000; - } - break; + break; + default: + if (isLC) { + hUsePns = levelTable[i].S48000; + } + break; } return (hUsePns); } - /***************************************************************************** functionname: FDKaacEnc_GetPnsParam - description: Gets PNS parameters depending on bitrate and bandwidth + description: Gets PNS parameters depending on bitrate and bandwidth or + bitsPerLine returns: error status input: Noiseparams struct, bitrate, sampling rate, number of sfb's, pointer to sfb offset output: PNS parameters *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, - INT bitRate, - INT sampleRate, - INT sfbCnt, - const INT *sfbOffset, - INT *usePns, - INT numChan, - const int isLC) - -{ - int i, hUsePns; - const PNS_INFO_TAB *pnsInfo; - - if (isLC) { - np->detectionAlgorithmFlags = IS_LOW_COMLEXITY; - pnsInfo = pnsInfoTab_lowComplexity; +AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate, + INT sampleRate, INT sfbCnt, + const INT *sfbOffset, INT *usePns, + INT numChan, const INT isLC) { + int i, hUsePns; + const PNS_INFO_TAB *pnsInfo; + + if (*usePns <= 0) return AAC_ENC_OK; + + if (isLC) { + np->detectionAlgorithmFlags = IS_LOW_COMPLEXITY; + + pnsInfo = pnsInfoTab_lowComplexity; + + /* new pns params */ + hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC); + if (hUsePns == 0) { + *usePns = 0; + return AAC_ENC_OK; } - else - { - np->detectionAlgorithmFlags = 0; - pnsInfo = pnsInfoTab; + + if (hUsePns == PNS_TABLE_ERROR) { + return AAC_ENC_PNS_TABLE_ERROR; } - if (*usePns<=0) - return AAC_ENC_OK; + /* select correct row of tuning table */ + pnsInfo += hUsePns - 1; + + } else { + np->detectionAlgorithmFlags = 0; + pnsInfo = pnsInfoTab; /* new pns params */ - hUsePns = FDKaacEnc_lookUpPnsUse (bitRate, sampleRate, numChan, isLC); + hUsePns = FDKaacEnc_lookUpPnsUse(bitRate, sampleRate, numChan, isLC); if (hUsePns == 0) { *usePns = 0; - return AAC_ENC_OK; - } - if (hUsePns == PNS_TABLE_ERROR) - return AAC_ENC_PNS_TABLE_ERROR; + return AAC_ENC_OK; + } + if (hUsePns == PNS_TABLE_ERROR) return AAC_ENC_PNS_TABLE_ERROR; /* select correct row of tuning table */ - pnsInfo += hUsePns-1; + pnsInfo += hUsePns - 1; + } - np->startSfb = FDKaacEnc_FreqToBandWithRounding( pnsInfo->startFreq, - sampleRate, - sfbCnt, - sfbOffset ); + np->startSfb = FDKaacEnc_FreqToBandWidthRounding( + pnsInfo->startFreq, sampleRate, sfbCnt, sfbOffset); - np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags; + np->detectionAlgorithmFlags |= pnsInfo->detectionAlgorithmFlags; - np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower); - np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality); - np->tnsGainThreshold = pnsInfo->tnsGainThreshold; - np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold; - np->minSfbWidth = pnsInfo->minSfbWidth; + np->refPower = FX_SGL2FX_DBL(pnsInfo->refPower); + np->refTonality = FX_SGL2FX_DBL(pnsInfo->refTonality); + np->tnsGainThreshold = pnsInfo->tnsGainThreshold; + np->tnsPNSGainThreshold = pnsInfo->tnsPNSGainThreshold; + np->minSfbWidth = pnsInfo->minSfbWidth; - np->gapFillThr = (FIXP_SGL)pnsInfo->gapFillThr; + np->gapFillThr = + pnsInfo->gapFillThr; /* for LC it is always FL2FXCONST_SGL(0.5) */ - /* assuming a constant dB/Hz slope in the signal's PSD curve, + /* assuming a constant dB/Hz slope in the signal's PSD curve, the detection threshold needs to be corrected for the width of the band */ - for ( i = 0; i < (sfbCnt-1); i++) - { - INT qtmp, sfbWidth; - FIXP_DBL tmp; - sfbWidth = sfbOffset[i+1]-sfbOffset[i]; + for (i = 0; i < (sfbCnt - 1); i++) { + INT qtmp, sfbWidth; + FIXP_DBL tmp; - tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS-1-5, &qtmp); - np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16)); - } - np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt-1]; + sfbWidth = sfbOffset[i + 1] - sfbOffset[i]; + + tmp = fPow(np->refPower, 0, sfbWidth, DFRACT_BITS - 1 - 5, &qtmp); + np->powDistPSDcurve[i] = (FIXP_SGL)((LONG)(scaleValue(tmp, qtmp) >> 16)); + } + np->powDistPSDcurve[sfbCnt] = np->powDistPSDcurve[sfbCnt - 1]; return AAC_ENC_OK; } diff --git a/libAACenc/src/pnsparam.h b/libAACenc/src/pnsparam.h index 08bb83e..c37738a 100644 --- a/libAACenc/src/pnsparam.h +++ b/libAACenc/src/pnsparam.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,36 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Lohwasser - Initial author: M. Lohwasser - contents/description: PNS parameters depending on bitrate and bandwidth + Description: PNS parameters depending on bitrate and bandwidth -******************************************************************************/ +*******************************************************************************/ -#ifndef __PNSPARAM_H -#define __PNSPARAM_H +#ifndef PNSPARAM_H +#define PNSPARAM_H #include "aacenc.h" #include "common_fix.h" #include "psy_const.h" -#define NUM_PNSINFOTAB 4 -#define PNS_TABLE_ERROR -1 +#define NUM_PNSINFOTAB 4 +#define PNS_TABLE_ERROR -1 /* detection algorithm flags */ -#define USE_POWER_DISTRIBUTION (1<<0) -#define USE_PSYCH_TONALITY (1<<1) -#define USE_TNS_GAIN_THR (1<<2) -#define USE_TNS_PNS (1<<3) -#define JUST_LONG_WINDOW (1<<4) +#define USE_POWER_DISTRIBUTION (1 << 0) +#define USE_PSYCH_TONALITY (1 << 1) +#define USE_TNS_GAIN_THR (1 << 2) +#define USE_TNS_PNS (1 << 3) +#define JUST_LONG_WINDOW (1 << 4) /* additional algorithm flags */ -#define IS_LOW_COMLEXITY (1<<5) +#define IS_LOW_COMPLEXITY (1 << 5) -typedef struct -{ +typedef struct { /* PNS start band */ short startSfb; @@ -116,26 +127,23 @@ typedef struct USHORT detectionAlgorithmFlags; /* Parameters for detection */ - FIXP_DBL refPower; - FIXP_DBL refTonality; - INT tnsGainThreshold; - INT tnsPNSGainThreshold; - INT minSfbWidth; - FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB]; - FIXP_SGL gapFillThr; + FIXP_DBL refPower; + FIXP_DBL refTonality; + INT tnsGainThreshold; + INT tnsPNSGainThreshold; + INT minSfbWidth; + FIXP_SGL powDistPSDcurve[MAX_GROUPED_SFB]; + FIXP_SGL gapFillThr; } NOISEPARAMS; -int FDKaacEnc_lookUpPnsUse (int bitRate, int sampleRate, int numChan, const int isLC); +int FDKaacEnc_lookUpPnsUse(int bitRate, int sampleRate, int numChan, + const int isLC); /****** Definition of prototypes ******/ -AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, - INT bitRate, - INT sampleRate, - INT sfbCnt, - const INT *sfbOffset, - INT *usePns, - INT numChan, - const INT isLC); +AAC_ENCODER_ERROR FDKaacEnc_GetPnsParam(NOISEPARAMS *np, INT bitRate, + INT sampleRate, INT sfbCnt, + const INT *sfbOffset, INT *usePns, + INT numChan, const INT isLC); -#endif +#endif /* PNSPARAM_H */ diff --git a/libAACenc/src/pre_echo_control.cpp b/libAACenc/src/pre_echo_control.cpp index 3dfd8ed..3d5d153 100644 --- a/libAACenc/src/pre_echo_control.cpp +++ b/libAACenc/src/pre_echo_control.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,92 +90,87 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Pre echo control + Description: Pre echo control -******************************************************************************/ +*******************************************************************************/ #include "pre_echo_control.h" #include "psy_configuration.h" -void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, - INT *calcPreEcho, - INT numPb, - FIXP_DBL *RESTRICT sfbPcmQuantThreshold, - INT *mdctScalenm1) -{ - *mdctScalenm1 = PCM_QUANT_THR_SCALE>>1; +void FDKaacEnc_InitPreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, + INT *calcPreEcho, INT numPb, + FIXP_DBL *RESTRICT sfbPcmQuantThreshold, + INT *mdctScalenm1) { + *mdctScalenm1 = PCM_QUANT_THR_SCALE >> 1; - FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb*sizeof(FIXP_DBL)); + FDKmemcpy(pbThresholdNm1, sfbPcmQuantThreshold, numPb * sizeof(FIXP_DBL)); *calcPreEcho = 1; } +void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, + INT calcPreEcho, INT numPb, + INT maxAllowedIncreaseFactor, + FIXP_SGL minRemainingThresholdFactor, + FIXP_DBL *RESTRICT pbThreshold, INT mdctScale, + INT *mdctScalenm1) { + int i; + FIXP_DBL tmpThreshold1, tmpThreshold2; + int scaling; + + /* If lastWindowSequence in previous frame was start- or stop-window, + skip preechocontrol calculation */ + if (calcPreEcho == 0) { + /* copy thresholds to internal memory */ + FDKmemcpy(pbThresholdNm1, pbThreshold, numPb * sizeof(FIXP_DBL)); + *mdctScalenm1 = mdctScale; + return; + } + + if (mdctScale > *mdctScalenm1) { + /* if current thresholds are downscaled more than the ones from the last + * block */ + scaling = 2 * (mdctScale - *mdctScalenm1); + for (i = 0; i < numPb; i++) { + /* multiplication with return data type fract ist equivalent to int + * multiplication */ + FDK_ASSERT(scaling >= 0); + tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i] >> scaling); + tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); + + FIXP_DBL tmp = pbThreshold[i]; -void FDKaacEnc_PreEchoControl(FIXP_DBL *RESTRICT pbThresholdNm1, - INT calcPreEcho, - INT numPb, - INT maxAllowedIncreaseFactor, - FIXP_SGL minRemainingThresholdFactor, - FIXP_DBL *RESTRICT pbThreshold, - INT mdctScale, - INT *mdctScalenm1) -{ - int i; - FIXP_DBL tmpThreshold1, tmpThreshold2; - int scaling; - - /* If lastWindowSequence in previous frame was start- or stop-window, - skip preechocontrol calculation */ - if (calcPreEcho==0) { /* copy thresholds to internal memory */ - FDKmemcpy(pbThresholdNm1, pbThreshold, numPb*sizeof(FIXP_DBL)); - *mdctScalenm1 = mdctScale; - return; - } - - if ( mdctScale > *mdctScalenm1 ) { - /* if current thresholds are downscaled more than the ones from the last block */ - scaling = 2*(mdctScale-*mdctScalenm1); - for(i = 0; i < numPb; i++) { + pbThresholdNm1[i] = tmp; - /* multiplication with return data type fract ist equivalent to int multiplication */ - FDK_ASSERT(scaling>=0); - tmpThreshold1 = maxAllowedIncreaseFactor * (pbThresholdNm1[i]>>scaling); - tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - - FIXP_DBL tmp = pbThreshold[i]; + tmp = fixMin(tmp, tmpThreshold1); + pbThreshold[i] = fixMax(tmp, tmpThreshold2); + } + } else { + /* if thresholds of last block are more downscaled than the current ones */ + scaling = 2 * (*mdctScalenm1 - mdctScale); + for (i = 0; i < numPb; i++) { + /* multiplication with return data type fract ist equivalent to int + * multiplication */ + tmpThreshold1 = (maxAllowedIncreaseFactor >> 1) * pbThresholdNm1[i]; + tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - /* copy thresholds to internal memory */ - pbThresholdNm1[i] = tmp; + /* copy thresholds to internal memory */ + pbThresholdNm1[i] = pbThreshold[i]; - tmp = fixMin(tmp, tmpThreshold1); - pbThreshold[i] = fixMax(tmp, tmpThreshold2); - } - } - else { - /* if thresholds of last block are more downscaled than the current ones */ - scaling = 2*(*mdctScalenm1-mdctScale); - for(i = 0; i < numPb; i++) { - - /* multiplication with return data type fract ist equivalent to int multiplication */ - tmpThreshold1 = (maxAllowedIncreaseFactor>>1) * pbThresholdNm1[i]; - tmpThreshold2 = fMult(minRemainingThresholdFactor, pbThreshold[i]); - - /* copy thresholds to internal memory */ - pbThresholdNm1[i] = pbThreshold[i]; - - FDK_ASSERT(scaling>=0); - if((pbThreshold[i]>>(scaling+1)) > tmpThreshold1) { - pbThreshold[i] = tmpThreshold1<<(scaling+1); - } - pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2); - } + FDK_ASSERT(scaling >= 0); + if ((pbThreshold[i] >> (scaling + 1)) > tmpThreshold1) { + pbThreshold[i] = tmpThreshold1 << (scaling + 1); + } + pbThreshold[i] = fixMax(pbThreshold[i], tmpThreshold2); } + } - *mdctScalenm1 = mdctScale; + *mdctScalenm1 = mdctScale; } diff --git a/libAACenc/src/pre_echo_control.h b/libAACenc/src/pre_echo_control.h index 9224db0..688efdb 100644 --- a/libAACenc/src/pre_echo_control.h +++ b/libAACenc/src/pre_echo_control.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,36 +90,29 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** +----------------------------------------------------------------------------- */ - Initial author: M.Werner - contents/description: Pre echo control +/**************************** AAC encoder library ****************************** -******************************************************************************/ + Author(s): M.Werner -#ifndef __PRE_ECHO_CONTROL_H -#define __PRE_ECHO_CONTROL_H + Description: Pre echo control -#include "common_fix.h" +*******************************************************************************/ +#ifndef PRE_ECHO_CONTROL_H +#define PRE_ECHO_CONTROL_H -void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, - INT *calcPreEcho, - INT numPb, - FIXP_DBL *sfbPcmQuantThreshold, - INT *mdctScalenm1); +#include "common_fix.h" +void FDKaacEnc_InitPreEchoControl(FIXP_DBL *pbThresholdnm1, INT *calcPreEcho, + INT numPb, FIXP_DBL *sfbPcmQuantThreshold, + INT *mdctScalenm1); -void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, - INT calcPreEcho, - INT numPb, - INT maxAllowedIncreaseFactor, - FIXP_SGL minRemainingThresholdFactor, - FIXP_DBL *pbThreshold, - INT mdctScale, - INT *mdctScalenm1); +void FDKaacEnc_PreEchoControl(FIXP_DBL *pbThresholdNm1, INT calcPreEcho, + INT numPb, INT maxAllowedIncreaseFactor, + FIXP_SGL minRemainingThresholdFactor, + FIXP_DBL *pbThreshold, INT mdctScale, + INT *mdctScalenm1); #endif - diff --git a/libAACenc/src/psy_configuration.cpp b/libAACenc/src/psy_configuration.cpp index 9a72c68..eef90bc 100644 --- a/libAACenc/src/psy_configuration.cpp +++ b/libAACenc/src/psy_configuration.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Psychoaccoustic configuration + Description: Psychoaccoustic configuration -******************************************************************************/ +*******************************************************************************/ #include "psy_configuration.h" #include "adj_thr.h" @@ -96,15 +108,14 @@ amm-info@iis.fraunhofer.de #include "FDK_trigFcts.h" -typedef struct{ - LONG sampleRate; - const SFB_PARAM_LONG *paramLong; - const SFB_PARAM_SHORT *paramShort; -}SFB_INFO_TAB; - +typedef struct { + LONG sampleRate; + const SFB_PARAM_LONG *paramLong; + const SFB_PARAM_SHORT *paramShort; +} SFB_INFO_TAB; static const SFB_INFO_TAB sfbInfoTab[] = { - {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128}, + {8000, &p_FDKaacEnc_8000_long_1024, &p_FDKaacEnc_8000_short_128}, {11025, &p_FDKaacEnc_11025_long_1024, &p_FDKaacEnc_11025_short_128}, {12000, &p_FDKaacEnc_12000_long_1024, &p_FDKaacEnc_12000_short_128}, {16000, &p_FDKaacEnc_16000_long_1024, &p_FDKaacEnc_16000_short_128}, @@ -121,108 +132,81 @@ static const SFB_INFO_TAB sfbInfoTab[] = { /* 22050 and 24000 Hz */ static const SFB_PARAM_LONG p_22050_long_512 = { - 31, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 8, 8, 8, 12, 12, 12, 16, 20, 24, - 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32} -}; + 31, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, + 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 32000 Hz */ static const SFB_PARAM_LONG p_32000_long_512 = { 37, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, - 32, 32, 32, 32, 32, 32, 32} -}; + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, + 12, 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 32, 32, 32, 32, 32, 32, 32}}; /* 44100 Hz */ static const SFB_PARAM_LONG p_44100_long_512 = { - 36, - {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, - 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, - 32, 32, 32, 32, 32, 52} -}; + 36, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, + 8, 8, 12, 12, 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 52}}; static const SFB_INFO_TAB sfbInfoTabLD512[] = { - { 8000, &p_22050_long_512, NULL}, - {11025, &p_22050_long_512, NULL}, - {12000, &p_22050_long_512, NULL}, - {16000, &p_22050_long_512, NULL}, - {22050, &p_22050_long_512, NULL}, - {24000, &p_22050_long_512, NULL}, - {32000, &p_32000_long_512, NULL}, - {44100, &p_44100_long_512, NULL}, - {48000, &p_44100_long_512, NULL}, - {64000, &p_44100_long_512, NULL}, - {88200, &p_44100_long_512, NULL}, - {96000, &p_44100_long_512, NULL}, - + {8000, &p_22050_long_512, NULL}, {11025, &p_22050_long_512, NULL}, + {12000, &p_22050_long_512, NULL}, {16000, &p_22050_long_512, NULL}, + {22050, &p_22050_long_512, NULL}, {24000, &p_22050_long_512, NULL}, + {32000, &p_32000_long_512, NULL}, {44100, &p_44100_long_512, NULL}, + {48000, &p_44100_long_512, NULL}, {64000, &p_44100_long_512, NULL}, + {88200, &p_44100_long_512, NULL}, {96000, &p_44100_long_512, NULL}, + {128000, &p_44100_long_512, NULL}, {176400, &p_44100_long_512, NULL}, + {192000, &p_44100_long_512, NULL}, {256000, &p_44100_long_512, NULL}, + {352800, &p_44100_long_512, NULL}, {384000, &p_44100_long_512, NULL}, }; - /* 22050 and 24000 Hz */ static const SFB_PARAM_LONG p_22050_long_480 = { - 30, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 8, 8, 8, 12, 12, 12, 16, 20, 24, - 28, 32, 32, 32, 32, 32, 32, 32, 32, 32} -}; + 30, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, + 12, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 32000 Hz */ static const SFB_PARAM_LONG p_32000_long_480 = { - 37, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, - 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, - 32, 32, 32, 32, 32, 32, 32} -}; + 37, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, + 8, 8, 8, 12, 12, 12, 16, 16, 20, 24, 32, 32, 32, 32, 32, 32, 32, 32}}; /* 44100 Hz */ static const SFB_PARAM_LONG p_44100_long_480 = { - 35, - { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 8, 8, 8, 8, 8, 12, - 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, - 32, 32, 32, 32, 48} -}; + 35, {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, + 8, 12, 12, 12, 12, 12, 16, 16, 24, 28, 32, 32, 32, 32, 32, 32, 48}}; static const SFB_INFO_TAB sfbInfoTabLD480[] = { - { 8000, &p_22050_long_480, NULL}, - {11025, &p_22050_long_480, NULL}, - {12000, &p_22050_long_480, NULL}, - {16000, &p_22050_long_480, NULL}, - {22050, &p_22050_long_480, NULL}, - {24000, &p_22050_long_480, NULL}, - {32000, &p_32000_long_480, NULL}, - {44100, &p_44100_long_480, NULL}, - {48000, &p_44100_long_480, NULL}, - {64000, &p_44100_long_480, NULL}, - {88200, &p_44100_long_480, NULL}, - {96000, &p_44100_long_480, NULL}, - + {8000, &p_22050_long_480, NULL}, {11025, &p_22050_long_480, NULL}, + {12000, &p_22050_long_480, NULL}, {16000, &p_22050_long_480, NULL}, + {22050, &p_22050_long_480, NULL}, {24000, &p_22050_long_480, NULL}, + {32000, &p_32000_long_480, NULL}, {44100, &p_44100_long_480, NULL}, + {48000, &p_44100_long_480, NULL}, {64000, &p_44100_long_480, NULL}, + {88200, &p_44100_long_480, NULL}, {96000, &p_44100_long_480, NULL}, + {128000, &p_44100_long_480, NULL}, {176400, &p_44100_long_480, NULL}, + {192000, &p_44100_long_480, NULL}, {256000, &p_44100_long_480, NULL}, + {352800, &p_44100_long_480, NULL}, {384000, &p_44100_long_480, NULL}, }; /* Fixed point precision definitions */ -#define Q_BARCVAL (25) - -static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, INT granuleLength, INT *sfbOffset, INT *sfbCnt) -{ - INT i, specStartOffset = 0; - const UCHAR* sfbWidth = NULL; +#define Q_BARCVAL (25) + +AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(const LONG sampleRate, + const INT blockType, + const INT granuleLength, + INT *const sfbOffset, + INT *const sfbCnt) { + INT i, specStartOffset = 0; + INT granuleLengthWindow = granuleLength; + const UCHAR *sfbWidth = NULL; const SFB_INFO_TAB *sfbInfo = NULL; int size; /* select table */ - switch(granuleLength) { + switch (granuleLength) { case 1024: - case 960: + case 960: sfbInfo = sfbInfoTab; - size = (INT)(sizeof(sfbInfoTab)/sizeof(SFB_INFO_TAB)); + size = (INT)(sizeof(sfbInfoTab) / sizeof(SFB_INFO_TAB)); break; case 512: sfbInfo = sfbInfoTabLD512; @@ -236,20 +220,20 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, return AAC_ENC_INVALID_FRAME_LENGTH; } - for(i = 0; i < size; i++){ - if(sfbInfo[i].sampleRate == sampleRate){ - switch(blockType){ - case LONG_WINDOW: - case START_WINDOW: - case STOP_WINDOW: - sfbWidth = sfbInfo[i].paramLong->sfbWidth; - *sfbCnt = sfbInfo[i].paramLong->sfbCnt; - break; - case SHORT_WINDOW: - sfbWidth = sfbInfo[i].paramShort->sfbWidth; - *sfbCnt = sfbInfo[i].paramShort->sfbCnt; - granuleLength /= TRANS_FAC; - break; + for (i = 0; i < size; i++) { + if (sfbInfo[i].sampleRate == sampleRate) { + switch (blockType) { + case LONG_WINDOW: + case START_WINDOW: + case STOP_WINDOW: + sfbWidth = sfbInfo[i].paramLong->sfbWidth; + *sfbCnt = sfbInfo[i].paramLong->sfbCnt; + break; + case SHORT_WINDOW: + sfbWidth = sfbInfo[i].paramShort->sfbWidth; + *sfbCnt = sfbInfo[i].paramShort->sfbCnt; + granuleLengthWindow /= TRANS_FAC; + break; } break; } @@ -261,21 +245,19 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, /* calc sfb offsets */ - for(i = 0; i < *sfbCnt; i++){ - sfbOffset[i] = specStartOffset; - specStartOffset += sfbWidth[i]; - if (specStartOffset >= granuleLength) { - i++; - break; - } + for (i = 0; i < *sfbCnt; i++) { + sfbOffset[i] = specStartOffset; + specStartOffset += sfbWidth[i]; + if (specStartOffset >= granuleLengthWindow) { + i++; + break; + } } - *sfbCnt = fixMin(i,*sfbCnt); - sfbOffset[*sfbCnt] = fixMin(specStartOffset,granuleLength); - + *sfbCnt = fixMin(i, *sfbCnt); + sfbOffset[*sfbCnt] = fixMin(specStartOffset, granuleLengthWindow); return AAC_ENC_OK; } - /***************************************************************************** functionname: FDKaacEnc_BarcLineValue @@ -285,51 +267,53 @@ static AAC_ENCODER_ERROR FDKaacEnc_initSfbTable(LONG sampleRate, INT blockType, output: *****************************************************************************/ -static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, LONG samplingFreq) -{ - - FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ - FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */ - FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */ - FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */ - FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39 - - FIXP_DBL center_freq, x1, x2; - FIXP_DBL bvalFFTLine, atan1, atan2; - - /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000 */ - /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in q28 */ - /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in q25 */ - - center_freq = fftLine * samplingFreq; /* q11 or q8 */ - - switch (noOfLines) { - case 1024: - center_freq = center_freq << 2; /* q13 */ - break; - case 128: - center_freq = center_freq << 5; /* q13 */ - break; - case 512: - center_freq = (fftLine * samplingFreq) << 3; // q13 - break; - case 480: - center_freq = fMult(center_freq, INV480) << 4; // q13 - break; - default: - center_freq = (FIXP_DBL)0; - } - - x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ - x2 = fMult(center_freq, PZZZ76) << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ +static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, + LONG samplingFreq) { + FIXP_DBL FOURBY3EM4 = (FIXP_DBL)0x45e7b273; /* 4.0/3 * 0.0001 in q43 */ + FIXP_DBL PZZZ76 = (FIXP_DBL)0x639d5e4a; /* 0.00076 in q41 */ + FIXP_DBL ONE3P3 = (FIXP_DBL)0x35333333; /* 13.3 in q26 */ + FIXP_DBL THREEP5 = (FIXP_DBL)0x1c000000; /* 3.5 in q27 */ + FIXP_DBL INV480 = (FIXP_DBL)0x44444444; // 1/480 in q39 + + FIXP_DBL center_freq, x1, x2; + FIXP_DBL bvalFFTLine, atan1, atan2; + + /* Theoritical maximum of center_freq (samp_freq*0.5) is 96khz * 0.5 = 48000 + */ + /* Theoritical maximum of x1 is 1.3333333e-4f * center_freq = 6.4, can keep in + * q28 */ + /* Theoritical maximum of x2 is 0.00076f * center_freq = 36.48, can keep in + * q25 */ + + center_freq = fftLine * samplingFreq; /* q11 or q8 */ + + switch (noOfLines) { + case 1024: + center_freq = center_freq << 2; /* q13 */ + break; + case 128: + center_freq = center_freq << 5; /* q13 */ + break; + case 512: + center_freq = (fftLine * samplingFreq) << 3; // q13 + break; + case 480: + center_freq = fMult(center_freq, INV480) << 4; // q13 + break; + default: + center_freq = (FIXP_DBL)0; + } - atan1 = fixp_atan(x1); - atan2 = fixp_atan(x2); + x1 = fMult(center_freq, FOURBY3EM4); /* q13 * q43 - (DFRACT_BITS-1) = q25 */ + x2 = fMult(center_freq, PZZZ76) + << 2; /* q13 * q41 - (DFRACT_BITS-1) + 2 = q25 */ - /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ - bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); - return(bvalFFTLine); + atan1 = fixp_atan(x1); + atan2 = fixp_atan(x2); + /* q25 (q26 * q30 - (DFRACT_BITS-1)) + q25 (q27 * q30 * q30) */ + bvalFFTLine = fMult(ONE3P3, atan2) + fMult(THREEP5, fMult(atan1, atan1)); + return (bvalFFTLine); } /* @@ -338,320 +322,306 @@ static FIXP_DBL FDKaacEnc_BarcLineValue(INT noOfLines, INT fftLine, LONG samplin might need to be configurable to e.g. 24 bit PCM Input or a lower resolution for low bit rates */ -static void FDKaacEnc_InitMinPCMResolution(int numPb, - int *pbOffset, - FIXP_DBL *sfbPCMquantThreshold) -{ - /* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY * FDKpow(2,PCM_QUANT_THR_SCALE) */ - #define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) - - for( int i = 0; i < numPb; i++ ) { - sfbPCMquantThreshold[i] = (pbOffset[i+1] - pbOffset[i]) * PCM_QUANT_NOISE; +static void FDKaacEnc_InitMinPCMResolution(int numPb, int *pbOffset, + FIXP_DBL *sfbPCMquantThreshold) { +/* PCM_QUANT_NOISE = FDKpow(10.0f, - 20.f / 10.0f) * ABS_LOW * NORM_PCM_ENERGY * + * FDKpow(2,PCM_QUANT_THR_SCALE) */ +#define PCM_QUANT_NOISE ((FIXP_DBL)0x00547062) + + for (int i = 0; i < numPb; i++) { + sfbPCMquantThreshold[i] = (pbOffset[i + 1] - pbOffset[i]) * PCM_QUANT_NOISE; } } -static FIXP_DBL getMaskFactor( - const FIXP_DBL dbVal_fix, - const INT dbVal_e, - const FIXP_DBL ten_fix, - const INT ten_e - ) -{ - INT q_msk; - FIXP_DBL mask_factor; +static FIXP_DBL getMaskFactor(const FIXP_DBL dbVal_fix, const INT dbVal_e, + const FIXP_DBL ten_fix, const INT ten_e) { + INT q_msk; + FIXP_DBL mask_factor; - mask_factor = fPow(ten_fix, DFRACT_BITS-1-ten_e, -dbVal_fix, DFRACT_BITS-1-dbVal_e, &q_msk); - q_msk = fixMin(DFRACT_BITS-1,fixMax(-(DFRACT_BITS-1),q_msk)); + mask_factor = fPow(ten_fix, DFRACT_BITS - 1 - ten_e, -dbVal_fix, + DFRACT_BITS - 1 - dbVal_e, &q_msk); + q_msk = fixMin(DFRACT_BITS - 1, fixMax(-(DFRACT_BITS - 1), q_msk)); - if ( (q_msk>0) && (mask_factor>(FIXP_DBL)MAXVAL_DBL>>q_msk) ) { - mask_factor = (FIXP_DBL)MAXVAL_DBL; - } - else { - mask_factor = scaleValue(mask_factor, q_msk); - } + if ((q_msk > 0) && (mask_factor > (FIXP_DBL)MAXVAL_DBL >> q_msk)) { + mask_factor = (FIXP_DBL)MAXVAL_DBL; + } else { + mask_factor = scaleValue(mask_factor, q_msk); + } - return (mask_factor); + return (mask_factor); } -static void FDKaacEnc_initSpreading(INT numPb, - FIXP_DBL *pbBarcValue, - FIXP_DBL *pbMaskLoFactor, - FIXP_DBL *pbMaskHiFactor, - FIXP_DBL *pbMaskLoFactorSprEn, - FIXP_DBL *pbMaskHiFactorSprEn, - const LONG bitrate, - const INT blockType) +static void FDKaacEnc_initSpreading(INT numPb, FIXP_DBL *pbBarcValue, + FIXP_DBL *pbMaskLoFactor, + FIXP_DBL *pbMaskHiFactor, + FIXP_DBL *pbMaskLoFactorSprEn, + FIXP_DBL *pbMaskHiFactorSprEn, + const LONG bitrate, const INT blockType) { - INT i; - FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; - - FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ - FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ - FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ - FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ - FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ - FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */ - - if (blockType != SHORT_WINDOW) - { - MASKLOWSPREN = MASKLOWSPRENLONG; - MASKHIGHSPREN = (bitrate>20000)?MASKHIGHSPRENLONG:MASKHIGHSPRENLONGLOWBR; - } - else - { - MASKLOWSPREN = MASKLOWSPRENSHORT; - MASKHIGHSPREN = MASKHIGHSPRENSHORT; - } + INT i; + FIXP_DBL MASKLOWSPREN, MASKHIGHSPREN; + + FIXP_DBL MASKHIGH = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL MASKLOW = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ + FIXP_DBL MASKLOWSPRENLONG = (FIXP_DBL)0x60000000; /* 3.0 in q29 */ + FIXP_DBL MASKHIGHSPRENLONG = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ + FIXP_DBL MASKHIGHSPRENLONGLOWBR = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL MASKLOWSPRENSHORT = (FIXP_DBL)0x40000000; /* 2.0 in q29 */ + FIXP_DBL MASKHIGHSPRENSHORT = (FIXP_DBL)0x30000000; /* 1.5 in q29 */ + FIXP_DBL TEN = (FIXP_DBL)0x50000000; /* 10.0 in q27 */ + + if (blockType != SHORT_WINDOW) { + MASKLOWSPREN = MASKLOWSPRENLONG; + MASKHIGHSPREN = + (bitrate > 20000) ? MASKHIGHSPRENLONG : MASKHIGHSPRENLONGLOWBR; + } else { + MASKLOWSPREN = MASKLOWSPRENSHORT; + MASKHIGHSPREN = MASKHIGHSPRENSHORT; + } - for(i=0; i<numPb; i++) - { - if (i > 0) - { - pbMaskHiFactor[i] = getMaskFactor( - fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskLoFactor[i-1] = getMaskFactor( - fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskHiFactorSprEn[i] = getMaskFactor( - fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - - pbMaskLoFactorSprEn[i-1] = getMaskFactor( - fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i-1])), 23, - TEN, 27); - } - else - { - pbMaskHiFactor[i] = (FIXP_DBL)0; - pbMaskLoFactor[numPb-1] = (FIXP_DBL)0; - pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; - pbMaskLoFactorSprEn[numPb-1] = (FIXP_DBL)0; - } + for (i = 0; i < numPb; i++) { + if (i > 0) { + pbMaskHiFactor[i] = getMaskFactor( + fMult(MASKHIGH, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); + + pbMaskLoFactor[i - 1] = getMaskFactor( + fMult(MASKLOW, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, 27); + + pbMaskHiFactorSprEn[i] = getMaskFactor( + fMult(MASKHIGHSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, + 27); + + pbMaskLoFactorSprEn[i - 1] = getMaskFactor( + fMult(MASKLOWSPREN, (pbBarcValue[i] - pbBarcValue[i - 1])), 23, TEN, + 27); + } else { + pbMaskHiFactor[i] = (FIXP_DBL)0; + pbMaskLoFactor[numPb - 1] = (FIXP_DBL)0; + pbMaskHiFactorSprEn[i] = (FIXP_DBL)0; + pbMaskLoFactorSprEn[numPb - 1] = (FIXP_DBL)0; } + } } -static void FDKaacEnc_initBarcValues(INT numPb, - INT *pbOffset, - INT numLines, - INT samplingFrequency, - FIXP_DBL *pbBval) -{ - INT i; - FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ - - for(i=0; i<numPb; i++) - { - FIXP_DBL v1, v2, cur_bark; - v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency); - v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i+1], samplingFrequency); - cur_bark = (v1 >> 1) + (v2 >> 1); - pbBval[i] = fixMin(cur_bark, MAX_BARC); - } +static void FDKaacEnc_initBarcValues(INT numPb, INT *pbOffset, INT numLines, + INT samplingFrequency, FIXP_DBL *pbBval) { + INT i; + FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ + + for (i = 0; i < numPb; i++) { + FIXP_DBL v1, v2, cur_bark; + v1 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i], samplingFrequency); + v2 = FDKaacEnc_BarcLineValue(numLines, pbOffset[i + 1], samplingFrequency); + cur_bark = (v1 >> 1) + (v2 >> 1); + pbBval[i] = fixMin(cur_bark, MAX_BARC); + } } -static void FDKaacEnc_initMinSnr(const LONG bitrate, - const LONG samplerate, - const INT numLines, - const INT *sfbOffset, - const INT sfbActive, - const INT blockType, - FIXP_DBL *sfbMinSnrLdData) -{ - INT sfb; - - /* Fix conversion variables */ - INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; - INT qtmp, qsnr, sfbWidth; - - FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ - FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ - FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ - FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */ - FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */ - FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */ - FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */ - - FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; - FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; - - /* relative number of active barks */ - barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfbActive], samplerate), MAX_BARC), - MAX_BARCP1, &qbfac); - - qbfac = DFRACT_BITS-1-qbfac; - - pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); - qperwin = DFRACT_BITS-1-qperwin; - pePerWindow = fMult(pePerWindow, BITS2PEFAC); qperwin = qperwin + 30 - (DFRACT_BITS-1); - pePerWindow = fMult(pePerWindow, PERS2P4); qperwin = qperwin + 36 - (DFRACT_BITS-1); - - switch (numLines) { - case 1024: - qperwin = qperwin - 10; - break; - case 128: - qperwin = qperwin - 7; - break; - case 512: - qperwin = qperwin - 9; - break; - case 480: - qperwin = qperwin - 9; - pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f/512.f)); - break; - } +static void FDKaacEnc_initMinSnr(const LONG bitrate, const LONG samplerate, + const INT numLines, const INT *sfbOffset, + const INT sfbActive, const INT blockType, + FIXP_DBL *sfbMinSnrLdData) { + INT sfb; + + /* Fix conversion variables */ + INT qbfac, qperwin, qdiv, qpeprt_const, qpeprt; + INT qtmp, qsnr, sfbWidth; + + FIXP_DBL MAX_BARC = (FIXP_DBL)0x30000000; /* 24.0 in q25 */ + FIXP_DBL MAX_BARCP1 = (FIXP_DBL)0x32000000; /* 25.0 in q25 */ + FIXP_DBL BITS2PEFAC = (FIXP_DBL)0x4b851eb8; /* 1.18 in q30 */ + FIXP_DBL PERS2P4 = (FIXP_DBL)0x624dd2f2; /* 0.024 in q36 */ + FIXP_DBL ONEP5 = (FIXP_DBL)0x60000000; /* 1.5 in q30 */ + FIXP_DBL MAX_SNR = (FIXP_DBL)0x33333333; /* 0.8 in q30 */ + FIXP_DBL MIN_SNR = (FIXP_DBL)0x003126e9; /* 0.003 in q30 */ + + FIXP_DBL barcFactor, pePerWindow, pePart, barcWidth; + FIXP_DBL pePart_const, tmp, snr, one_qsnr, one_point5; + + /* relative number of active barks */ + barcFactor = fDivNorm(fixMin(FDKaacEnc_BarcLineValue( + numLines, sfbOffset[sfbActive], samplerate), + MAX_BARC), + MAX_BARCP1, &qbfac); + + qbfac = DFRACT_BITS - 1 - qbfac; + + pePerWindow = fDivNorm(bitrate, samplerate, &qperwin); + qperwin = DFRACT_BITS - 1 - qperwin; + pePerWindow = fMult(pePerWindow, BITS2PEFAC); + qperwin = qperwin + 30 - (DFRACT_BITS - 1); + pePerWindow = fMult(pePerWindow, PERS2P4); + qperwin = qperwin + 36 - (DFRACT_BITS - 1); + + switch (numLines) { + case 1024: + qperwin = qperwin - 10; + break; + case 128: + qperwin = qperwin - 7; + break; + case 512: + qperwin = qperwin - 9; + break; + case 480: + qperwin = qperwin - 9; + pePerWindow = fMult(pePerWindow, FL2FXCONST_DBL(480.f / 512.f)); + break; + } - /* for short blocks it is assumed that more bits are available */ - if (blockType == SHORT_WINDOW) - { - pePerWindow = fMult(pePerWindow, ONEP5); - qperwin = qperwin + 30 - (DFRACT_BITS-1); - } - pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); qpeprt_const = qperwin - qbfac + DFRACT_BITS-1-qdiv; + /* for short blocks it is assumed that more bits are available */ + if (blockType == SHORT_WINDOW) { + pePerWindow = fMult(pePerWindow, ONEP5); + qperwin = qperwin + 30 - (DFRACT_BITS - 1); + } + pePart_const = fDivNorm(pePerWindow, barcFactor, &qdiv); + qpeprt_const = qperwin - qbfac + DFRACT_BITS - 1 - qdiv; - for (sfb = 0; sfb < sfbActive; sfb++) - { - barcWidth = FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb+1], samplerate) - - FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); + for (sfb = 0; sfb < sfbActive; sfb++) { + barcWidth = + FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb + 1], samplerate) - + FDKaacEnc_BarcLineValue(numLines, sfbOffset[sfb], samplerate); - /* adapt to sfb bands */ - pePart = fMult(pePart_const, barcWidth); qpeprt = qpeprt_const + 25 - (DFRACT_BITS-1); + /* adapt to sfb bands */ + pePart = fMult(pePart_const, barcWidth); + qpeprt = qpeprt_const + 25 - (DFRACT_BITS - 1); - /* pe -> snr calculation */ - sfbWidth = (sfbOffset[sfb+1] - sfbOffset[sfb]); - pePart = fDivNorm(pePart, sfbWidth, &qdiv); qpeprt += DFRACT_BITS-1-qdiv; + /* pe -> snr calculation */ + sfbWidth = (sfbOffset[sfb + 1] - sfbOffset[sfb]); + pePart = fDivNorm(pePart, sfbWidth, &qdiv); + qpeprt += DFRACT_BITS - 1 - qdiv; - tmp = f2Pow(pePart, DFRACT_BITS-1-qpeprt, &qtmp); - qtmp = DFRACT_BITS-1-qtmp; + tmp = f2Pow(pePart, DFRACT_BITS - 1 - qpeprt, &qtmp); + qtmp = DFRACT_BITS - 1 - qtmp; - /* Subtract 1.5 */ - qsnr = fixMin(qtmp, 30); - tmp = tmp >> (qtmp - qsnr); + /* Subtract 1.5 */ + qsnr = fixMin(qtmp, 30); + tmp = tmp >> (qtmp - qsnr); - if((30+1-qsnr) > (DFRACT_BITS-1)) - one_point5 = (FIXP_DBL)0; - else - one_point5 = (FIXP_DBL)(ONEP5 >> (30+1-qsnr)); + if ((30 + 1 - qsnr) > (DFRACT_BITS - 1)) + one_point5 = (FIXP_DBL)0; + else + one_point5 = (FIXP_DBL)(ONEP5 >> (30 + 1 - qsnr)); - snr = (tmp>>1) - (one_point5); qsnr -= 1; + snr = (tmp >> 1) - (one_point5); + qsnr -= 1; - /* max(snr, 1.0) */ - if(qsnr > 0) - one_qsnr = (FIXP_DBL)(1 << qsnr); - else - one_qsnr = (FIXP_DBL)0; + /* max(snr, 1.0) */ + if (qsnr > 0) + one_qsnr = (FIXP_DBL)(1 << qsnr); + else + one_qsnr = (FIXP_DBL)0; - snr = fixMax(one_qsnr, snr); + snr = fixMax(one_qsnr, snr); - /* 1/snr */ - snr = fDivNorm(one_qsnr, snr, &qsnr); - qsnr = DFRACT_BITS-1-qsnr; - snr = (qsnr > 30)? (snr>>(qsnr-30)):snr; + /* 1/snr */ + snr = fDivNorm(one_qsnr, snr, &qsnr); + qsnr = DFRACT_BITS - 1 - qsnr; + snr = (qsnr > 30) ? (snr >> (qsnr - 30)) : snr; - /* upper limit is -1 dB */ - snr = (snr > MAX_SNR) ? MAX_SNR : snr; + /* upper limit is -1 dB */ + snr = (snr > MAX_SNR) ? MAX_SNR : snr; - /* lower limit is -25 dB */ - snr = (snr < MIN_SNR) ? MIN_SNR : snr; - snr = snr << 1; + /* lower limit is -25 dB */ + snr = (snr < MIN_SNR) ? MIN_SNR : snr; + snr = snr << 1; - sfbMinSnrLdData[sfb] = CalcLdData(snr); - } + sfbMinSnrLdData[sfb] = CalcLdData(snr); + } } -AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, - INT samplerate, - INT bandwidth, - INT blocktype, - INT granuleLength, - INT useIS, +AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate, + INT bandwidth, INT blocktype, + INT granuleLength, INT useIS, + INT useMS, PSY_CONFIGURATION *psyConf, - FB_TYPE filterbank) -{ - AAC_ENCODER_ERROR ErrorStatus; - INT sfb; - FIXP_DBL sfbBarcVal[MAX_SFB]; - const INT frameLengthLong = granuleLength; - const INT frameLengthShort = granuleLength/TRANS_FAC; - - FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); - psyConf->granuleLength = granuleLength; - psyConf->filterbank = filterbank; - - psyConf->allowIS = (useIS) && ( (bitrate/bandwidth) < 5 ); - - /* init sfb table */ - ErrorStatus = FDKaacEnc_initSfbTable(samplerate,blocktype,granuleLength,psyConf->sfbOffset,&psyConf->sfbCnt); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - /* calculate barc values for each pb */ - FDKaacEnc_initBarcValues(psyConf->sfbCnt, - psyConf->sfbOffset, - psyConf->sfbOffset[psyConf->sfbCnt], - samplerate, - sfbBarcVal); - - FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, - psyConf->sfbOffset, - psyConf->sfbPcmQuantThreshold); - - /* calculate spreading function */ - FDKaacEnc_initSpreading(psyConf->sfbCnt, - sfbBarcVal, - psyConf->sfbMaskLowFactor, - psyConf->sfbMaskHighFactor, - psyConf->sfbMaskLowFactorSprEn, - psyConf->sfbMaskHighFactorSprEn, - bitrate, - blocktype); - - /* init ratio */ - - psyConf->maxAllowedIncreaseFactor = 2; /* integer */ - psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; /* FL2FXCONST_SGL(0.01f); */ /* fract */ - - psyConf->clipEnergy = (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ - - if (blocktype!=SHORT_WINDOW) { - psyConf->lowpassLine = (INT)((2*bandwidth*frameLengthLong)/samplerate); - psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; - } - else { - psyConf->lowpassLine = (INT)((2*bandwidth*frameLengthShort)/samplerate); - psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ - /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ - psyConf->clipEnergy >>= 6; - } + FB_TYPE filterbank) { + AAC_ENCODER_ERROR ErrorStatus; + INT sfb; + FIXP_DBL sfbBarcVal[MAX_SFB]; + const INT frameLengthLong = granuleLength; + const INT frameLengthShort = granuleLength / TRANS_FAC; + INT downscaleFactor = 1; + + switch (granuleLength) { + case 256: + case 240: + downscaleFactor = 2; + break; + case 128: + case 120: + downscaleFactor = 4; + break; + default: + downscaleFactor = 1; + break; + } - for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ - if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) - break; - } - psyConf->sfbActive = FDKmax(sfb, 1); + FDKmemclear(psyConf, sizeof(PSY_CONFIGURATION)); + psyConf->granuleLength = granuleLength; + psyConf->filterbank = filterbank; + + psyConf->allowIS = (useIS) && ((bitrate / bandwidth) < 5); + psyConf->allowMS = useMS; + + /* init sfb table */ + ErrorStatus = FDKaacEnc_initSfbTable(samplerate * downscaleFactor, blocktype, + granuleLength * downscaleFactor, + psyConf->sfbOffset, &psyConf->sfbCnt); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + + /* calculate barc values for each pb */ + FDKaacEnc_initBarcValues(psyConf->sfbCnt, psyConf->sfbOffset, + psyConf->sfbOffset[psyConf->sfbCnt], samplerate, + sfbBarcVal); + + FDKaacEnc_InitMinPCMResolution(psyConf->sfbCnt, psyConf->sfbOffset, + psyConf->sfbPcmQuantThreshold); + + /* calculate spreading function */ + FDKaacEnc_initSpreading(psyConf->sfbCnt, sfbBarcVal, + psyConf->sfbMaskLowFactor, psyConf->sfbMaskHighFactor, + psyConf->sfbMaskLowFactorSprEn, + psyConf->sfbMaskHighFactorSprEn, bitrate, blocktype); + + /* init ratio */ + + psyConf->maxAllowedIncreaseFactor = 2; /* integer */ + psyConf->minRemainingThresholdFactor = (FIXP_SGL)0x0148; + /* FL2FXCONST_SGL(0.01f); */ /* fract */ + + psyConf->clipEnergy = + (FIXP_DBL)0x773593ff; /* FL2FXCONST_DBL(1.0e9*NORM_PCM_ENERGY); */ + + if (blocktype != SHORT_WINDOW) { + psyConf->lowpassLine = + (INT)((2 * bandwidth * frameLengthLong) / samplerate); + psyConf->lowpassLineLFE = LFE_LOWPASS_LINE; + } else { + psyConf->lowpassLine = + (INT)((2 * bandwidth * frameLengthShort) / samplerate); + psyConf->lowpassLineLFE = 0; /* LFE only in lonf blocks */ + /* psyConf->clipEnergy /= (TRANS_FAC * TRANS_FAC); */ + psyConf->clipEnergy >>= 6; + } - for (sfb = 0; sfb < psyConf->sfbCnt; sfb++){ - if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) - break; - } - psyConf->sfbActiveLFE = sfb; - psyConf->sfbActive = FDKmax(psyConf->sfbActive, psyConf->sfbActiveLFE); - - /* calculate minSnr */ - FDKaacEnc_initMinSnr(bitrate, - samplerate, - psyConf->sfbOffset[psyConf->sfbCnt], - psyConf->sfbOffset, - psyConf->sfbActive, - blocktype, - psyConf->sfbMinSnrLdData); - - return AAC_ENC_OK; -} + for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { + if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLine) break; + } + psyConf->sfbActive = fMax(sfb, 1); + for (sfb = 0; sfb < psyConf->sfbCnt; sfb++) { + if (psyConf->sfbOffset[sfb] >= psyConf->lowpassLineLFE) break; + } + psyConf->sfbActiveLFE = sfb; + psyConf->sfbActive = fMax(psyConf->sfbActive, psyConf->sfbActiveLFE); + + /* calculate minSnr */ + FDKaacEnc_initMinSnr(bitrate, samplerate * downscaleFactor, + psyConf->sfbOffset[psyConf->sfbCnt], psyConf->sfbOffset, + psyConf->sfbActive, blocktype, psyConf->sfbMinSnrLdData); + + return AAC_ENC_OK; +} diff --git a/libAACenc/src/psy_configuration.h b/libAACenc/src/psy_configuration.h index 3629246..52b2887 100644 --- a/libAACenc/src/psy_configuration.h +++ b/libAACenc/src/psy_configuration.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic configuration + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic configuration -#ifndef _PSY_CONFIGURATION_H -#define _PSY_CONFIGURATION_H +*******************************************************************************/ +#ifndef PSY_CONFIGURATION_H +#define PSY_CONFIGURATION_H #include "aacenc.h" #include "common_fix.h" @@ -99,67 +110,62 @@ amm-info@iis.fraunhofer.de #include "aacenc_tns.h" #include "aacenc_pns.h" -#define THR_SHIFTBITS 4 -#define PCM_QUANT_THR_SCALE 16 - -#define C_RATIO (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */ +#define THR_SHIFTBITS 4 +#define PCM_QUANT_THR_SCALE 16 +#define BITS_PER_LINE_SHIFT 3 -typedef struct{ +#define C_RATIO \ + (FIXP_DBL)0x02940a10 /* FL2FXCONST_DBL(0.001258925f) << THR_SHIFTBITS; */ /* pow(10.0f, -(29.0f/10.0f)) */ - INT sfbCnt; /* number of existing sf bands */ - INT sfbActive; /* number of sf bands containing energy after lowpass */ +typedef struct { + INT sfbCnt; /* number of existing sf bands */ + INT sfbActive; /* number of sf bands containing energy after lowpass */ INT sfbActiveLFE; - INT sfbOffset[MAX_SFB+1]; + INT sfbOffset[MAX_SFB + 1]; - INT filterbank; /* LC, LD or ELD */ + INT filterbank; /* LC, LD or ELD */ - FIXP_DBL sfbPcmQuantThreshold[MAX_SFB]; + FIXP_DBL sfbPcmQuantThreshold[MAX_SFB]; - INT maxAllowedIncreaseFactor; /* preecho control */ - FIXP_SGL minRemainingThresholdFactor; + INT maxAllowedIncreaseFactor; /* preecho control */ + FIXP_SGL minRemainingThresholdFactor; - INT lowpassLine; - INT lowpassLineLFE; - FIXP_DBL clipEnergy; /* for level dependend tmn */ + INT lowpassLine; + INT lowpassLineLFE; + FIXP_DBL clipEnergy; /* for level dependend tmn */ - FIXP_DBL sfbMaskLowFactor[MAX_SFB]; - FIXP_DBL sfbMaskHighFactor[MAX_SFB]; + FIXP_DBL sfbMaskLowFactor[MAX_SFB]; + FIXP_DBL sfbMaskHighFactor[MAX_SFB]; - FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB]; - FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB]; + FIXP_DBL sfbMaskLowFactorSprEn[MAX_SFB]; + FIXP_DBL sfbMaskHighFactorSprEn[MAX_SFB]; - FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */ + FIXP_DBL sfbMinSnrLdData[MAX_SFB]; /* minimum snr (formerly known as bmax) */ TNS_CONFIG tnsConf; PNS_CONFIG pnsConf; - INT granuleLength; - INT allowIS; - -}PSY_CONFIGURATION; - - -typedef struct{ - UCHAR sfbCnt; /* Number of scalefactor bands */ - UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */ -}SFB_PARAM_LONG; - -typedef struct{ - UCHAR sfbCnt; /* Number of scalefactor bands */ - UCHAR sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */ -}SFB_PARAM_SHORT; - - -AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, - INT samplerate, - INT bandwidth, - INT blocktype, - INT granuleLength, - INT useIS, + INT granuleLength; + INT allowIS; + INT allowMS; +} PSY_CONFIGURATION; + +typedef struct { + UCHAR sfbCnt; /* Number of scalefactor bands */ + UCHAR sfbWidth[MAX_SFB_LONG]; /* Width of scalefactor bands for long blocks */ +} SFB_PARAM_LONG; + +typedef struct { + UCHAR sfbCnt; /* Number of scalefactor bands */ + UCHAR + sfbWidth[MAX_SFB_SHORT]; /* Width of scalefactor bands for short blocks */ +} SFB_PARAM_SHORT; + +AAC_ENCODER_ERROR FDKaacEnc_InitPsyConfiguration(INT bitrate, INT samplerate, + INT bandwidth, INT blocktype, + INT granuleLength, INT useIS, + INT useMS, PSY_CONFIGURATION *psyConf, FB_TYPE filterbank); -#endif /* _PSY_CONFIGURATION_H */ - - - +#endif /* PSY_CONFIGURATION_H */ diff --git a/libAACenc/src/psy_const.h b/libAACenc/src/psy_const.h index d9c9f43..c2d5304 100644 --- a/libAACenc/src/psy_const.h +++ b/libAACenc/src/psy_const.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,37 +90,34 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Global psychoaccoustic constants + Description: Global psychoaccoustic constants -******************************************************************************/ -#ifndef _PSYCONST_H -#define _PSYCONST_H +*******************************************************************************/ +#ifndef PSY_CONST_H +#define PSY_CONST_H -#define TRUE 1 +#define TRUE 1 #define FALSE 0 - #define TRANS_FAC 8 /* encoder short long ratio */ +#define TRANS_FAC 8 /* encoder short long ratio */ -#define FRAME_MAXLEN_SHORT ((1024)/TRANS_FAC) -#define FRAME_LEN_SHORT_128 ((1024)/TRANS_FAC) +#define FRAME_MAXLEN_SHORT ((1024) / TRANS_FAC) +#define FRAME_LEN_SHORT_128 ((1024) / TRANS_FAC) +#define FRAME_LEN_SHORT_120 (FRAME_LEN_LONG_960 / TRANS_FAC) /* Filterbank type*/ -enum FB_TYPE { - FB_LC = 0, - FB_LD = 1, - FB_ELD = 2 -}; +enum FB_TYPE { FB_LC = 0, FB_LD = 1, FB_ELD = 2 }; /* Block types */ #define N_BLOCKTYPES 6 -enum -{ +enum { LONG_WINDOW = 0, START_WINDOW, SHORT_WINDOW, @@ -119,42 +127,42 @@ enum }; /* Window shapes */ -enum -{ +enum { SINE_WINDOW = 0, - KBD_WINDOW = 1, + KBD_WINDOW = 1, LOL_WINDOW = 2 /* Low OverLap window shape for AAC-LD */ }; /* MS stuff */ -enum -{ - SI_MS_MASK_NONE = 0, - SI_MS_MASK_SOME = 1, - SI_MS_MASK_ALL = 2 -}; - - - #define MAX_NO_OF_GROUPS 4 - #define MAX_SFB_LONG 51 /* 51 for a memory optimized implementation, maybe 64 for convenient debugging */ - #define MAX_SFB_SHORT 15 /* 15 for a memory optimized implementation, maybe 16 for convenient debugging */ +enum { SI_MS_MASK_NONE = 0, SI_MS_MASK_SOME = 1, SI_MS_MASK_ALL = 2 }; -#define MAX_SFB (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */ -#define MAX_GROUPED_SFB (MAX_NO_OF_GROUPS*MAX_SFB_SHORT > MAX_SFB_LONG ? \ - MAX_NO_OF_GROUPS*MAX_SFB_SHORT : MAX_SFB_LONG) /* = 60 */ +#define MAX_NO_OF_GROUPS 4 +#define MAX_SFB_LONG \ + 51 /* 51 for a memory optimized implementation, maybe 64 for convenient \ + debugging */ +#define MAX_SFB_SHORT \ + 15 /* 15 for a memory optimized implementation, maybe 16 for convenient \ + debugging */ -#define MAX_INPUT_BUFFER_SIZE (2*(1024)) /* 2048 */ +#define MAX_SFB \ + (MAX_SFB_SHORT > MAX_SFB_LONG ? MAX_SFB_SHORT : MAX_SFB_LONG) /* = 51 */ +#define MAX_GROUPED_SFB \ + (MAX_NO_OF_GROUPS * MAX_SFB_SHORT > MAX_SFB_LONG \ + ? MAX_NO_OF_GROUPS * MAX_SFB_SHORT \ + : MAX_SFB_LONG) /* = 60 */ +#define MAX_INPUT_BUFFER_SIZE (2 * (1024)) /* 2048 */ -#define PCM_LEVEL 1.0f -#define NORM_PCM (PCM_LEVEL/32768.0f) -#define NORM_PCM_ENERGY (NORM_PCM*NORM_PCM) -#define LOG_NORM_PCM -15 +#define PCM_LEVEL 1.0f +#define NORM_PCM (PCM_LEVEL / 32768.0f) +#define NORM_PCM_ENERGY (NORM_PCM * NORM_PCM) +#define LOG_NORM_PCM -15 -#define TNS_PREDGAIN_SCALE (1000) +#define TNS_PREDGAIN_SCALE (1000) -#define LFE_LOWPASS_LINE 12 +#define LFE_LOWPASS_LINE 12 +#define LFE_LOWPASS_LINE_MIN 4 -#endif /* _PSYCONST_H */ +#endif /* PSY_CONST_H */ diff --git a/libAACenc/src/psy_data.h b/libAACenc/src/psy_data.h index 7183955..fc04734 100644 --- a/libAACenc/src/psy_data.h +++ b/libAACenc/src/psy_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,74 +90,80 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic data + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic data -#ifndef _PSY_DATA_H -#define _PSY_DATA_H +*******************************************************************************/ +#ifndef PSY_DATA_H +#define PSY_DATA_H #include "block_switch.h" +#include "mdct.h" /* Be careful with MAX_SFB_LONG as length of the .Long arrays. - * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a temporary storage for the regrouped - * short energies and thresholds between FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). - * The space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT ). - * However, this is not important if unions are used (which is not possible with pfloat). */ - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_THRESHOLD; - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_ENERGY; - -typedef shouldBeUnion{ - FIXP_DBL Long[MAX_GROUPED_SFB]; - FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_LD_ENERGY; - -typedef shouldBeUnion{ - INT Long[MAX_GROUPED_SFB]; - INT Short[TRANS_FAC][MAX_SFB_SHORT]; -}SFB_MAX_SCALE; - - -typedef struct{ - INT_PCM* psyInputBuffer; - FIXP_DBL overlapAddBuffer[1024]; - - BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */ - FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */ - INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */ - INT calcPreEcho; - INT isLFE; -}PSY_STATIC; - - -typedef struct{ - FIXP_DBL *mdctSpectrum; - SFB_THRESHOLD sfbThreshold; /* adapt */ - SFB_ENERGY sfbEnergy; /* sfb energies */ - SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */ - SFB_MAX_SCALE sfbMaxScaleSpec; - SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */ - FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in ldData format */ - SFB_ENERGY sfbSpreadEnergy; - INT mdctScale; /* exponent of data in mdctSpectrum */ - INT groupedSfbOffset[MAX_GROUPED_SFB+1]; - INT sfbActive; - INT lowpassLine; -}PSY_DATA; - - -#endif /* _PSY_DATA_H */ + * sfbEnergy.Long and sfbEnergyMS.Long and sfbThreshold.Long are used as a + * temporary storage for the regrouped short energies and thresholds between + * FDKaacEnc_groupShortData() and BuildInterface() in FDKaacEnc_psyMain(). The + * space required for this is MAX_GROUPED_SFB ( = MAX_NO_OF_GROUPS*MAX_SFB_SHORT + * ). However, this is not important if unions are used (which is not possible + * with pfloat). */ + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_THRESHOLD; + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_ENERGY; + +typedef shouldBeUnion { + FIXP_DBL Long[MAX_GROUPED_SFB]; + FIXP_DBL Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_LD_ENERGY; + +typedef shouldBeUnion { + INT Long[MAX_GROUPED_SFB]; + INT Short[TRANS_FAC][MAX_SFB_SHORT]; +} +SFB_MAX_SCALE; + +typedef struct { + INT_PCM* psyInputBuffer; + FIXP_DBL overlapAddBuffer[3 * 512 / 2]; + + mdct_t mdctPers; /* MDCT persistent data */ + BLOCK_SWITCHING_CONTROL blockSwitchingControl; /* block switching */ + FIXP_DBL sfbThresholdnm1[MAX_SFB]; /* FDKaacEnc_PreEchoControl */ + INT mdctScalenm1; /* scale of last block's mdct (FDKaacEnc_PreEchoControl) */ + INT calcPreEcho; + INT isLFE; +} PSY_STATIC; + +typedef struct { + FIXP_DBL* mdctSpectrum; + SFB_THRESHOLD sfbThreshold; /* adapt */ + SFB_ENERGY sfbEnergy; /* sfb energies */ + SFB_LD_ENERGY sfbEnergyLdData; /* sfb energies in ldData format */ + SFB_MAX_SCALE sfbMaxScaleSpec; + SFB_ENERGY sfbEnergyMS; /* mid/side sfb energies */ + FIXP_DBL sfbEnergyMSLdData[MAX_GROUPED_SFB]; /* mid/side sfb energies in + ldData format */ + SFB_ENERGY sfbSpreadEnergy; + INT mdctScale; /* exponent of data in mdctSpectrum */ + INT groupedSfbOffset[MAX_GROUPED_SFB + 1]; + INT sfbActive; + INT lowpassLine; +} PSY_DATA; + +#endif /* PSY_DATA_H */ diff --git a/libAACenc/src/psy_main.cpp b/libAACenc/src/psy_main.cpp index 446c894..f6345e4 100644 --- a/libAACenc/src/psy_main.cpp +++ b/libAACenc/src/psy_main.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Psychoaccoustic major function block + Description: Psychoaccoustic major function block -******************************************************************************/ +*******************************************************************************/ #include "psy_const.h" @@ -107,15 +119,13 @@ amm-info@iis.fraunhofer.de #include "aacEnc_ram.h" #include "intensity.h" - - /* blending to reduce gibbs artifacts */ #define FADE_OUT_LEN 6 -static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016}; +static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = { + 1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016}; /* forward definitions */ - /***************************************************************************** functionname: FDKaacEnc_PsyNew @@ -124,56 +134,52 @@ static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 122 input: pointer to a psych handle *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, - const INT nElements, - const INT nChannels - ,UCHAR *dynamic_RAM - ) -{ - AAC_ENCODER_ERROR ErrorStatus; - PSY_INTERNAL *hPsy; - INT i; - - hPsy = GetRam_aacEnc_PsyInternal(); - *phpsy = hPsy; - if (hPsy == NULL) { +AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements, + const INT nChannels, UCHAR *dynamic_RAM) { + AAC_ENCODER_ERROR ErrorStatus; + PSY_INTERNAL *hPsy; + INT i; + + hPsy = GetRam_aacEnc_PsyInternal(); + *phpsy = hPsy; + if (hPsy == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } + + for (i = 0; i < nElements; i++) { + /* PSY_ELEMENT */ + hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i); + if (hPsy->psyElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; goto bail; } + } - for (i=0; i<nElements; i++) { - /* PSY_ELEMENT */ - hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i); - if (hPsy->psyElement[i] == NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } + for (i = 0; i < nChannels; i++) { + /* PSY_STATIC */ + hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i); + if (hPsy->pStaticChannels[i] == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; } - - for (i=0; i<nChannels; i++) { - /* PSY_STATIC */ - hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i); - if (hPsy->pStaticChannels[i]==NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } - /* AUDIO INPUT BUFFER */ - hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i); - if (hPsy->pStaticChannels[i]->psyInputBuffer==NULL) { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto bail; - } + /* AUDIO INPUT BUFFER */ + hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i); + if (hPsy->pStaticChannels[i]->psyInputBuffer == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; } + } - /* reusable psych memory */ - hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM); + /* reusable psych memory */ + hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM); - return AAC_ENC_OK; + return AAC_ENC_OK; bail: - FDKaacEnc_PsyClose(phpsy, NULL); + FDKaacEnc_PsyClose(phpsy, NULL); - return ErrorStatus; + return ErrorStatus; } /***************************************************************************** @@ -184,18 +190,14 @@ bail: input: pointer to a psych handle *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int n, i; int elInc = 0, chInc = 0; - for (n=0; n<nSubFrames; n++) { + for (n = 0; n < nSubFrames; n++) { phpsyOut[n] = GetRam_aacEnc_PsyOut(n); if (phpsyOut[n] == NULL) { @@ -203,11 +205,15 @@ AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, goto bail; } - for (i=0; i<nChannels; i++) { + for (i = 0; i < nChannels; i++) { phpsyOut[n]->pPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++); + if (NULL == phpsyOut[n]->pPsyOutChannels[i]) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto bail; + } } - for (i=0; i<nElements; i++) { + for (i = 0; i < nElements; i++) { phpsyOut[n]->psyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++); if (phpsyOut[n]->psyOutElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; @@ -223,63 +229,59 @@ bail: return ErrorStatus; } - -AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy, - PSY_STATIC* psyStatic, - AUDIO_OBJECT_TYPE audioObjectType) -{ +AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy, + PSY_STATIC *psyStatic, + AUDIO_OBJECT_TYPE audioObjectType) { /* init input buffer */ - FDKmemclear(psyStatic->psyInputBuffer, MAX_INPUT_BUFFER_SIZE*sizeof(INT_PCM)); + FDKmemclear(psyStatic->psyInputBuffer, + MAX_INPUT_BUFFER_SIZE * sizeof(INT_PCM)); FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl, - isLowDelay(audioObjectType) - ); + isLowDelay(audioObjectType)); return AAC_ENC_OK; } - -AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, - PSY_OUT **phpsyOut, - const INT nSubFrames, - const INT nMaxChannels, +AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut, + const INT nSubFrames, + const INT nMaxChannels, const AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm) -{ + CHANNEL_MAPPING *cm) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; int i, ch, n, chInc = 0, resetChannels = 3; - if ( (nMaxChannels>2) && (cm->nChannels==2) ) { + if ((nMaxChannels > 2) && (cm->nChannels == 2)) { chInc = 1; FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType); } - if ( (nMaxChannels==2) ) { + if ((nMaxChannels == 2)) { resetChannels = 0; } - for (i=0; i<cm->nElements; i++) { - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { - if (cm->elInfo[i].elType!=ID_LFE) { - hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc]; - if (chInc>=resetChannels) { - FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc]; + if (cm->elInfo[i].elType != ID_LFE) { + if (chInc >= resetChannels) { + FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], + audioObjectType); } + mdct_init(&(hPsy->psyElement[i]->psyStatic[ch]->mdctPers), NULL, 0); hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0; - } - else { - hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[nMaxChannels-1]; + } else { hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1; } chInc++; } } - for (n=0; n<nSubFrames; n++) { + for (n = 0; n < nSubFrames; n++) { chInc = 0; - for (i=0; i<cm->nElements; i++) { - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { - phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = phpsyOut[n]->pPsyOutChannels[chInc++]; + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = + phpsyOut[n]->pPsyOutChannels[chInc++]; } } } @@ -287,7 +289,6 @@ AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, return ErrorStatus; } - /***************************************************************************** functionname: FDKaacEnc_psyMainInit @@ -296,139 +297,104 @@ AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, *****************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy, - AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm, - INT sampleRate, - INT granuleLength, - INT bitRate, - INT tnsMask, - INT bandwidth, - INT usePns, - INT useIS, - UINT syntaxFlags, - ULONG initFlags) -{ +AAC_ENCODER_ERROR FDKaacEnc_psyMainInit( + PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm, + INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth, + INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags) { AAC_ENCODER_ERROR ErrorStatus; int i, ch; int channelsEff = cm->nChannelsEff; int tnsChannels = 0; FB_TYPE filterBank; - - switch(FDKaacEnc_GetMonoStereoMode(cm->encMode)) { + switch (FDKaacEnc_GetMonoStereoMode(cm->encMode)) { /* ... and map to tnsChannels */ - case EL_MODE_MONO: tnsChannels = 1; break; - case EL_MODE_STEREO: tnsChannels = 2; break; - default: tnsChannels = 0; + case EL_MODE_MONO: + tnsChannels = 1; + break; + case EL_MODE_STEREO: + tnsChannels = 2; + break; + default: + tnsChannels = 0; } - switch (audioObjectType) - { - default: filterBank = FB_LC; break; - case AOT_ER_AAC_LD: filterBank = FB_LD; break; - case AOT_ER_AAC_ELD: filterBank = FB_ELD; break; + switch (audioObjectType) { + default: + filterBank = FB_LC; + break; + case AOT_ER_AAC_LD: + filterBank = FB_LD; + break; + case AOT_ER_AAC_ELD: + filterBank = FB_ELD; + break; } hPsy->granuleLength = granuleLength; - ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, LONG_WINDOW, hPsy->granuleLength, useIS, &(hPsy->psyConf[0]), filterBank); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_InitPsyConfiguration( + bitRate / channelsEff, sampleRate, bandwidth, LONG_WINDOW, + hPsy->granuleLength, useIS, useMS, &(hPsy->psyConf[0]), filterBank); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; ErrorStatus = FDKaacEnc_InitTnsConfiguration( - (bitRate*tnsChannels)/channelsEff, - sampleRate, - tnsChannels, - LONG_WINDOW, - hPsy->granuleLength, - isLowDelay(audioObjectType), - (syntaxFlags&AC_SBR_PRESENT)?1:0, - &(hPsy->psyConf[0].tnsConf), - &hPsy->psyConf[0], - (INT)(tnsMask&2), - (INT)(tnsMask&8) ); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels, + LONG_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType), + (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &(hPsy->psyConf[0].tnsConf), + &hPsy->psyConf[0], (INT)(tnsMask & 2), (INT)(tnsMask & 8)); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; if (granuleLength > 512) { - ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, SHORT_WINDOW, hPsy->granuleLength, useIS, &hPsy->psyConf[1], filterBank); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + ErrorStatus = FDKaacEnc_InitPsyConfiguration( + bitRate / channelsEff, sampleRate, bandwidth, SHORT_WINDOW, + hPsy->granuleLength, useIS, useMS, &hPsy->psyConf[1], filterBank); + + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; ErrorStatus = FDKaacEnc_InitTnsConfiguration( - (bitRate*tnsChannels)/channelsEff, - sampleRate, - tnsChannels, - SHORT_WINDOW, - hPsy->granuleLength, - isLowDelay(audioObjectType), - (syntaxFlags&AC_SBR_PRESENT)?1:0, - &hPsy->psyConf[1].tnsConf, - &hPsy->psyConf[1], - (INT)(tnsMask&1), - (INT)(tnsMask&4) ); - - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; + (bitRate * tnsChannels) / channelsEff, sampleRate, tnsChannels, + SHORT_WINDOW, hPsy->granuleLength, isLowDelay(audioObjectType), + (syntaxFlags & AC_SBR_PRESENT) ? 1 : 0, &hPsy->psyConf[1].tnsConf, + &hPsy->psyConf[1], (INT)(tnsMask & 1), (INT)(tnsMask & 4)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; } - - for (i=0; i<cm->nElements; i++) { - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { if (initFlags) { /* reset states */ - FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); + FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], + audioObjectType); } - FDKaacEnc_InitPreEchoControl(hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1, - &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho, - hPsy->psyConf[0].sfbCnt, - hPsy->psyConf[0].sfbPcmQuantThreshold, - &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1); + FDKaacEnc_InitPreEchoControl( + hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1, + &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho, + hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbPcmQuantThreshold, + &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1); } } - ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[0].pnsConf, - bitRate/channelsEff, - sampleRate, - usePns, - hPsy->psyConf[0].sfbCnt, - hPsy->psyConf[0].sfbOffset, - cm->elInfo[0].nChannelsInEl, - (hPsy->psyConf[0].filterbank == FB_LC)); - if (ErrorStatus != AAC_ENC_OK) - return ErrorStatus; - - ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[1].pnsConf, - bitRate/channelsEff, - sampleRate, - usePns, - hPsy->psyConf[1].sfbCnt, - hPsy->psyConf[1].sfbOffset, - cm->elInfo[1].nChannelsInEl, - (hPsy->psyConf[1].filterbank == FB_LC)); - return ErrorStatus; -} + ErrorStatus = FDKaacEnc_InitPnsConfiguration( + &hPsy->psyConf[0].pnsConf, bitRate / channelsEff, sampleRate, usePns, + hPsy->psyConf[0].sfbCnt, hPsy->psyConf[0].sfbOffset, + cm->elInfo[0].nChannelsInEl, (hPsy->psyConf[0].filterbank == FB_LC)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + if (granuleLength > 512) { + ErrorStatus = FDKaacEnc_InitPnsConfiguration( + &hPsy->psyConf[1].pnsConf, bitRate / channelsEff, sampleRate, usePns, + hPsy->psyConf[1].sfbCnt, hPsy->psyConf[1].sfbOffset, + cm->elInfo[1].nChannelsInEl, (hPsy->psyConf[1].filterbank == FB_LC)); + if (ErrorStatus != AAC_ENC_OK) return ErrorStatus; + } -static -void FDKaacEnc_deinterleaveInputBuffer(INT_PCM *pOutputSamples, - INT_PCM *pInputSamples, - INT nSamples, - INT nChannels) -{ - INT k; - /* deinterlave input samples and write to output buffer */ - for (k=0; k<nSamples; k++) { - pOutputSamples[k] = pInputSamples[k*nChannels]; - } + return ErrorStatus; } - - /***************************************************************************** functionname: FDKaacEnc_psyMain @@ -438,950 +404,945 @@ void FDKaacEnc_deinterleaveInputBuffer(INT_PCM *pOutputSamples, This function assumes that enough input data is in the modulo buffer. *****************************************************************************/ +AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement, + PSY_DYNAMIC *psyDynamic, + PSY_CONFIGURATION *psyConf, + PSY_OUT_ELEMENT *RESTRICT psyOutElement, + INT_PCM *pInput, const UINT inputBufSize, + INT *chIdx, INT totalChannels) { + const INT commonWindow = 1; + INT maxSfbPerGroup[(2)]; + INT mdctSpectrum_e; + INT ch; /* counts through channels */ + INT w; /* counts through windows */ + INT sfb; /* counts through scalefactor bands */ + INT line; /* counts through lines */ + + PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0]; + PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1]; + PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel; + FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG]; + + PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic; + + PSY_DATA *RESTRICT psyData[(2)]; + TNS_DATA *RESTRICT tnsData[(2)]; + PNS_DATA *RESTRICT pnsData[(2)]; + + INT zeroSpec = TRUE; /* means all spectral lines are zero */ + + INT blockSwitchingOffset; + + PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)]; + INT windowLength[(2)]; + INT nWindows[(2)]; + INT wOffset; + + INT maxSfb[(2)]; + INT *pSfbMaxScaleSpec[(2)]; + FIXP_DBL *pSfbEnergy[(2)]; + FIXP_DBL *pSfbSpreadEnergy[(2)]; + FIXP_DBL *pSfbEnergyLdData[(2)]; + FIXP_DBL *pSfbEnergyMS[(2)]; + FIXP_DBL *pSfbThreshold[(2)]; + + INT isShortWindow[(2)]; + + /* number of incoming time samples to be processed */ + const INT nTimeSamples = psyConf->granuleLength; + + switch (hPsyConfLong->filterbank) { + case FB_LC: + blockSwitchingOffset = + nTimeSamples + (9 * nTimeSamples / (2 * TRANS_FAC)); + break; + case FB_LD: + case FB_ELD: + blockSwitchingOffset = nTimeSamples; + break; + default: + return AAC_ENC_UNSUPPORTED_FILTERBANK; + } -AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, - PSY_ELEMENT *psyElement, - PSY_DYNAMIC *psyDynamic, - PSY_CONFIGURATION *psyConf, - PSY_OUT_ELEMENT *RESTRICT psyOutElement, - INT_PCM *pInput, - INT *chIdx, - INT totalChannels - ) -{ - const INT commonWindow = 1; - INT maxSfbPerGroup[(2)]; - INT mdctSpectrum_e; - INT ch; /* counts through channels */ - INT w; /* counts through windows */ - INT sfb; /* counts through scalefactor bands */ - INT line; /* counts through lines */ - - PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0]; - PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1]; - PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel; - FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG]; - - PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic; - - PSY_DATA *RESTRICT psyData[(2)]; - TNS_DATA *RESTRICT tnsData[(2)]; - PNS_DATA *RESTRICT pnsData[(2)]; - - INT zeroSpec = TRUE; /* means all spectral lines are zero */ - - INT blockSwitchingOffset; - - PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)]; - INT windowLength[(2)]; - INT nWindows[(2)]; - INT wOffset; - - INT maxSfb[(2)]; - INT *pSfbMaxScaleSpec[(2)]; - FIXP_DBL *pSfbEnergy[(2)]; - FIXP_DBL *pSfbSpreadEnergy[(2)]; - FIXP_DBL *pSfbEnergyLdData[(2)]; - FIXP_DBL *pSfbEnergyMS[(2)]; - FIXP_DBL *pSfbThreshold[(2)]; - - INT isShortWindow[(2)]; - - - if (hPsyConfLong->filterbank == FB_LC) { - blockSwitchingOffset = psyConf->granuleLength + (9*psyConf->granuleLength/(2*TRANS_FAC)); - } else { - blockSwitchingOffset = psyConf->granuleLength; - } + for (ch = 0; ch < channels; ch++) { + psyData[ch] = &psyDynamic->psyData[ch]; + tnsData[ch] = &psyDynamic->tnsData[ch]; + pnsData[ch] = &psyDynamic->pnsData[ch]; - for(ch = 0; ch < channels; ch++) - { - psyData[ch] = &psyDynamic->psyData[ch]; - tnsData[ch] = &psyDynamic->tnsData[ch]; - pnsData[ch] = &psyDynamic->pnsData[ch]; + psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum; + } - psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum; - } + /* block switching */ + if (hPsyConfLong->filterbank != FB_ELD) { + int err; - /* block switching */ - if (hPsyConfLong->filterbank != FB_ELD) - { - int err; + for (ch = 0; ch < channels; ch++) { + C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024)) - for(ch = 0; ch < channels; ch++) - { - C_ALLOC_SCRATCH_START(pTimeSignal, INT_PCM, (1024)) + /* copy input data and use for block switching */ + FDKmemcpy(pTimeSignal, pInput + chIdx[ch] * inputBufSize, + nTimeSamples * sizeof(INT_PCM)); - /* deinterleave input data and use for block switching */ - FDKaacEnc_deinterleaveInputBuffer( pTimeSignal, - &pInput[chIdx[ch]], - psyConf->granuleLength, - totalChannels); + FDKaacEnc_BlockSwitching(&psyStatic[ch]->blockSwitchingControl, + nTimeSamples, psyStatic[ch]->isLFE, pTimeSignal); + /* fill up internal input buffer, to 2xframelength samples */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, + pTimeSignal, + (2 * nTimeSamples - blockSwitchingOffset) * sizeof(INT_PCM)); - FDKaacEnc_BlockSwitching (&psyStatic[ch]->blockSwitchingControl, - psyConf->granuleLength, - psyStatic[ch]->isLFE, - pTimeSignal - ); + C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024)) + } + /* synch left and right block type */ + err = FDKaacEnc_SyncBlockSwitching( + &psyStatic[0]->blockSwitchingControl, + (channels > 1) ? &psyStatic[1]->blockSwitchingControl : NULL, channels, + commonWindow); - /* fill up internal input buffer, to 2xframelength samples */ - FDKmemcpy(psyStatic[ch]->psyInputBuffer+blockSwitchingOffset, - pTimeSignal, - (2*psyConf->granuleLength-blockSwitchingOffset)*sizeof(INT_PCM)); + if (err) { + return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */ + } - C_ALLOC_SCRATCH_END(pTimeSignal, INT_PCM, (1024)) - } + } else { + for (ch = 0; ch < channels; ch++) { + /* copy input data and use for block switching */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, + pInput + chIdx[ch] * inputBufSize, + nTimeSamples * sizeof(INT_PCM)); + } + } - /* synch left and right block type */ - err = FDKaacEnc_SyncBlockSwitching(&psyStatic[0]->blockSwitchingControl, - &psyStatic[1]->blockSwitchingControl, - channels, - commonWindow); + for (ch = 0; ch < channels; ch++) + isShortWindow[ch] = + (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + SHORT_WINDOW); + + /* set parameters according to window length */ + for (ch = 0; ch < channels; ch++) { + if (isShortWindow[ch]) { + hThisPsyConf[ch] = hPsyConfShort; + windowLength[ch] = psyConf->granuleLength / TRANS_FAC; + nWindows[ch] = TRANS_FAC; + maxSfb[ch] = MAX_SFB_SHORT; + + pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0]; + pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0]; + pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0]; + pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0]; + pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0]; + pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0]; - if (err) { - return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */ - } + } else { + hThisPsyConf[ch] = hPsyConfLong; + windowLength[ch] = psyConf->granuleLength; + nWindows[ch] = 1; + maxSfb[ch] = MAX_GROUPED_SFB; + + pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long; + pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long; + pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long; + pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long; + pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long; + pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long; + } + } + /* Transform and get mdctScaling for all channels and windows. */ + for (ch = 0; ch < channels; ch++) { + /* update number of active bands */ + if (psyStatic[ch]->isLFE) { + psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE; + psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE; + } else { + psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive; + psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine; } - else { - for(ch = 0; ch < channels; ch++) - { - /* deinterleave input data and use for block switching */ - FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, - &pInput[chIdx[ch]], - psyConf->granuleLength, - totalChannels); + + if (hThisPsyConf[ch]->filterbank == FB_ELD) { + if (FDKaacEnc_Transform_Real_Eld( + psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyStatic[ch]->blockSwitchingControl.windowShape, + &psyStatic[ch]->blockSwitchingControl.lastWindowShape, + nTimeSamples, &mdctSpectrum_e, hThisPsyConf[ch]->filterbank, + psyStatic[ch]->overlapAddBuffer) != 0) { + return AAC_ENC_UNSUPPORTED_FILTERBANK; + } + } else { + if (FDKaacEnc_Transform_Real( + psyStatic[ch]->psyInputBuffer, psyData[ch]->mdctSpectrum, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyStatic[ch]->blockSwitchingControl.windowShape, + &psyStatic[ch]->blockSwitchingControl.lastWindowShape, + &psyStatic[ch]->mdctPers, nTimeSamples, &mdctSpectrum_e, + hThisPsyConf[ch]->filterbank) != 0) { + return AAC_ENC_UNSUPPORTED_FILTERBANK; } } - for(ch = 0; ch < channels; ch++) - isShortWindow[ch]=(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == SHORT_WINDOW); - - /* set parameters according to window length */ - for(ch = 0; ch < channels; ch++) - { - if(isShortWindow[ch]) { - hThisPsyConf[ch] = hPsyConfShort; - windowLength[ch] = psyConf->granuleLength/TRANS_FAC; - nWindows[ch] = TRANS_FAC; - maxSfb[ch] = MAX_SFB_SHORT; - - pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0]; - pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0]; - pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0]; - pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0]; - pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0]; - pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0]; - - } else - { - hThisPsyConf[ch] = hPsyConfLong; - windowLength[ch] = psyConf->granuleLength; - nWindows[ch] = 1; - maxSfb[ch] = MAX_GROUPED_SFB; - - pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long; - pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long; - pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long; - pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long; - pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long; - pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long; + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + + /* Low pass / highest sfb */ + FDKmemclear( + &psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset], + (windowLength[ch] - psyData[ch]->lowpassLine) * sizeof(FIXP_DBL)); + + if ((hPsyConfLong->filterbank != FB_LC) && + (psyData[ch]->lowpassLine >= FADE_OUT_LEN)) { + /* Do blending to reduce gibbs artifacts */ + for (int i = 0; i < FADE_OUT_LEN; i++) { + psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + wOffset - + FADE_OUT_LEN + i] = + fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine + + wOffset - FADE_OUT_LEN + i], + fadeOutFactor[i]); } - } + } - /* Transform and get mdctScaling for all channels and windows. */ - for(ch = 0; ch < channels; ch++) - { - /* update number of active bands */ - if (psyStatic[ch]->isLFE) { - psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE; - psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE; - } else - { - psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive; - psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine; + /* Check for zero spectrum. These loops will usually terminate very, very + * early. */ + for (line = 0; (line < psyData[ch]->lowpassLine) && (zeroSpec == TRUE); + line++) { + if (psyData[ch]->mdctSpectrum[line + wOffset] != (FIXP_DBL)0) { + zeroSpec = FALSE; + break; } + } - for(w = 0; w < nWindows[ch]; w++) { - - wOffset = w*windowLength[ch]; - - FDKaacEnc_Transform_Real( psyStatic[ch]->psyInputBuffer + wOffset, - psyData[ch]->mdctSpectrum+wOffset, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence, - psyStatic[ch]->blockSwitchingControl.windowShape, - &psyStatic[ch]->blockSwitchingControl.lastWindowShape, - psyConf->granuleLength, - &mdctSpectrum_e, - hThisPsyConf[ch]->filterbank - ,psyStatic[ch]->overlapAddBuffer - ); - - /* Low pass / highest sfb */ - FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset], - (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL)); - - if ( (hPsyConfLong->filterbank != FB_LC) && (psyData[ch]->lowpassLine >= FADE_OUT_LEN) ) { - /* Do blending to reduce gibbs artifacts */ - for (int i=0; i<FADE_OUT_LEN; i++) { - psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]); - } - } - - - /* Check for zero spectrum. These loops will usually terminate very, very early. */ - for(line=0; (line<psyData[ch]->lowpassLine) && (zeroSpec==TRUE); line++) { - if (psyData[ch]->mdctSpectrum[line+wOffset] != (FIXP_DBL)0) { - zeroSpec = FALSE; - break; - } - } - - } /* w loop */ - - psyData[ch]->mdctScale = mdctSpectrum_e; - - /* rotate internal time samples */ - FDKmemmove(psyStatic[ch]->psyInputBuffer, - psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, - psyConf->granuleLength*sizeof(INT_PCM)); - - - /* ... and get remaining samples from input buffer */ - FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, - &pInput[ (2*psyConf->granuleLength-blockSwitchingOffset)*totalChannels + chIdx[ch] ], - blockSwitchingOffset-psyConf->granuleLength, - totalChannels); - - } /* ch */ - - /* Do some rescaling to get maximum possible accuracy for energies */ - if ( zeroSpec == FALSE) { - - /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ - INT minSpecShift = MAX_SHIFT_DBL; - INT nrgShift = MAX_SHIFT_DBL; - INT finalShift = MAX_SHIFT_DBL; - FIXP_DBL currNrg = 0; - FIXP_DBL maxNrg = 0; - - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, - hThisPsyConf[ch]->sfbOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - psyData[ch]->sfbActive); - - for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) - minSpecShift = fixMin(minSpecShift, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]); - } - - } + } /* w loop */ + + psyData[ch]->mdctScale = mdctSpectrum_e; + + /* rotate internal time samples */ + FDKmemmove(psyStatic[ch]->psyInputBuffer, + psyStatic[ch]->psyInputBuffer + nTimeSamples, + nTimeSamples * sizeof(INT_PCM)); + + /* ... and get remaining samples from input buffer */ + FDKmemcpy(psyStatic[ch]->psyInputBuffer + nTimeSamples, + pInput + (2 * nTimeSamples - blockSwitchingOffset) + + chIdx[ch] * inputBufSize, + (blockSwitchingOffset - nTimeSamples) * sizeof(INT_PCM)); + + } /* ch */ + + /* Do some rescaling to get maximum possible accuracy for energies */ + if (zeroSpec == FALSE) { + /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift + * is possible without overflow) */ + INT minSpecShift = MAX_SHIFT_DBL; + INT nrgShift = MAX_SHIFT_DBL; + INT finalShift = MAX_SHIFT_DBL; + FIXP_DBL currNrg = 0; + FIXP_DBL maxNrg = 0; + + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + FDKaacEnc_CalcSfbMaxScaleSpec( + psyData[ch]->mdctSpectrum + wOffset, hThisPsyConf[ch]->sfbOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], psyData[ch]->sfbActive); + + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) + minSpecShift = fixMin(minSpecShift, + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb]); + } + } - /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - currNrg = FDKaacEnc_CheckBandEnergyOptim(psyData[ch]->mdctSpectrum+wOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch]+w*maxSfb[ch], - pSfbEnergyLdData[ch]+w*maxSfb[ch], - minSpecShift-4); - - maxNrg = fixMax(maxNrg, currNrg); - } - } + /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is + * possible without overflow) */ + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + currNrg = FDKaacEnc_CheckBandEnergyOptim( + psyData[ch]->mdctSpectrum + wOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], hThisPsyConf[ch]->sfbOffset, + psyData[ch]->sfbActive, pSfbEnergy[ch] + w * maxSfb[ch], + pSfbEnergyLdData[ch] + w * maxSfb[ch], minSpecShift - 4); + + maxNrg = fixMax(maxNrg, currNrg); + } + } - if ( maxNrg != (FIXP_DBL)0 ) { - nrgShift = (CountLeadingBits(maxNrg)>>1) + (minSpecShift-4); - } + if (maxNrg != (FIXP_DBL)0) { + nrgShift = (CountLeadingBits(maxNrg) >> 1) + (minSpecShift - 4); + } - /* 2check: Hasn't this decision to be made for both channels? */ - /* For short windows 1 additional bit headroom is necessary to prevent overflows when summing up energies in FDKaacEnc_groupShortData() */ - if(isShortWindow[0]) nrgShift--; - - /* both spectrum and energies mustn't overflow */ - finalShift = fixMin(minSpecShift, nrgShift); - - /* do not shift more than 3 bits more to the left than signal without blockfloating point - * would be to avoid overflow of scaled PCM quantization thresholds */ - if (finalShift > psyData[0]->mdctScale + 3 ) - finalShift = psyData[0]->mdctScale + 3; - - FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */ - - /* correct sfbEnergy and sfbEnergyLdData with new finalShift */ - FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0/64); - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { - INT scale = fixMax(0, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]-4); - scale = fixMin((scale-finalShift)<<1, DFRACT_BITS-1); - if (scale >= 0) (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] >>= (scale); - else (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] <<= (-scale); - (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = fMult((pSfbEnergy[ch]+w*maxSfb[ch])[sfb], C_RATIO); - (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] += ldShift; - } - } + /* 2check: Hasn't this decision to be made for both channels? */ + /* For short windows 1 additional bit headroom is necessary to prevent + * overflows when summing up energies in FDKaacEnc_groupShortData() */ + if (isShortWindow[0]) nrgShift--; + + /* both spectrum and energies mustn't overflow */ + finalShift = fixMin(minSpecShift, nrgShift); + + /* do not shift more than 3 bits more to the left than signal without + * blockfloating point would be to avoid overflow of scaled PCM quantization + * thresholds */ + if (finalShift > psyData[0]->mdctScale + 3) + finalShift = psyData[0]->mdctScale + 3; + + FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */ + + /* correct sfbEnergy and sfbEnergyLdData with new finalShift */ + FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0 / 64); + for (ch = 0; ch < channels; ch++) { + INT maxSfb_ch = maxSfb[ch]; + INT w_maxSfb_ch = 0; + for (w = 0; w < nWindows[ch]; w++) { + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + INT scale = fixMax(0, (pSfbMaxScaleSpec[ch] + w_maxSfb_ch)[sfb] - 4); + scale = fixMin((scale - finalShift) << 1, DFRACT_BITS - 1); + if (scale >= 0) + (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] >>= (scale); + else + (pSfbEnergy[ch] + w_maxSfb_ch)[sfb] <<= (-scale); + (pSfbThreshold[ch] + w_maxSfb_ch)[sfb] = + fMult((pSfbEnergy[ch] + w_maxSfb_ch)[sfb], C_RATIO); + (pSfbEnergyLdData[ch] + w_maxSfb_ch)[sfb] += ldShift; } + w_maxSfb_ch += maxSfb_ch; + } + } - if ( finalShift != 0 ) { - for (ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - wOffset = w*windowLength[ch]; - for(line=0; line<psyData[ch]->lowpassLine; line++) { - psyData[ch]->mdctSpectrum[line+wOffset] <<= finalShift; - } - /* update sfbMaxScaleSpec */ - for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) - (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] -= finalShift; - } - /* update mdctScale */ - psyData[ch]->mdctScale -= finalShift; - } - } + if (finalShift != 0) { + for (ch = 0; ch < channels; ch++) { + INT wLen = windowLength[ch]; + INT lowpassLine = psyData[ch]->lowpassLine; + wOffset = 0; + FIXP_DBL *mdctSpectrum = &psyData[ch]->mdctSpectrum[0]; + for (w = 0; w < nWindows[ch]; w++) { + FIXP_DBL *spectrum = &mdctSpectrum[wOffset]; + for (line = 0; line < lowpassLine; line++) { + spectrum[line] <<= finalShift; + } + wOffset += wLen; - } else { - /* all spectral lines are zero */ - for (ch = 0; ch < channels; ch++) { - psyData[ch]->mdctScale = 0; /* otherwise mdctScale would be for example 7 and PCM quantization thresholds would be shifted - * 14 bits to the right causing some of them to become 0 (which causes problems later) */ - /* clear sfbMaxScaleSpec */ - for(w = 0; w < nWindows[ch]; w++) { - for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) { - (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] = 0; - (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; - (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f); - (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; - } - } + /* update sfbMaxScaleSpec */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] -= finalShift; } + /* update mdctScale */ + psyData[ch]->mdctScale -= finalShift; + } } - /* Advance psychoacoustics: Tonality and TNS */ - if (psyStatic[0]->isLFE) { - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0; - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0; - } - else - { - - for(ch = 0; ch < channels; ch++) { - if (!isShortWindow[ch]) { - /* tonality */ - FDKaacEnc_CalculateFullTonality( psyData[ch]->mdctSpectrum, - pSfbMaxScaleSpec[ch], - pSfbEnergyLdData[ch], - sfbTonality[ch], - psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbOffset, - hThisPsyConf[ch]->pnsConf.usePns); - } + } else { + /* all spectral lines are zero */ + for (ch = 0; ch < channels; ch++) { + psyData[ch]->mdctScale = + 0; /* otherwise mdctScale would be for example 7 and PCM quantization + * thresholds would be shifted 14 bits to the right causing some of + * them to become 0 (which causes problems later) */ + /* clear sfbMaxScaleSpec */ + for (w = 0; w < nWindows[ch]; w++) { + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + (pSfbMaxScaleSpec[ch] + w * maxSfb[ch])[sfb] = 0; + (pSfbEnergy[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0; + (pSfbEnergyLdData[ch] + w * maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f); + (pSfbThreshold[ch] + w * maxSfb[ch])[sfb] = (FIXP_DBL)0; } + } + } + } - if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) { - INT tnsActive[TRANS_FAC]; - INT nrgScaling[2] = {0,0}; - INT tnsSpecShift = 0; - - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - - wOffset = w*windowLength[ch]; - /* TNS */ - FDKaacEnc_TnsDetect( - tnsData[ch], - &hThisPsyConf[ch]->tnsConf, - &psyOutChannel[ch]->tnsInfo, - hThisPsyConf[ch]->sfbCnt, - psyData[ch]->mdctSpectrum+wOffset, - w, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence - ); - } - } - - if (channels == 2) { - FDKaacEnc_TnsSync( - tnsData[1], - tnsData[0], - &psyOutChannel[1]->tnsInfo, - &psyOutChannel[0]->tnsInfo, + /* Advance psychoacoustics: Tonality and TNS */ + if ((channels >= 1) && (psyStatic[0]->isLFE)) { + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] = 0; + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] = 0; + } else { + for (ch = 0; ch < channels; ch++) { + if (!isShortWindow[ch]) { + /* tonality */ + FDKaacEnc_CalculateFullTonality( + psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch], + pSfbEnergyLdData[ch], sfbTonality[ch], psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbOffset, hThisPsyConf[ch]->pnsConf.usePns); + } + } /* ch */ - psyStatic[1]->blockSwitchingControl.lastWindowSequence, - psyStatic[0]->blockSwitchingControl.lastWindowSequence, - &hThisPsyConf[1]->tnsConf); - } + if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) { + INT tnsActive[TRANS_FAC] = {0}; + INT nrgScaling[2] = {0, 0}; + INT tnsSpecShift = 0; + + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + /* TNS */ + FDKaacEnc_TnsDetect( + tnsData[ch], &hThisPsyConf[ch]->tnsConf, + &psyOutChannel[ch]->tnsInfo, hThisPsyConf[ch]->sfbCnt, + psyData[ch]->mdctSpectrum + wOffset, w, + psyStatic[ch]->blockSwitchingControl.lastWindowSequence); + } + } - FDK_ASSERT(1==commonWindow); /* all checks for TNS do only work for common windows (which is always set)*/ - for(w = 0; w < nWindows[0]; w++) - { - if (isShortWindow[0]) - tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || - tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] || - tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || - tnsData[channels-1]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT]; - else - tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || - tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] || - tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || - tnsData[channels-1]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT]; - } + if (channels == 2) { + FDKaacEnc_TnsSync( + tnsData[1], tnsData[0], &psyOutChannel[1]->tnsInfo, + &psyOutChannel[0]->tnsInfo, - for(ch = 0; ch < channels; ch++) { - if (tnsActive[0] && !isShortWindow[ch]) { - /* Scale down spectrum if tns is active in one of the two channels with same lastWindowSequence */ - /* first part of threshold calculation; it's not necessary to update sfbMaxScaleSpec */ - INT shift = 1; - for(sfb=0; sfb<hThisPsyConf[ch]->lowpassLine; sfb++) { - psyData[ch]->mdctSpectrum[sfb] = psyData[ch]->mdctSpectrum[sfb] >> shift; - } + psyStatic[1]->blockSwitchingControl.lastWindowSequence, + psyStatic[0]->blockSwitchingControl.lastWindowSequence, + &hThisPsyConf[1]->tnsConf); + } - /* update thresholds */ - for (sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { - pSfbThreshold[ch][sfb] >>= (2*shift); - } + if (channels >= 1) { + FDK_ASSERT(1 == commonWindow); /* all checks for TNS do only work for + common windows (which is always set)*/ + for (w = 0; w < nWindows[0]; w++) { + if (isShortWindow[0]) + tnsActive[w] = + tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[HIFILT] || + tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive[LOFILT] || + tnsData[channels - 1] + ->dataRaw.Short.subBlockInfo[w] + .tnsActive[HIFILT] || + tnsData[channels - 1] + ->dataRaw.Short.subBlockInfo[w] + .tnsActive[LOFILT]; + else + tnsActive[w] = + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || + tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive[LOFILT] || + tnsData[channels - 1] + ->dataRaw.Long.subBlockInfo.tnsActive[HIFILT] || + tnsData[channels - 1] + ->dataRaw.Long.subBlockInfo.tnsActive[LOFILT]; + } + } - psyData[ch]->mdctScale += shift; /* update mdctScale */ + for (ch = 0; ch < channels; ch++) { + if (tnsActive[0] && !isShortWindow[ch]) { + /* Scale down spectrum if tns is active in one of the two channels + * with same lastWindowSequence */ + /* first part of threshold calculation; it's not necessary to update + * sfbMaxScaleSpec */ + INT shift = 1; + for (sfb = 0; sfb < hThisPsyConf[ch]->lowpassLine; sfb++) { + psyData[ch]->mdctSpectrum[sfb] = + psyData[ch]->mdctSpectrum[sfb] >> shift; + } - /* calc sfbEnergies after tnsEncode again ! */ + /* update thresholds */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + pSfbThreshold[ch][sfb] >>= (2 * shift); + } - } - } + psyData[ch]->mdctScale += shift; /* update mdctScale */ - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) - { - wOffset = w*windowLength[ch]; - FDKaacEnc_TnsEncode( - &psyOutChannel[ch]->tnsInfo, - tnsData[ch], - hThisPsyConf[ch]->sfbCnt, - &hThisPsyConf[ch]->tnsConf, - hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],/*hThisPsyConf[ch]->lowpassLine*/ /* filter stops before that line ! */ - psyData[ch]->mdctSpectrum+wOffset, - w, - psyStatic[ch]->blockSwitchingControl.lastWindowSequence); - - if(tnsActive[w]) { - /* Calc sfb-bandwise mdct-energies for left and right channel again, */ - /* if tns active in current channel or in one channel with same lastWindowSequence left and right */ - FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, - hThisPsyConf[ch]->sfbOffset, - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - psyData[ch]->sfbActive); - } - } - } + /* calc sfbEnergies after tnsEncode again ! */ + } + } - for(ch = 0; ch < channels; ch++) { - for(w = 0; w < nWindows[ch]; w++) { - - if (tnsActive[w]) { - - if (isShortWindow[ch]) { - FDKaacEnc_CalcBandEnergyOptimShort(psyData[ch]->mdctSpectrum+w*windowLength[ch], - pSfbMaxScaleSpec[ch]+w*maxSfb[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch]+w*maxSfb[ch]); - } - else { - nrgScaling[ch] = /* with tns, energy calculation can overflow; -> scaling */ - FDKaacEnc_CalcBandEnergyOptimLong(psyData[ch]->mdctSpectrum, - pSfbMaxScaleSpec[ch], - hThisPsyConf[ch]->sfbOffset, - psyData[ch]->sfbActive, - pSfbEnergy[ch], - pSfbEnergyLdData[ch]); - tnsSpecShift = fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set only if nrg would have an overflow */ - } - } /* if tnsActive */ - } - } /* end channel loop */ - - /* adapt scaling to prevent nrg overflow, only for long blocks */ - for(ch = 0; ch < channels; ch++) { - if ( (tnsSpecShift!=0) && !isShortWindow[ch] ) { - /* scale down spectrum, nrg's and thresholds, if there was an overflow in sfbNrg calculation after tns */ - for(line=0; line<hThisPsyConf[ch]->lowpassLine; line++) { - psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift; - } - INT scale = (tnsSpecShift-nrgScaling[ch])<<1; - for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { - pSfbEnergyLdData[ch][sfb] -= scale*FL2FXCONST_DBL(1.0/LD_DATA_SCALING); - pSfbEnergy[ch][sfb] >>= scale; - pSfbThreshold[ch][sfb] >>= (tnsSpecShift<<1); - } - psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not necessary to update sfbMaxScaleSpec */ - - } - } /* end channel loop */ - - } /* TNS active */ - } /* !isLFE */ - - - - - - - /* Advance thresholds */ - for(ch = 0; ch < channels; ch++) { - INT headroom; - - FIXP_DBL clipEnergy; - INT energyShift = psyData[ch]->mdctScale*2 ; - INT clipNrgShift = energyShift - THR_SHIFTBITS ; - - if(isShortWindow[ch]) - headroom = 6; - else - headroom = 0; - - if (clipNrgShift >= 0) - clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift ; - else if (clipNrgShift>=-headroom) - clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift ; - else - clipEnergy = (FIXP_DBL)MAXVAL_DBL ; - - for(w = 0; w < nWindows[ch]; w++) - { - INT i; - /* limit threshold to avoid clipping */ - for (i=0; i<psyData[ch]->sfbActive; i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMin(*(pSfbThreshold[ch]+w*maxSfb[ch]+i), clipEnergy); - } + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + wOffset = w * windowLength[ch]; + FDKaacEnc_TnsEncode( + &psyOutChannel[ch]->tnsInfo, tnsData[ch], + hThisPsyConf[ch]->sfbCnt, &hThisPsyConf[ch]->tnsConf, + hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive], + /*hThisPsyConf[ch]->lowpassLine*/ /* filter stops + before that + line ! */ + psyData[ch]->mdctSpectrum + + wOffset, + w, psyStatic[ch]->blockSwitchingControl.lastWindowSequence); + + if (tnsActive[w]) { + /* Calc sfb-bandwise mdct-energies for left and right channel again, + */ + /* if tns active in current channel or in one channel with same + * lastWindowSequence left and right */ + FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum + wOffset, + hThisPsyConf[ch]->sfbOffset, + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], + psyData[ch]->sfbActive); + } + } + } - /* spreading */ - FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbMaskLowFactor, - hThisPsyConf[ch]->sfbMaskHighFactor, - pSfbThreshold[ch]+w*maxSfb[ch]); - - - /* PCM quantization threshold */ - energyShift += PCM_QUANT_THR_SCALE; - if (energyShift>=0) { - energyShift = fixMin(DFRACT_BITS-1,energyShift); - for (i=0; i<psyData[ch]->sfbActive;i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, - (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift)); - } + for (ch = 0; ch < channels; ch++) { + for (w = 0; w < nWindows[ch]; w++) { + if (tnsActive[w]) { + if (isShortWindow[ch]) { + FDKaacEnc_CalcBandEnergyOptimShort( + psyData[ch]->mdctSpectrum + w * windowLength[ch], + pSfbMaxScaleSpec[ch] + w * maxSfb[ch], + hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive, + pSfbEnergy[ch] + w * maxSfb[ch]); } else { - energyShift = fixMin(DFRACT_BITS-1,-energyShift); - for (i=0; i<psyData[ch]->sfbActive;i++) { - *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, - (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift)); - } + nrgScaling[ch] = /* with tns, energy calculation can overflow; -> + scaling */ + FDKaacEnc_CalcBandEnergyOptimLong( + psyData[ch]->mdctSpectrum, pSfbMaxScaleSpec[ch], + hThisPsyConf[ch]->sfbOffset, psyData[ch]->sfbActive, + pSfbEnergy[ch], pSfbEnergyLdData[ch]); + tnsSpecShift = + fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set + only if nrg would + have an overflow */ } + } /* if tnsActive */ + } + } /* end channel loop */ + + /* adapt scaling to prevent nrg overflow, only for long blocks */ + for (ch = 0; ch < channels; ch++) { + if ((tnsSpecShift != 0) && !isShortWindow[ch]) { + /* scale down spectrum, nrg's and thresholds, if there was an overflow + * in sfbNrg calculation after tns */ + for (line = 0; line < hThisPsyConf[ch]->lowpassLine; line++) { + psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift; + } + INT scale = (tnsSpecShift - nrgScaling[ch]) << 1; + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + pSfbEnergyLdData[ch][sfb] -= + scale * FL2FXCONST_DBL(1.0 / LD_DATA_SCALING); + pSfbEnergy[ch][sfb] >>= scale; + pSfbThreshold[ch][sfb] >>= (tnsSpecShift << 1); + } + psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not + necessary to update + sfbMaxScaleSpec */ + } + } /* end channel loop */ - if (!psyStatic[ch]->isLFE) - { - /* preecho control */ - if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == STOP_WINDOW) { - /* prevent FDKaacEnc_PreEchoControl from comparing stop - thresholds with short thresholds */ - for (i=0; i<psyData[ch]->sfbActive;i++) { - psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; - } - - psyStatic[ch]->mdctScalenm1 = 0; - psyStatic[ch]->calcPreEcho = 0; - } - - FDKaacEnc_PreEchoControl( psyStatic[ch]->sfbThresholdnm1, - psyStatic[ch]->calcPreEcho, - psyData[ch]->sfbActive, - hThisPsyConf[ch]->maxAllowedIncreaseFactor, - hThisPsyConf[ch]->minRemainingThresholdFactor, - pSfbThreshold[ch]+w*maxSfb[ch], - psyData[ch]->mdctScale, - &psyStatic[ch]->mdctScalenm1); - - psyStatic[ch]->calcPreEcho = 1; - - if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == START_WINDOW) - { - /* prevent FDKaacEnc_PreEchoControl in next frame to compare start - thresholds with short thresholds */ - for (i=0; i<psyData[ch]->sfbActive;i++) { - psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; - } - - psyStatic[ch]->mdctScalenm1 = 0; - psyStatic[ch]->calcPreEcho = 0; - } + } /* TNS active */ + else { + /* In case of disable TNS, reset its dynamic data. Some of its elements is + * required in PNS detection below. */ + FDKmemclear(psyDynamic->tnsData, sizeof(psyDynamic->tnsData)); + } + } /* !isLFE */ - } + /* Advance thresholds */ + for (ch = 0; ch < channels; ch++) { + INT headroom; - /* spread energy to avoid hole detection */ - FDKmemcpy(pSfbSpreadEnergy[ch]+w*maxSfb[ch], pSfbEnergy[ch]+w*maxSfb[ch], psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + FIXP_DBL clipEnergy; + INT energyShift = psyData[ch]->mdctScale * 2; + INT clipNrgShift = energyShift - THR_SHIFTBITS; + if (isShortWindow[ch]) + headroom = 6; + else + headroom = 0; - FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, - hThisPsyConf[ch]->sfbMaskLowFactorSprEn, - hThisPsyConf[ch]->sfbMaskHighFactorSprEn, - pSfbSpreadEnergy[ch]+w*maxSfb[ch]); - } - } + if (clipNrgShift >= 0) + clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift; + else if (clipNrgShift >= -headroom) + clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift; + else + clipEnergy = (FIXP_DBL)MAXVAL_DBL; + + for (w = 0; w < nWindows[ch]; w++) { + INT i; + /* limit threshold to avoid clipping */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = + fixMin(*(pSfbThreshold[ch] + w * maxSfb[ch] + i), clipEnergy); + } - /* Calc bandwise energies for mid and side channel. Do it only if 2 channels exist */ - if (channels==2) { - for(w = 0; w < nWindows[1]; w++) { - wOffset = w*windowLength[1]; - FDKaacEnc_CalcBandNrgMSOpt(psyData[0]->mdctSpectrum+wOffset, - psyData[1]->mdctSpectrum+wOffset, - pSfbMaxScaleSpec[0]+w*maxSfb[0], - pSfbMaxScaleSpec[1]+w*maxSfb[1], - hThisPsyConf[1]->sfbOffset, - psyData[0]->sfbActive, - pSfbEnergyMS[0]+w*maxSfb[0], - pSfbEnergyMS[1]+w*maxSfb[1], - (psyStatic[1]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW), - psyData[0]->sfbEnergyMSLdData, - psyData[1]->sfbEnergyMSLdData); + /* spreading */ + FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbMaskLowFactor, + hThisPsyConf[ch]->sfbMaskHighFactor, + pSfbThreshold[ch] + w * maxSfb[ch]); + + /* PCM quantization threshold */ + energyShift += PCM_QUANT_THR_SCALE; + if (energyShift >= 0) { + energyShift = fixMin(DFRACT_BITS - 1, energyShift); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax( + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS, + (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift)); } - } - - /* group short data (maxSfb[ch] for short blocks is determined here) */ - for(ch=0;ch<channels;ch++) - { - INT noSfb, i; - if(isShortWindow[ch]) - { - int sfbGrp; - noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups * hPsyConfShort->sfbCnt; - /* At this point, energies and thresholds are copied/regrouped from the ".Short" to the ".Long" arrays */ - FDKaacEnc_groupShortData( psyData[ch]->mdctSpectrum, - &psyData[ch]->sfbThreshold, - &psyData[ch]->sfbEnergy, - &psyData[ch]->sfbEnergyMS, - &psyData[ch]->sfbSpreadEnergy, - hPsyConfShort->sfbCnt, - psyData[ch]->sfbActive, - hPsyConfShort->sfbOffset, - hPsyConfShort->sfbMinSnrLdData, - psyData[ch]->groupedSfbOffset, - &maxSfbPerGroup[ch], - psyOutChannel[ch]->sfbMinSnrLdData, - psyStatic[ch]->blockSwitchingControl.noOfGroups, - psyStatic[ch]->blockSwitchingControl.groupLen, - psyConf[1].granuleLength); - - - /* calculate ldData arrays (short values are in .Long-arrays after FDKaacEnc_groupShortData) */ - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], psyData[ch]->sfbActive); - } - - /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], psyData[ch]->sfbActive); - for (sfb=0;sfb<psyData[ch]->sfbActive;sfb++) { - psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = - fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb], FL2FXCONST_DBL(-0.515625f)); - } - } + } else { + energyShift = fixMin(DFRACT_BITS - 1, -energyShift); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) = fixMax( + *(pSfbThreshold[ch] + w * maxSfb[ch] + i) >> THR_SHIFTBITS, + (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift)); + } + } - if ( channels==2 ) { - for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { - LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], &psyData[ch]->sfbEnergyMSLdData[sfbGrp], psyData[ch]->sfbActive); - } - } + if (!psyStatic[ch]->isLFE) { + /* preecho control */ + if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + STOP_WINDOW) { + /* prevent FDKaacEnc_PreEchoControl from comparing stop + thresholds with short thresholds */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; + } - FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); + psyStatic[ch]->mdctScalenm1 = 0; + psyStatic[ch]->calcPreEcho = 0; + } - } else { - /* maxSfb[ch] for long blocks */ - for (sfb = psyData[ch]->sfbActive-1; sfb >= 0; sfb--) { - for (line = hPsyConfLong->sfbOffset[sfb+1]-1; line >= hPsyConfLong->sfbOffset[sfb]; line--) { - if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break; - } - if (line > hPsyConfLong->sfbOffset[sfb]) break; - } - maxSfbPerGroup[ch] = sfb + 1; - /* ensure at least one section in ICS; workaround for existing decoder crc implementation */ - maxSfbPerGroup[ch] = fixMax(fixMin(5,psyData[ch]->sfbActive),maxSfbPerGroup[ch]); + FDKaacEnc_PreEchoControl( + psyStatic[ch]->sfbThresholdnm1, psyStatic[ch]->calcPreEcho, + psyData[ch]->sfbActive, hThisPsyConf[ch]->maxAllowedIncreaseFactor, + hThisPsyConf[ch]->minRemainingThresholdFactor, + pSfbThreshold[ch] + w * maxSfb[ch], psyData[ch]->mdctScale, + &psyStatic[ch]->mdctScalenm1); + + psyStatic[ch]->calcPreEcho = 1; + + if (psyStatic[ch]->blockSwitchingControl.lastWindowSequence == + START_WINDOW) { + /* prevent FDKaacEnc_PreEchoControl in next frame to compare start + thresholds with short thresholds */ + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; + } - /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in psyOut structure */ - FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, psyData[ch]->sfbEnergyLdData.Long, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + psyStatic[ch]->mdctScalenm1 = 0; + psyStatic[ch]->calcPreEcho = 0; + } + } - FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); + /* spread energy to avoid hole detection */ + FDKmemcpy(pSfbSpreadEnergy[ch] + w * maxSfb[ch], + pSfbEnergy[ch] + w * maxSfb[ch], + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); - /* sfbMinSnrLdData modified in adjust threshold, copy necessary */ - FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, hPsyConfLong->sfbMinSnrLdData, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); + FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, + hThisPsyConf[ch]->sfbMaskLowFactorSprEn, + hThisPsyConf[ch]->sfbMaskHighFactorSprEn, + pSfbSpreadEnergy[ch] + w * maxSfb[ch]); + } + } - /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; only in long case */ + /* Calc bandwise energies for mid and side channel. Do it only if 2 channels + * exist */ + if (channels == 2) { + for (w = 0; w < nWindows[1]; w++) { + wOffset = w * windowLength[1]; + FDKaacEnc_CalcBandNrgMSOpt( + psyData[0]->mdctSpectrum + wOffset, + psyData[1]->mdctSpectrum + wOffset, + pSfbMaxScaleSpec[0] + w * maxSfb[0], + pSfbMaxScaleSpec[1] + w * maxSfb[1], hThisPsyConf[1]->sfbOffset, + psyData[0]->sfbActive, pSfbEnergyMS[0] + w * maxSfb[0], + pSfbEnergyMS[1] + w * maxSfb[1], + (psyStatic[1]->blockSwitchingControl.lastWindowSequence != + SHORT_WINDOW), + psyData[0]->sfbEnergyMSLdData, psyData[1]->sfbEnergyMSLdData); + } + } - /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ - LdDataVector(psyData[ch]->sfbThreshold.Long, psyOutChannel[ch]->sfbThresholdLdData, psyData[ch]->sfbActive); - for (i=0;i<psyData[ch]->sfbActive;i++) { - psyOutChannel[ch]->sfbThresholdLdData[i] = - fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], FL2FXCONST_DBL(-0.515625f)); - } + /* group short data (maxSfb[ch] for short blocks is determined here) */ + for (ch = 0; ch < channels; ch++) { + if (isShortWindow[ch]) { + int sfbGrp; + int noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt; + /* At this point, energies and thresholds are copied/regrouped from the + * ".Short" to the ".Long" arrays */ + FDKaacEnc_groupShortData( + psyData[ch]->mdctSpectrum, &psyData[ch]->sfbThreshold, + &psyData[ch]->sfbEnergy, &psyData[ch]->sfbEnergyMS, + &psyData[ch]->sfbSpreadEnergy, hPsyConfShort->sfbCnt, + psyData[ch]->sfbActive, hPsyConfShort->sfbOffset, + hPsyConfShort->sfbMinSnrLdData, psyData[ch]->groupedSfbOffset, + &maxSfbPerGroup[ch], psyOutChannel[ch]->sfbMinSnrLdData, + psyStatic[ch]->blockSwitchingControl.noOfGroups, + psyStatic[ch]->blockSwitchingControl.groupLen, + psyConf[1].granuleLength); + + /* calculate ldData arrays (short values are in .Long-arrays after + * FDKaacEnc_groupShortData) */ + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], + &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], + psyData[ch]->sfbActive); + } + /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], + &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], + psyData[ch]->sfbActive); + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb] = + fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp + sfb], + FL2FXCONST_DBL(-0.515625f)); + } + } + if (channels == 2) { + for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { + LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], + &psyData[ch]->sfbEnergyMSLdData[sfbGrp], + psyData[ch]->sfbActive); } + } + FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, + (MAX_GROUPED_SFB + 1) * sizeof(INT)); + } else { + int i; + /* maxSfb[ch] for long blocks */ + for (sfb = psyData[ch]->sfbActive - 1; sfb >= 0; sfb--) { + for (line = hPsyConfLong->sfbOffset[sfb + 1] - 1; + line >= hPsyConfLong->sfbOffset[sfb]; line--) { + if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break; + } + if (line > hPsyConfLong->sfbOffset[sfb]) break; + } + maxSfbPerGroup[ch] = sfb + 1; + maxSfbPerGroup[ch] = + fixMax(fixMin(5, psyData[ch]->sfbActive), maxSfbPerGroup[ch]); + + /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in + * psyOut structure */ + FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, + psyData[ch]->sfbEnergyLdData.Long, + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); + + FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, + (MAX_GROUPED_SFB + 1) * sizeof(INT)); + + /* sfbMinSnrLdData modified in adjust threshold, copy necessary */ + FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, + hPsyConfLong->sfbMinSnrLdData, + psyData[ch]->sfbActive * sizeof(FIXP_DBL)); + + /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; + * only in long case */ + + /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ + LdDataVector(psyData[ch]->sfbThreshold.Long, + psyOutChannel[ch]->sfbThresholdLdData, + psyData[ch]->sfbActive); + for (i = 0; i < psyData[ch]->sfbActive; i++) { + psyOutChannel[ch]->sfbThresholdLdData[i] = + fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], + FL2FXCONST_DBL(-0.515625f)); + } } + } + /* + Intensity parameter intialization. + */ + for (ch = 0; ch < channels; ch++) { + FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB * sizeof(INT)); + FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB * sizeof(INT)); + } - /* - Intensity parameter intialization. - */ - for(ch=0;ch<channels;ch++) { - FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB*sizeof(INT)); - FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB*sizeof(INT)); - } + for (ch = 0; ch < channels; ch++) { + INT win = (isShortWindow[ch] ? 1 : 0); + if (!psyStatic[ch]->isLFE) { + /* PNS Decision */ + FDKaacEnc_PnsDetect( + &(psyConf[0].pnsConf), pnsData[ch], + psyStatic[ch]->blockSwitchingControl.lastWindowSequence, + psyData[ch]->sfbActive, + maxSfbPerGroup[ch], /* count of Sfb which are not zero. */ + psyOutChannel[ch]->sfbThresholdLdData, psyConf[win].sfbOffset, + psyData[ch]->mdctSpectrum, psyData[ch]->sfbMaxScaleSpec.Long, + sfbTonality[ch], psyOutChannel[ch]->tnsInfo.order[0][0], + tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT], + tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT], + psyOutChannel[ch]->sfbEnergyLdData, psyOutChannel[ch]->noiseNrg); + } /* !isLFE */ + } /* ch */ - for(ch=0;ch<channels;ch++) { - INT win = (isShortWindow[ch]?1:0); - if (!psyStatic[ch]->isLFE) - { - /* PNS Decision */ - FDKaacEnc_PnsDetect( &(psyConf[0].pnsConf), - pnsData[ch], - psyStatic[ch]->blockSwitchingControl.lastWindowSequence, - psyData[ch]->sfbActive, - maxSfbPerGroup[ch], /* count of Sfb which are not zero. */ - psyOutChannel[ch]->sfbThresholdLdData, - psyConf[win].sfbOffset, - psyData[ch]->mdctSpectrum, - psyData[ch]->sfbMaxScaleSpec.Long, - sfbTonality[ch], - psyOutChannel[ch]->tnsInfo.order[0][0], - tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain[HIFILT], - tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive[HIFILT], - psyOutChannel[ch]->sfbEnergyLdData, - psyOutChannel[ch]->noiseNrg ); - } /* !isLFE */ - } + /* + stereo Processing + */ + if (channels == 2) { + psyOutElement->toolsInfo.msDigest = MS_NONE; + psyOutElement->commonWindow = commonWindow; + if (psyOutElement->commonWindow) + maxSfbPerGroup[0] = maxSfbPerGroup[1] = + fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]); + if (psyStatic[0]->blockSwitchingControl.lastWindowSequence != + SHORT_WINDOW) { + /* PNS preprocessing depending on ms processing: PNS not in Short Window! + */ + FDKaacEnc_PreProcessPnsChannelPair( + psyData[0]->sfbActive, (&psyData[0]->sfbEnergy)->Long, + (&psyData[1]->sfbEnergy)->Long, psyOutChannel[0]->sfbEnergyLdData, + psyOutChannel[1]->sfbEnergyLdData, psyData[0]->sfbEnergyMS.Long, + &(psyConf[0].pnsConf), pnsData[0], pnsData[1]); + + FDKaacEnc_IntensityStereoProcessing( + psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long, + psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum, + psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long, + psyOutChannel[1]->sfbThresholdLdData, + psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long, + psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[0].sfbCnt, psyConf[0].sfbCnt, maxSfbPerGroup[0], + psyConf[0].sfbOffset, + psyConf[0].allowIS && psyOutElement->commonWindow, + psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData); + + FDKaacEnc_MsStereoProcessing( + psyData, psyOutChannel, psyOutChannel[1]->isBook, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[0].allowMS, psyData[0]->sfbActive, psyData[0]->sfbActive, + maxSfbPerGroup[0], psyOutChannel[0]->sfbOffsets); + + /* PNS postprocessing */ + FDKaacEnc_PostProcessPnsChannelPair( + psyData[0]->sfbActive, &(psyConf[0].pnsConf), pnsData[0], pnsData[1], + psyOutElement->toolsInfo.msMask, &psyOutElement->toolsInfo.msDigest); - /* - stereo Processing - */ - if(channels == 2) - { - psyOutElement->toolsInfo.msDigest = MS_NONE; - psyOutElement->commonWindow = commonWindow; - if (psyOutElement->commonWindow) - maxSfbPerGroup[0] = maxSfbPerGroup[1] = - fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]); - - if(psyStatic[0]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW) - { - /* PNS preprocessing depending on ms processing: PNS not in Short Window! */ - FDKaacEnc_PreProcessPnsChannelPair( - psyData[0]->sfbActive, - (&psyData[0]->sfbEnergy)->Long, - (&psyData[1]->sfbEnergy)->Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - psyData[0]->sfbEnergyMS.Long, - &(psyConf[0].pnsConf), - pnsData[0], - pnsData[1]); - - FDKaacEnc_IntensityStereoProcessing( - psyData[0]->sfbEnergy.Long, - psyData[1]->sfbEnergy.Long, - psyData[0]->mdctSpectrum, - psyData[1]->mdctSpectrum, - psyData[0]->sfbThreshold.Long, - psyData[1]->sfbThreshold.Long, - psyOutChannel[1]->sfbThresholdLdData, - psyData[0]->sfbSpreadEnergy.Long, - psyData[1]->sfbSpreadEnergy.Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyConf[0].sfbCnt, - psyConf[0].sfbCnt, - maxSfbPerGroup[0], - psyConf[0].sfbOffset, - psyConf[0].allowIS && commonWindow, - psyOutChannel[1]->isBook, - psyOutChannel[1]->isScale, - pnsData); - - FDKaacEnc_MsStereoProcessing( - psyData, - psyOutChannel, - psyOutChannel[1]->isBook, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyData[0]->sfbActive, - psyData[0]->sfbActive, - maxSfbPerGroup[0], - psyOutChannel[0]->sfbOffsets); - - /* PNS postprocessing */ - FDKaacEnc_PostProcessPnsChannelPair(psyData[0]->sfbActive, - &(psyConf[0].pnsConf), - pnsData[0], - pnsData[1], - psyOutElement->toolsInfo.msMask, - &psyOutElement->toolsInfo.msDigest); - - } else { - FDKaacEnc_IntensityStereoProcessing( - psyData[0]->sfbEnergy.Long, - psyData[1]->sfbEnergy.Long, - psyData[0]->mdctSpectrum, - psyData[1]->mdctSpectrum, - psyData[0]->sfbThreshold.Long, - psyData[1]->sfbThreshold.Long, - psyOutChannel[1]->sfbThresholdLdData, - psyData[0]->sfbSpreadEnergy.Long, - psyData[1]->sfbSpreadEnergy.Long, - psyOutChannel[0]->sfbEnergyLdData, - psyOutChannel[1]->sfbEnergyLdData, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, - psyConf[1].sfbCnt, - maxSfbPerGroup[0], - psyData[0]->groupedSfbOffset, - psyConf[0].allowIS && commonWindow, - psyOutChannel[1]->isBook, - psyOutChannel[1]->isScale, - pnsData); - - /* it's OK to pass the ".Long" arrays here. They contain grouped short data since FDKaacEnc_groupShortData() */ - FDKaacEnc_MsStereoProcessing( psyData, - psyOutChannel, - psyOutChannel[1]->isBook, - &psyOutElement->toolsInfo.msDigest, - psyOutElement->toolsInfo.msMask, - psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, - hPsyConfShort->sfbCnt, - maxSfbPerGroup[0], - psyOutChannel[0]->sfbOffsets); - } + } else { + FDKaacEnc_IntensityStereoProcessing( + psyData[0]->sfbEnergy.Long, psyData[1]->sfbEnergy.Long, + psyData[0]->mdctSpectrum, psyData[1]->mdctSpectrum, + psyData[0]->sfbThreshold.Long, psyData[1]->sfbThreshold.Long, + psyOutChannel[1]->sfbThresholdLdData, + psyData[0]->sfbSpreadEnergy.Long, psyData[1]->sfbSpreadEnergy.Long, + psyOutChannel[0]->sfbEnergyLdData, psyOutChannel[1]->sfbEnergyLdData, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyStatic[0]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt, + psyConf[1].sfbCnt, maxSfbPerGroup[0], psyData[0]->groupedSfbOffset, + psyConf[0].allowIS && psyOutElement->commonWindow, + psyOutChannel[1]->isBook, psyOutChannel[1]->isScale, pnsData); + + /* it's OK to pass the ".Long" arrays here. They contain grouped short + * data since FDKaacEnc_groupShortData() */ + FDKaacEnc_MsStereoProcessing( + psyData, psyOutChannel, psyOutChannel[1]->isBook, + &psyOutElement->toolsInfo.msDigest, psyOutElement->toolsInfo.msMask, + psyConf[1].allowMS, + psyStatic[0]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt, + hPsyConfShort->sfbCnt, maxSfbPerGroup[0], + psyOutChannel[0]->sfbOffsets); } + } /* (channels == 2) */ /* PNS Coding */ - for(ch=0;ch<channels;ch++) { - if (psyStatic[ch]->isLFE) { - /* no PNS coding */ - for(sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { - psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS; - } - } else - { - FDKaacEnc_CodePnsChannel(psyData[ch]->sfbActive, - &(psyConf[ch].pnsConf), - pnsData[ch]->pnsFlag, - psyData[ch]->sfbEnergyLdData.Long, - psyOutChannel[ch]->noiseNrg, /* this is the energy that will be written to the bitstream */ - psyOutChannel[ch]->sfbThresholdLdData); + for (ch = 0; ch < channels; ch++) { + if (psyStatic[ch]->isLFE) { + /* no PNS coding */ + for (sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { + psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS; } + } else { + FDKaacEnc_CodePnsChannel( + psyData[ch]->sfbActive, &(hThisPsyConf[ch]->pnsConf), + pnsData[ch]->pnsFlag, psyData[ch]->sfbEnergyLdData.Long, + psyOutChannel[ch]->noiseNrg, /* this is the energy that will be + written to the bitstream */ + psyOutChannel[ch]->sfbThresholdLdData); + } } - /* - build output - */ - for(ch=0;ch<channels;ch++) - { - INT j, grp, mask; - - psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch]; - psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale; - - if(isShortWindow[ch]==0) { - - psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive; - psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive; - psyOutChannel[ch]->lastWindowSequence = psyStatic[ch]->blockSwitchingControl.lastWindowSequence; - psyOutChannel[ch]->windowShape = psyStatic[ch]->blockSwitchingControl.windowShape; - } - else { - INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt; - - psyOutChannel[ch]->sfbCnt = sfbCnt; - psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt; - psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW; - psyOutChannel[ch]->windowShape = SINE_WINDOW; - } - - /* generate grouping mask */ - mask = 0; - for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; grp++) - { - mask <<= 1; - for (j=1; j<psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) { - mask = (mask<<1) | 1 ; - } - } - psyOutChannel[ch]->groupingMask = mask; + /* + build output + */ + for (ch = 0; ch < channels; ch++) { + INT mask; + int grp; + psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch]; + psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale; + if (isShortWindow[ch] == 0) { + psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive; + psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive; + psyOutChannel[ch]->lastWindowSequence = + psyStatic[ch]->blockSwitchingControl.lastWindowSequence; + psyOutChannel[ch]->windowShape = + psyStatic[ch]->blockSwitchingControl.windowShape; + } else { + INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups * + hPsyConfShort->sfbCnt; - /* build interface */ - FDKmemcpy(psyOutChannel[ch]->groupLen,psyStatic[ch]->blockSwitchingControl.groupLen,MAX_NO_OF_GROUPS*sizeof(INT)); - FDKmemcpy(psyOutChannel[ch]->sfbEnergy,(&psyData[ch]->sfbEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); - FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,(&psyData[ch]->sfbSpreadEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); -// FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL)); + psyOutChannel[ch]->sfbCnt = sfbCnt; + psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt; + psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW; + psyOutChannel[ch]->windowShape = SINE_WINDOW; + } + /* generate grouping mask */ + mask = 0; + for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; + grp++) { + int j; + mask <<= 1; + for (j = 1; j < psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) { + mask = (mask << 1) | 1; + } } + psyOutChannel[ch]->groupingMask = mask; + + /* build interface */ + FDKmemcpy(psyOutChannel[ch]->groupLen, + psyStatic[ch]->blockSwitchingControl.groupLen, + MAX_NO_OF_GROUPS * sizeof(INT)); + FDKmemcpy(psyOutChannel[ch]->sfbEnergy, (&psyData[ch]->sfbEnergy)->Long, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy, + (&psyData[ch]->sfbSpreadEnergy)->Long, + MAX_GROUPED_SFB * sizeof(FIXP_DBL)); + // FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, + // psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL)); + } - return AAC_ENC_OK; + return AAC_ENC_OK; } +void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut) { + int n, i; -void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, - PSY_OUT **phPsyOut) -{ - int n, i; - - - if(phPsyInternal!=NULL) { - PSY_INTERNAL *hPsyInternal = *phPsyInternal; + if (phPsyInternal != NULL) { + PSY_INTERNAL *hPsyInternal = *phPsyInternal; - if (hPsyInternal) - { - for (i=0; i<(8); i++) { - if (hPsyInternal->pStaticChannels[i]) { - if (hPsyInternal->pStaticChannels[i]->psyInputBuffer) - FreeRam_aacEnc_PsyInputBuffer(&hPsyInternal->pStaticChannels[i]->psyInputBuffer); /* AUDIO INPUT BUFFER */ + if (hPsyInternal) { + for (i = 0; i < (8); i++) { + if (hPsyInternal->pStaticChannels[i]) { + if (hPsyInternal->pStaticChannels[i]->psyInputBuffer) + FreeRam_aacEnc_PsyInputBuffer( + &hPsyInternal->pStaticChannels[i] + ->psyInputBuffer); /* AUDIO INPUT BUFFER */ - FreeRam_aacEnc_PsyStatic(&hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */ - } + FreeRam_aacEnc_PsyStatic( + &hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */ } + } - for (i=0; i<(8); i++) { - if (hPsyInternal->psyElement[i]) - FreeRam_aacEnc_PsyElement(&hPsyInternal->psyElement[i]); /* PSY_ELEMENT */ - } - - - FreeRam_aacEnc_PsyInternal(phPsyInternal); + for (i = 0; i < ((8)); i++) { + if (hPsyInternal->psyElement[i]) + FreeRam_aacEnc_PsyElement( + &hPsyInternal->psyElement[i]); /* PSY_ELEMENT */ } - } - if (phPsyOut!=NULL) { - for (n=0; n<(1); n++) { - if (phPsyOut[n]) - { - for (i=0; i<(8); i++) { - if (phPsyOut[n]->pPsyOutChannels[i]) - FreeRam_aacEnc_PsyOutChannel(&phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */ - } + FreeRam_aacEnc_PsyInternal(phPsyInternal); + } + } - for (i=0; i<(8); i++) { - if (phPsyOut[n]->psyOutElement[i]) - FreeRam_aacEnc_PsyOutElements(&phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */ - } + if (phPsyOut != NULL) { + for (n = 0; n < (1); n++) { + if (phPsyOut[n]) { + for (i = 0; i < (8); i++) { + if (phPsyOut[n]->pPsyOutChannels[i]) + FreeRam_aacEnc_PsyOutChannel( + &phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */ + } - FreeRam_aacEnc_PsyOut(&phPsyOut[n]); + for (i = 0; i < ((8)); i++) { + if (phPsyOut[n]->psyOutElement[i]) + FreeRam_aacEnc_PsyOutElements( + &phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */ } + + FreeRam_aacEnc_PsyOut(&phPsyOut[n]); } } + } } diff --git a/libAACenc/src/psy_main.h b/libAACenc/src/psy_main.h index 7bdcc38..7cc01a3 100644 --- a/libAACenc/src/psy_main.h +++ b/libAACenc/src/psy_main.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Psychoaccoustic major function block + Author(s): M.Werner -******************************************************************************/ + Description: Psychoaccoustic major function block -#ifndef _PSYMAIN_H -#define _PSYMAIN_H +*******************************************************************************/ +#ifndef PSY_MAIN_H +#define PSY_MAIN_H #include "psy_configuration.h" #include "qc_data.h" @@ -99,76 +110,52 @@ amm-info@iis.fraunhofer.de /* psych internal */ -typedef struct { - - PSY_STATIC* psyStatic[(2)]; +typedef struct { + PSY_STATIC *psyStatic[(2)]; -}PSY_ELEMENT; +} PSY_ELEMENT; -typedef struct { +typedef struct { + PSY_DATA psyData[(2)]; + TNS_DATA tnsData[(2)]; + PNS_DATA pnsData[(2)]; - PSY_DATA psyData[(2)]; - TNS_DATA tnsData[(2)]; - PNS_DATA pnsData[(2)]; +} PSY_DYNAMIC; -}PSY_DYNAMIC; +typedef struct { + PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */ + PSY_ELEMENT *psyElement[((8))]; + PSY_STATIC *pStaticChannels[(8)]; + PSY_DYNAMIC *psyDynamic; + INT granuleLength; +} PSY_INTERNAL; -typedef struct { +AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, const INT nElements, + const INT nChannels, UCHAR *dynamic_RAM); - PSY_CONFIGURATION psyConf[2]; /* LONG / SHORT */ - PSY_ELEMENT* psyElement[(8)]; - PSY_STATIC* pStaticChannels[(8)]; - PSY_DYNAMIC* psyDynamic; - INT granuleLength; - -}PSY_INTERNAL; +AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM); +AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, PSY_OUT **phpsyOut, + const INT nSubFrames, + const INT nMaxChannels, + const AUDIO_OBJECT_TYPE audioObjectType, + CHANNEL_MAPPING *cm); -AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, - const INT nElements, - const INT nChannels - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_psyMainInit( + PSY_INTERNAL *hPsy, AUDIO_OBJECT_TYPE audioObjectType, CHANNEL_MAPPING *cm, + INT sampleRate, INT granuleLength, INT bitRate, INT tnsMask, INT bandwidth, + INT usePns, INT useIS, INT useMS, UINT syntaxFlags, ULONG initFlags); -AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, PSY_ELEMENT *psyElement, + PSY_DYNAMIC *psyDynamic, + PSY_CONFIGURATION *psyConf, + PSY_OUT_ELEMENT *psyOutElement, + INT_PCM *pInput, const UINT inputBufSize, + INT *chIdx, INT totalChannels); -AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, - PSY_OUT **phpsyOut, - const INT nSubFrames, - const INT nMaxChannels, - const AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm); +void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, PSY_OUT **phPsyOut); -AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy, - AUDIO_OBJECT_TYPE audioObjectType, - CHANNEL_MAPPING *cm, - INT sampleRate, - INT granuleLength, - INT bitRate, - INT tnsMask, - INT bandwidth, - INT usePns, - INT useIS, - UINT syntaxFlags, - ULONG initFlags); - -AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, - PSY_ELEMENT *psyElement, - PSY_DYNAMIC *psyDynamic, - PSY_CONFIGURATION *psyConf, - PSY_OUT_ELEMENT *psyOutElement, - INT_PCM *pInput, - INT *chIdx, - INT totalChannels - ); - -void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, - PSY_OUT **phPsyOut); - -#endif /* _PSYMAIN_H */ +#endif /* PSY_MAIN_H */ diff --git a/libAACenc/src/qc_data.h b/libAACenc/src/qc_data.h index 00d6090..6e671ed 100644 --- a/libAACenc/src/qc_data.h +++ b/libAACenc/src/qc_data.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,19 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Quantizing & coding data + Author(s): M. Werner -******************************************************************************/ + Description: Quantizing & coding data -#ifndef _QC_DATA_H -#define _QC_DATA_H +*******************************************************************************/ +#ifndef QC_DATA_H +#define QC_DATA_H +#include "aacenc.h" #include "psy_const.h" #include "dyn_bits.h" #include "adj_thr_data.h" @@ -99,18 +111,16 @@ amm-info@iis.fraunhofer.de #include "FDK_audio.h" #include "interface.h" - typedef enum { QCDATA_BR_MODE_INVALID = -1, - QCDATA_BR_MODE_CBR = 0, - QCDATA_BR_MODE_VBR_1 = 1, /* 32 kbps/channel */ - QCDATA_BR_MODE_VBR_2 = 2, /* 40 kbps/channel */ - QCDATA_BR_MODE_VBR_3 = 3, /* 48 kbps/channel */ - QCDATA_BR_MODE_VBR_4 = 4, /* 64 kbps/channel */ - QCDATA_BR_MODE_VBR_5 = 5, /* 96 kbps/channel */ - QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */ - QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */ - + QCDATA_BR_MODE_CBR = 0, /* Constant bit rate, given average bitrate */ + QCDATA_BR_MODE_VBR_1 = 1, /* Variable bit rate, very low */ + QCDATA_BR_MODE_VBR_2 = 2, /* Variable bit rate, low */ + QCDATA_BR_MODE_VBR_3 = 3, /* Variable bit rate, medium */ + QCDATA_BR_MODE_VBR_4 = 4, /* Variable bit rate, high */ + QCDATA_BR_MODE_VBR_5 = 5, /* Variable bit rate, very high */ + QCDATA_BR_MODE_FF = 6, /* Fixed frame mode. */ + QCDATA_BR_MODE_SFR = 7 /* Superframe mode. */ } QCDATA_BR_MODE; @@ -127,137 +137,150 @@ typedef struct { INT nChannels; INT nChannelsEff; INT nElements; - ELEMENT_INFO elInfo[(8)]; + ELEMENT_INFO elInfo[((8))]; } CHANNEL_MAPPING; typedef struct { INT paddingRest; } PADDING; - /* Quantizing & coding stage */ -struct QC_INIT{ - CHANNEL_MAPPING* channelMapping; +struct QC_INIT { + CHANNEL_MAPPING *channelMapping; INT sceCpe; /* not used yet */ INT maxBits; /* maximum number of bits in reservoir */ INT averageBits; /* average number of bits we should use */ INT bitRes; - INT sampleRate; /* output sample rate */ - INT advancedBitsToPe; /* if set, calc bits2PE factor depending on samplerate */ - INT staticBits; /* Bits per frame consumed by transport layers. */ + INT sampleRate; /* output sample rate */ + INT isLowDelay; /* if set, calc bits2PE factor depending on samplerate */ + INT staticBits; /* Bits per frame consumed by transport layers. */ QCDATA_BR_MODE bitrateMode; INT meanPe; - INT chBitrate; + INT chBitrate; /* Bitrate/channel */ INT invQuant; - INT maxIterations; /* Maximum number of allowed iterations before FDKaacEnc_crashRecovery() is applied. */ + INT maxIterations; /* Maximum number of allowed iterations before + FDKaacEnc_crashRecovery() is applied. */ FIXP_DBL maxBitFac; INT bitrate; - INT nSubFrames; /* helper variable */ - INT minBits; /* minimal number of bits in one frame*/ + INT nSubFrames; /* helper variable */ + INT minBits; /* minimal number of bits in one frame*/ + AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced + bitreservoir, 2: disabled bitreservoir */ + INT bitDistributionMode; /* Configure element-wise execution or execution over + all elements for the pe-dependent + threshold-adaption */ PADDING padding; }; -typedef struct -{ - FIXP_DBL mdctSpectrum[(1024)]; +typedef struct { + FIXP_DBL mdctSpectrum[(1024)]; - SHORT quantSpec[(1024)]; + SHORT quantSpec[(1024)]; - UINT maxValueInSfb[MAX_GROUPED_SFB]; - INT scf[MAX_GROUPED_SFB]; - INT globalGain; - SECTION_DATA sectionData; + UINT maxValueInSfb[MAX_GROUPED_SFB]; + INT scf[MAX_GROUPED_SFB]; + INT globalGain; + SECTION_DATA sectionData; - FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbFormFactorLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnergy[MAX_GROUPED_SFB]; - FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbThresholdLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbMinSnrLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnergyLdData[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnergy[MAX_GROUPED_SFB]; + FIXP_DBL sfbWeightedEnergyLdData[MAX_GROUPED_SFB]; - FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB]; + FIXP_DBL sfbEnFacLd[MAX_GROUPED_SFB]; - FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB]; + FIXP_DBL sfbSpreadEnergy[MAX_GROUPED_SFB]; } QC_OUT_CHANNEL; - -typedef struct -{ - EXT_PAYLOAD_TYPE type; /* type of the extension payload */ - INT nPayloadBits; /* size of the payload */ - UCHAR *pPayload; /* pointer to payload */ +typedef struct { + EXT_PAYLOAD_TYPE type; /* type of the extension payload */ + INT nPayloadBits; /* size of the payload */ + UCHAR *pPayload; /* pointer to payload */ } QC_OUT_EXTENSION; +typedef struct { + INT staticBitsUsed; /* for verification purposes */ + INT dynBitsUsed; /* for verification purposes */ -typedef struct -{ - INT staticBitsUsed; /* for verification purposes */ - INT dynBitsUsed; /* for verification purposes */ - - INT extBitsUsed; /* bit consumption of extended fill elements */ - INT nExtensions; /* number of extension payloads for this element */ - QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */ + INT extBitsUsed; /* bit consumption of extended fill elements */ + INT nExtensions; /* number of extension payloads for this element */ + QC_OUT_EXTENSION extension[(1)]; /* reffering extension payload */ - INT grantedDynBits; + INT grantedDynBits; - INT grantedPe; - INT grantedPeCorr; + INT grantedPe; + INT grantedPeCorr; - PE_DATA peData; + PE_DATA peData; QC_OUT_CHANNEL *qcOutChannel[(2)]; + UCHAR + *dynMem_Ah_Flag; /* pointer to dynamic buffer used by AhFlag in function + FDKaacEnc_adaptThresholdsToPe() */ + UCHAR + *dynMem_Thr_Exp; /* pointer to dynamic buffer used by ThrExp in function + FDKaacEnc_adaptThresholdsToPe() */ + UCHAR *dynMem_SfbNActiveLinesLdData; /* pointer to dynamic buffer used by + sfbNActiveLinesLdData in function + FDKaacEnc_correctThresh() */ } QC_OUT_ELEMENT; -typedef struct -{ - QC_OUT_ELEMENT *qcElement[(8)]; - QC_OUT_CHANNEL *pQcOutChannels[(8)]; - QC_OUT_EXTENSION extension[(2+2)]; /* global extension payload */ - INT nExtensions; /* number of extension payloads for this AU */ - INT maxDynBits; /* maximal allowed dynamic bits in frame */ - INT grantedDynBits; /* granted dynamic bits in frame */ - INT totFillBits; /* fill bits */ - INT elementExtBits; /* element associated extension payload bits, e.g. sbr, drc ... */ - INT globalExtBits; /* frame/au associated extension payload bits (anc data ...) */ - INT staticBits; /* aac side info bits */ - - INT totalNoRedPe; - INT totalGrantedPeCorr; - - INT usedDynBits; /* number of dynamic bits in use */ - INT alignBits; /* AU alignment bits */ - INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */ +typedef struct { + QC_OUT_ELEMENT *qcElement[((8))]; + QC_OUT_CHANNEL *pQcOutChannels[(8)]; + QC_OUT_EXTENSION extension[(2 + 2)]; /* global extension payload */ + INT nExtensions; /* number of extension payloads for this AU */ + INT maxDynBits; /* maximal allowed dynamic bits in frame */ + INT grantedDynBits; /* granted dynamic bits in frame */ + INT totFillBits; /* fill bits */ + INT elementExtBits; /* element associated extension payload bits, e.g. sbr, + drc ... */ + INT globalExtBits; /* frame/au associated extension payload bits (anc data + ...) */ + INT staticBits; /* aac side info bits */ + + INT totalNoRedPe; + INT totalGrantedPeCorr; + + INT usedDynBits; /* number of dynamic bits in use */ + INT alignBits; /* AU alignment bits */ + INT totalBits; /* sum of static, dyn, sbr, fill, align and dse bits */ } QC_OUT; typedef struct { - INT chBitrateEl; /* channel bitrate in element (totalbitrate*el_relativeBits/el_channels) */ - INT maxBitsEl; /* used in crash recovery */ - INT bitResLevelEl; /* update bitreservoir level in each call of FDKaacEnc_QCMain */ - INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */ - FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/ + INT chBitrateEl; /* channel bitrate in element + (totalbitrate*el_relativeBits/el_channels) */ + INT maxBitsEl; /* used in crash recovery */ + INT bitResLevelEl; /* update bitreservoir level in each call of + FDKaacEnc_QCMain */ + INT maxBitResBitsEl; /* nEffChannels*6144 - averageBitsInFrame */ + FIXP_DBL relativeBitsEl; /* Bits relative to total Bits*/ } ELEMENT_BITS; -typedef struct -{ +typedef struct { /* this is basically struct QC_INIT */ INT globHdrBits; - INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */ - INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */ + INT maxBitsPerFrame; /* maximal allowed bits per frame, 6144*nChannelsEff */ + INT minBitsPerFrame; /* minimal allowd bits per fram, superframing - DRM */ INT nElements; QCDATA_BR_MODE bitrateMode; - INT bitDistributionMode; /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ + AACENC_BITRES_MODE bitResMode; /* 0: full bitreservoir, 1: reduced + bitreservoir, 2: disabled bitreservoir */ INT bitResTot; INT bitResTotMax; - INT maxIterations; /* Maximum number of allowed iterations before FDKaacEnc_crashRecovery() is applied. */ + INT maxIterations; /* Maximum number of allowed iterations before + FDKaacEnc_crashRecovery() is applied. */ INT invQuant; FIXP_DBL vbrQualFactor; @@ -265,16 +288,12 @@ typedef struct PADDING padding; - ELEMENT_BITS *elementBits[(8)]; + ELEMENT_BITS *elementBits[((8))]; BITCNTR_STATE *hBitCounter; ADJ_THR_STATE *hAdjThr; - INT dZoneQuantEnable; /* enable dead zone quantizer */ + INT dZoneQuantEnable; /* enable dead zone quantizer */ } QC_STATE; -#endif /* _QC_DATA_H */ - - - - +#endif /* QC_DATA_H */ diff --git a/libAACenc/src/qc_main.cpp b/libAACenc/src/qc_main.cpp index 9cd73f6..ba3bc7e 100644 --- a/libAACenc/src/qc_main.cpp +++ b/libAACenc/src/qc_main.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Quantizing & coding + Description: Quantizing & coding -******************************************************************************/ +*******************************************************************************/ #include "qc_main.h" #include "quantize.h" @@ -100,6 +112,7 @@ amm-info@iis.fraunhofer.de #include "genericStds.h" +#define AACENC_DZQ_BR_THR 32000 /* Dead zone quantizer bitrate threshold */ typedef struct { QCDATA_BR_MODE bitrateMode; @@ -107,62 +120,57 @@ typedef struct { } TAB_VBR_QUAL_FACTOR; static const TAB_VBR_QUAL_FACTOR tableVbrQualFactor[] = { - {QCDATA_BR_MODE_VBR_1, FL2FXCONST_DBL(0.160f)}, /* 32 kbps mono AAC-LC + SBR + PS */ - {QCDATA_BR_MODE_VBR_2, FL2FXCONST_DBL(0.148f)}, /* 64 kbps stereo AAC-LC + SBR */ - {QCDATA_BR_MODE_VBR_3, FL2FXCONST_DBL(0.135f)}, /* 80 - 96 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_4, FL2FXCONST_DBL(0.111f)}, /* 128 kbps stereo AAC-LC */ - {QCDATA_BR_MODE_VBR_5, FL2FXCONST_DBL(0.070f)} /* 192 kbps stereo AAC-LC */ + {QCDATA_BR_MODE_VBR_1, + FL2FXCONST_DBL(0.160f)}, /* Approx. 32 - 48 (AC-LC), 32 - 56 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_2, + FL2FXCONST_DBL(0.148f)}, /* Approx. 40 - 56 (AC-LC), 40 - 64 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_3, + FL2FXCONST_DBL(0.135f)}, /* Approx. 48 - 64 (AC-LC), 48 - 72 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_4, + FL2FXCONST_DBL(0.111f)}, /* Approx. 64 - 80 (AC-LC), 64 - 88 + (AAC-LD/ELD) kbps/channel */ + {QCDATA_BR_MODE_VBR_5, + FL2FXCONST_DBL(0.070f)} /* Approx. 96 - 120 (AC-LC), 112 - 144 + (AAC-LD/ELD) kbps/channel */ }; -static INT isConstantBitrateMode( - const QCDATA_BR_MODE bitrateMode - ) -{ - return ( ((bitrateMode==QCDATA_BR_MODE_CBR) || (bitrateMode==QCDATA_BR_MODE_SFR) || (bitrateMode==QCDATA_BR_MODE_FF)) ? 1 : 0 ); +static INT isConstantBitrateMode(const QCDATA_BR_MODE bitrateMode) { + return (((bitrateMode == QCDATA_BR_MODE_CBR) || + (bitrateMode == QCDATA_BR_MODE_SFR) || + (bitrateMode == QCDATA_BR_MODE_FF)) + ? 1 + : 0); } +typedef enum { + FRAME_LEN_BYTES_MODULO = 1, + FRAME_LEN_BYTES_INT = 2 +} FRAME_LEN_RESULT_MODE; + +/* forward declarations */ +static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup, + INT sfbPerGroup, INT* RESTRICT sfbOffset, + SHORT* RESTRICT quantSpectrum, + UINT* RESTRICT maxValue); -typedef enum{ - FRAME_LEN_BYTES_MODULO = 1, - FRAME_LEN_BYTES_INT = 2 -}FRAME_LEN_RESULT_MODE; +static void FDKaacEnc_crashRecovery(INT nChannels, + PSY_OUT_ELEMENT* psyOutElement, + QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement, + INT bitsToSave, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); -/* forward declarations */ +static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption( + int* iterations, const int maxIterations, int gainAdjustment, + int* chConstraintsFulfilled, int* calculateQuant, int nChannels, + PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement, + ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, + SCHAR epConfig); -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue); - -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - -static -AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig); - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); +void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC); /***************************************************************************** @@ -173,25 +181,22 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); output: *****************************************************************************/ -static INT FDKaacEnc_calcFrameLen(INT bitRate, - INT sampleRate, - INT granuleLength, - FRAME_LEN_RESULT_MODE mode) -{ - - INT result; +static INT FDKaacEnc_calcFrameLen(INT bitRate, INT sampleRate, + INT granuleLength, + FRAME_LEN_RESULT_MODE mode) { + INT result; - result = ((granuleLength)>>3)*(bitRate); + result = ((granuleLength) >> 3) * (bitRate); - switch(mode) { - case FRAME_LEN_BYTES_MODULO: - result %= sampleRate; - break; - case FRAME_LEN_BYTES_INT: - result /= sampleRate; - break; - } - return(result); + switch (mode) { + case FRAME_LEN_BYTES_MODULO: + result %= sampleRate; + break; + case FRAME_LEN_BYTES_INT: + result /= sampleRate; + break; + } + return (result); } /***************************************************************************** @@ -203,31 +208,25 @@ static INT FDKaacEnc_calcFrameLen(INT bitRate, output: *****************************************************************************/ -static INT FDKaacEnc_framePadding(INT bitRate, - INT sampleRate, - INT granuleLength, - INT *paddingRest) -{ +static INT FDKaacEnc_framePadding(INT bitRate, INT sampleRate, + INT granuleLength, INT* paddingRest) { INT paddingOn; INT difference; paddingOn = 0; - difference = FDKaacEnc_calcFrameLen( bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_MODULO ); - *paddingRest-=difference; + difference = FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength, + FRAME_LEN_BYTES_MODULO); + *paddingRest -= difference; - if (*paddingRest <= 0 ) { + if (*paddingRest <= 0) { paddingOn = 1; *paddingRest += sampleRate; } - return( paddingOn ); + return (paddingOn); } - /********************************************************************************* functionname: FDKaacEnc_QCOutNew @@ -235,48 +234,50 @@ static INT FDKaacEnc_framePadding(INT bitRate, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT** phQC, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR* dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int n, i; int elInc = 0, chInc = 0; - for (n=0; n<nSubFrames; n++) { + for (n = 0; n < nSubFrames; n++) { phQC[n] = GetRam_aacEnc_QCout(n); if (phQC[n] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; goto QCOutNew_bail; } - for (i=0; i<nChannels; i++) { + for (i = 0; i < nChannels; i++) { phQC[n]->pQcOutChannels[i] = GetRam_aacEnc_QCchannel(chInc, dynamic_RAM); - if ( phQC[n]->pQcOutChannels[i] == NULL - ) - { - ErrorStatus = AAC_ENC_NO_MEMORY; - goto QCOutNew_bail; + if (phQC[n]->pQcOutChannels[i] == NULL) { + ErrorStatus = AAC_ENC_NO_MEMORY; + goto QCOutNew_bail; } + chInc++; } /* nChannels */ - for (i=0; i<nElements; i++) { - phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc); - if (phQC[n]->qcElement[i] == NULL) - { + for (i = 0; i < nElements; i++) { + phQC[n]->qcElement[i] = GetRam_aacEnc_QCelement(elInc); + if (phQC[n]->qcElement[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; goto QCOutNew_bail; } elInc++; + + /* initialize pointer to dynamic buffer which are used in adjust + * thresholds */ + phQC[n]->qcElement[i]->dynMem_Ah_Flag = dynamic_RAM + (P_BUF_1); + phQC[n]->qcElement[i]->dynMem_Thr_Exp = + dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE; + phQC[n]->qcElement[i]->dynMem_SfbNActiveLinesLdData = + dynamic_RAM + (P_BUF_1) + ADJ_THR_AH_FLAG_SIZE + ADJ_THR_THR_EXP_SIZE; + } /* nElements */ } /* nSubFrames */ - return AAC_ENC_OK; QCOutNew_bail: @@ -290,21 +291,20 @@ QCOutNew_bail: return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], - const INT nSubFrames, - const CHANNEL_MAPPING *cm) -{ - INT n,i,ch; +AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT* phQC[(1)], const INT nSubFrames, + const CHANNEL_MAPPING* cm) { + INT n, i, ch; - for (n=0; n<nSubFrames; n++) { + for (n = 0; n < nSubFrames; n++) { INT chInc = 0; - for (i=0; i<cm->nElements; i++) { - for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { - phQC[n]->qcElement[i]->qcOutChannel[ch] = phQC[n]->pQcOutChannels[chInc]; + for (i = 0; i < cm->nElements; i++) { + for (ch = 0; ch < cm->elInfo[i].nChannelsInEl; ch++) { + phQC[n]->qcElement[i]->qcOutChannel[ch] = + phQC[n]->pQcOutChannels[chInc]; chInc++; } /* chInEl */ - } /* nElements */ - } /* nSubFrames */ + } /* nElements */ + } /* nSubFrames */ return AAC_ENC_OK; } @@ -316,11 +316,8 @@ AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, - INT nElements - ,UCHAR* dynamic_RAM - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE** phQC, INT nElements, + UCHAR* dynamic_RAM) { AAC_ENCODER_ERROR ErrorStatus; int i; @@ -341,7 +338,7 @@ AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, goto QCNew_bail; } - for (i=0; i<nElements; i++) { + for (i = 0; i < nElements; i++) { hQC->elementBits[i] = GetRam_aacEnc_ElementBits(i); if (hQC->elementBits[i] == NULL) { ErrorStatus = AAC_ENC_NO_MEMORY; @@ -363,52 +360,60 @@ QCNew_bail: return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, - struct QC_INIT *init) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE* hQC, struct QC_INIT* init, + const ULONG initFlags) { + AAC_ENCODER_ERROR err = AAC_ENC_OK; + int i; hQC->maxBitsPerFrame = init->maxBits; hQC->minBitsPerFrame = init->minBits; - hQC->nElements = init->channelMapping->nElements; - hQC->bitResTotMax = init->bitRes; - hQC->bitResTot = init->bitRes; - hQC->maxBitFac = init->maxBitFac; - hQC->bitrateMode = init->bitrateMode; - hQC->invQuant = init->invQuant; - hQC->maxIterations = init->maxIterations; - - if ( isConstantBitrateMode(hQC->bitrateMode) ) { - INT bitresPerChannel = (hQC->bitResTotMax / init->channelMapping->nChannelsEff); - /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir */ - hQC->bitDistributionMode = (bitresPerChannel>BITRES_MIN_LD) ? 0 : (bitresPerChannel>0) ? 1 : 2; + hQC->nElements = init->channelMapping->nElements; + if ((initFlags != 0) || ((init->bitrateMode != QCDATA_BR_MODE_FF) && + (hQC->bitResTotMax != init->bitRes))) { + hQC->bitResTot = init->bitRes; } - else { - hQC->bitDistributionMode = 0; /* full bitreservoir */ + hQC->bitResTotMax = init->bitRes; + hQC->maxBitFac = init->maxBitFac; + hQC->bitrateMode = init->bitrateMode; + hQC->invQuant = init->invQuant; + hQC->maxIterations = init->maxIterations; + + if (isConstantBitrateMode(hQC->bitrateMode)) { + /* 0: full bitreservoir, 1: reduced bitreservoir, 2: disabled bitreservoir + */ + hQC->bitResMode = init->bitResMode; + } else { + hQC->bitResMode = AACENC_BR_MODE_FULL; /* full bitreservoir */ } - hQC->padding.paddingRest = init->padding.paddingRest; hQC->globHdrBits = init->staticBits; /* Bit overhead due to transport */ - FDKaacEnc_InitElementBits(hQC, - init->channelMapping, - init->bitrate, - (init->averageBits/init->nSubFrames) - hQC->globHdrBits, - hQC->maxBitsPerFrame/init->channelMapping->nChannelsEff); + err = FDKaacEnc_InitElementBits( + hQC, init->channelMapping, init->bitrate, + (init->averageBits / init->nSubFrames) - hQC->globHdrBits, + hQC->maxBitsPerFrame / init->channelMapping->nChannelsEff); + if (err != AAC_ENC_OK) goto bail; hQC->vbrQualFactor = FL2FXCONST_DBL(0.f); - for (i=0; i<(int)(sizeof(tableVbrQualFactor)/sizeof(TAB_VBR_QUAL_FACTOR)); i++) { - if (hQC->bitrateMode==tableVbrQualFactor[i].bitrateMode) { + for (i = 0; + i < (int)(sizeof(tableVbrQualFactor) / sizeof(TAB_VBR_QUAL_FACTOR)); + i++) { + if (hQC->bitrateMode == tableVbrQualFactor[i].bitrateMode) { hQC->vbrQualFactor = (FIXP_DBL)tableVbrQualFactor[i].vbrQualFactor; break; } } if (init->channelMapping->nChannelsEff == 1 && - (init->bitrate / init->channelMapping->nChannelsEff) < 32000 && - init->advancedBitsToPe != 0 - ) + (init->bitrate / init->channelMapping->nChannelsEff) < + AACENC_DZQ_BR_THR && + init->isLowDelay != + 0) /* watch out here: init->bitrate is the bitrate "minus" the + standard SBR bitrate (=2500kbps) --> for the FDK the OFFSTE + tuning should start somewhere below 32000kbps-2500kbps ... so + everything is fine here */ { hQC->dZoneQuantEnable = 1; } else { @@ -416,23 +421,20 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, } FDKaacEnc_AdjThrInit( - hQC->hAdjThr, - init->meanPe, - hQC->elementBits, /* or channelBitrates, was: channelBitrate */ - hQC->invQuant, - init->channelMapping->nElements, - init->channelMapping->nChannelsEff, - init->sampleRate, /* output sample rate */ - init->advancedBitsToPe, /* if set, calc bits2PE factor depending on samplerate */ - hQC->vbrQualFactor, - hQC->dZoneQuantEnable - ); - - return AAC_ENC_OK; + hQC->hAdjThr, init->meanPe, hQC->invQuant, init->channelMapping, + init->sampleRate, /* output sample rate */ + init->bitrate, /* total bitrate */ + init->isLowDelay, /* if set, calc bits2PE factor + depending on samplerate */ + init->bitResMode /* for a small bitreservoir, the pe + correction is calc'd differently */ + , + hQC->dZoneQuantEnable, init->bitDistributionMode, hQC->vbrQualFactor); + +bail: + return err; } - - /********************************************************************************* functionname: FDKaacEnc_QCMainPrepare @@ -440,33 +442,28 @@ AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(ELEMENT_INFO *elInfo, - ATS_ELEMENT* RESTRICT adjThrStateElement, - PSY_OUT_ELEMENT* RESTRICT psyOutElement, - QC_OUT_ELEMENT* RESTRICT qcOutElement, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare( + ELEMENT_INFO* elInfo, ATS_ELEMENT* RESTRICT adjThrStateElement, + PSY_OUT_ELEMENT* RESTRICT psyOutElement, + QC_OUT_ELEMENT* RESTRICT qcOutElement, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; - INT nChannels = elInfo->nChannelsInEl; + INT nChannels = elInfo->nChannelsInEl; - PSY_OUT_CHANNEL** RESTRICT psyOutChannel = psyOutElement->psyOutChannel; /* may be modified in-place */ + PSY_OUT_CHANNEL** RESTRICT psyOutChannel = + psyOutElement->psyOutChannel; /* may be modified in-place */ - FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel, nChannels); + FDKaacEnc_CalcFormFactor(qcOutElement->qcOutChannel, psyOutChannel, + nChannels); /* prepare and calculate PE without reduction */ - FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel, qcOutElement->qcOutChannel, &psyOutElement->toolsInfo, adjThrStateElement, nChannels); + FDKaacEnc_peCalculation(&qcOutElement->peData, psyOutChannel, + qcOutElement->qcOutChannel, &psyOutElement->toolsInfo, + adjThrStateElement, nChannels); - ErrorStatus = FDKaacEnc_ChannelElementWrite( NULL, elInfo, NULL, - psyOutElement, - psyOutElement->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &qcOutElement->staticBitsUsed, - 0 ); + ErrorStatus = FDKaacEnc_ChannelElementWrite( + NULL, elInfo, NULL, psyOutElement, psyOutElement->psyOutChannel, + syntaxFlags, aot, epConfig, &qcOutElement->staticBitsUsed, 0); return ErrorStatus; } @@ -474,57 +471,90 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare(ELEMENT_INFO *elInfo, /********************************************************************************* functionname: FDKaacEnc_AdjustBitrate - description: adjusts framelength via padding on a frame to frame basis, - to achieve a bitrate that demands a non byte aligned - framelength - return: errorcode + description: adjusts framelength via padding on a frame to frame +basis, to achieve a bitrate that demands a non byte aligned framelength return: +errorcode **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC, - CHANNEL_MAPPING *RESTRICT cm, - INT *avgTotalBits, - INT bitRate, /* total bitrate */ - INT sampleRate, /* output sampling rate */ - INT granuleLength) /* frame length */ +AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate( + QC_STATE* RESTRICT hQC, CHANNEL_MAPPING* RESTRICT cm, INT* avgTotalBits, + INT bitRate, /* total bitrate */ + INT sampleRate, /* output sampling rate */ + INT granuleLength) /* frame length */ { INT paddingOn; INT frameLen; /* Do we need an extra padding byte? */ - paddingOn = FDKaacEnc_framePadding(bitRate, - sampleRate, - granuleLength, - &hQC->padding.paddingRest); + paddingOn = FDKaacEnc_framePadding(bitRate, sampleRate, granuleLength, + &hQC->padding.paddingRest); - frameLen = paddingOn + FDKaacEnc_calcFrameLen(bitRate, - sampleRate, - granuleLength, - FRAME_LEN_BYTES_INT); + frameLen = + paddingOn + FDKaacEnc_calcFrameLen(bitRate, sampleRate, granuleLength, + FRAME_LEN_BYTES_INT); - *avgTotalBits = frameLen<<3; + *avgTotalBits = frameLen << 3; return AAC_ENC_OK; } -static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQC, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm, - INT codeBits) -{ +#define isAudioElement(elType) \ + ((elType == ID_SCE) || (elType == ID_CPE) || (elType == ID_LFE)) + +/********************************************************************************* - INT i, firstEl = cm->nElements-1; - INT totalBits = 0; + functionname: FDKaacEnc_distributeElementDynBits + description: distributes all bits over all elements. The relative bit + distibution is described in the ELEMENT_INFO of the + appropriate element. The bit distribution table is + initialized in FDKaacEnc_InitChannelMapping(). + return: errorcode - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - qcElement[i]->grantedDynBits = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)codeBits); +**********************************************************************************/ +static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits( + QC_STATE* hQC, QC_OUT_ELEMENT* qcElement[((8))], CHANNEL_MAPPING* cm, + INT codeBits) { + INT i; /* counter variable */ + INT totalBits = 0; /* sum of bits over all elements */ + + for (i = (cm->nElements - 1); i >= 0; i--) { + if (isAudioElement(cm->elInfo[i].elType)) { + qcElement[i]->grantedDynBits = + fMax(0, fMultI(hQC->elementBits[i]->relativeBitsEl, codeBits)); totalBits += qcElement[i]->grantedDynBits; - firstEl = i; } } - qcElement[firstEl]->grantedDynBits += codeBits - totalBits; + + /* Due to inaccuracies with the multiplication, codeBits may differ from + totalBits. For that case, the difference must be added/substracted again + to/from one element, i.e: + Negative differences are substracted from the element with the most bits. + Positive differences are added to the element with the least bits. + */ + if (codeBits != totalBits) { + INT elMaxBits = cm->nElements - 1; /* element with the most bits */ + INT elMinBits = cm->nElements - 1; /* element with the least bits */ + + /* Search for biggest and smallest audio element */ + for (i = (cm->nElements - 1); i >= 0; i--) { + if (isAudioElement(cm->elInfo[i].elType)) { + if (qcElement[i]->grantedDynBits > + qcElement[elMaxBits]->grantedDynBits) { + elMaxBits = i; + } + if (qcElement[i]->grantedDynBits < + qcElement[elMinBits]->grantedDynBits) { + elMinBits = i; + } + } + } + /* Compensate for bit distibution difference */ + if (codeBits - totalBits > 0) { + qcElement[elMinBits]->grantedDynBits += codeBits - totalBits; + } else { + qcElement[elMaxBits]->grantedDynBits += codeBits - totalBits; + } + } return AAC_ENC_OK; } @@ -532,12 +562,13 @@ static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQ /** * \brief Verify whether minBitsPerFrame criterion can be satisfied. * - * This function evaluates the bit consumption only if minBitsPerFrame parameter is not 0. - * In hyperframing mode the difference between grantedDynBits and usedDynBits of all sub frames - * results the number of fillbits to be written. - * This bits can be distrubitued in superframe to reach minBitsPerFrame bit consumption in single AU's. - * The return value denotes if enough desired fill bits are available to achieve minBitsPerFrame in all frames. - * This check can only be used within superframes. + * This function evaluates the bit consumption only if minBitsPerFrame parameter + * is not 0. In hyperframing mode the difference between grantedDynBits and + * usedDynBits of all sub frames results the number of fillbits to be written. + * This bits can be distrubitued in superframe to reach minBitsPerFrame bit + * consumption in single AU's. The return value denotes if enough desired fill + * bits are available to achieve minBitsPerFrame in all frames. This check can + * only be used within superframes. * * \param qcOut Pointer to coding data struct. * \param minBitsPerFrame Minimal number of bits to be consumed in each frame. @@ -547,12 +578,8 @@ static AAC_ENCODER_ERROR FDKaacEnc_distributeElementDynBits(QC_STATE* hQ * - 1: all fine * - 0: criterion not fulfilled */ -static int checkMinFrameBitsDemand( - QC_OUT** qcOut, - const INT minBitsPerFrame, - const INT nSubFrames - ) -{ +static int checkMinFrameBitsDemand(QC_OUT** qcOut, const INT minBitsPerFrame, + const INT nSubFrames) { int result = 1; /* all fine*/ return result; } @@ -568,33 +595,26 @@ static int checkMinFrameBitsDemand( return: number of static bits **********************************************************************************/ -static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, - PSY_OUT** psyOut) -{ +static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, + PSY_OUT** psyOut) { AUDIO_OBJECT_TYPE aot = AOT_AAC_LC; - UINT syntaxFlags = 0; + UINT syntaxFlags = 0; SCHAR epConfig = -1; int i, bitcount = 0; - for (i=0; i<cm->nElements; i++) { - ELEMENT_INFO elInfo = cm->elInfo[i]; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ( (elInfo.elType == ID_SCE) - || (elInfo.elType == ID_CPE) - || (elInfo.elType == ID_LFE) ) - { - INT minElBits = 0; - - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOut[0]->psyOutElement[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - syntaxFlags, - aot, - epConfig, - &minElBits, - 1 ); - bitcount += minElBits; - } + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + INT minElBits = 0; + + FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, + psyOut[0]->psyOutElement[i], + psyOut[0]->psyOutElement[i]->psyOutChannel, + syntaxFlags, aot, epConfig, &minElBits, 1); + bitcount += minElBits; + } } return bitcount; @@ -602,201 +622,184 @@ static int FDKaacEnc_getMinimalStaticBitdemand(CHANNEL_MAPPING* cm, //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution(QC_STATE* hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - CHANNEL_MAPPING* cm, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - INT avgTotalBits, - INT *totalAvailableBits, - INT *avgTotalDynBits) -{ - int i; - /* get maximal allowed dynamic bits */ - qcOut[0]->grantedDynBits = (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits)&~7; - qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame)&~7) - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - /* assure that enough bits are available */ - if ((qcOut[0]->grantedDynBits+hQC->bitResTot) < 0) { - /* crash recovery allows to reduce static bits to a minimum */ - if ( (qcOut[0]->grantedDynBits+hQC->bitResTot) < (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut)-qcOut[0]->staticBits) ) - return AAC_ENC_BITRES_TOO_LOW; - } +static AAC_ENCODER_ERROR FDKaacEnc_prepareBitDistribution( + QC_STATE* hQC, PSY_OUT** psyOut, QC_OUT** qcOut, CHANNEL_MAPPING* cm, + QC_OUT_ELEMENT* qcElement[(1)][((8))], INT avgTotalBits, + INT* totalAvailableBits, INT* avgTotalDynBits) { + int i; + /* get maximal allowed dynamic bits */ + qcOut[0]->grantedDynBits = + (fixMin(hQC->maxBitsPerFrame, avgTotalBits) - hQC->globHdrBits) & ~7; + qcOut[0]->grantedDynBits -= (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + qcOut[0]->maxDynBits = ((hQC->maxBitsPerFrame) & ~7) - + (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + /* assure that enough bits are available */ + if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < 0) { + /* crash recovery allows to reduce static bits to a minimum */ + if ((qcOut[0]->grantedDynBits + hQC->bitResTot) < + (FDKaacEnc_getMinimalStaticBitdemand(cm, psyOut) - + qcOut[0]->staticBits)) + return AAC_ENC_BITRES_TOO_LOW; + } - /* distribute dynamic bits to each element */ - FDKaacEnc_distributeElementDynBits(hQC, - qcElement[0], - cm, - qcOut[0]->grantedDynBits); + /* distribute dynamic bits to each element */ + FDKaacEnc_distributeElementDynBits(hQC, qcElement[0], cm, + qcOut[0]->grantedDynBits); - *avgTotalDynBits = 0; /*frameDynBits;*/ + *avgTotalDynBits = 0; /*frameDynBits;*/ - *totalAvailableBits = avgTotalBits; + *totalAvailableBits = avgTotalBits; - /* sum up corrected granted PE */ - qcOut[0]->totalGrantedPeCorr = 0; + /* sum up corrected granted PE */ + qcOut[0]->totalGrantedPeCorr = 0; - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - int nChannels = elInfo.nChannelsInEl; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + int nChannels = elInfo.nChannelsInEl; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - FDKaacEnc_DistributeBits(hQC->hAdjThr, - hQC->hAdjThr->adjThrStateElem[i], - psyOut[0]->psyOutElement[i]->psyOutChannel, - &qcElement[0][i]->peData, - &qcElement[0][i]->grantedPe, - &qcElement[0][i]->grantedPeCorr, - nChannels, - psyOut[0]->psyOutElement[i]->commonWindow, - qcElement[0][i]->grantedDynBits, - hQC->elementBits[i]->bitResLevelEl, - hQC->elementBits[i]->maxBitResBitsEl, - hQC->maxBitFac, - hQC->bitDistributionMode); - - *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl; - /* get total corrected granted PE */ - qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - *totalAvailableBits = FDKmin(hQC->maxBitsPerFrame, (*totalAvailableBits)); - - return AAC_ENC_OK; + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for ( all sub frames ) ... */ + FDKaacEnc_DistributeBits( + hQC->hAdjThr, hQC->hAdjThr->adjThrStateElem[i], + psyOut[0]->psyOutElement[i]->psyOutChannel, &qcElement[0][i]->peData, + &qcElement[0][i]->grantedPe, &qcElement[0][i]->grantedPeCorr, + nChannels, psyOut[0]->psyOutElement[i]->commonWindow, + qcElement[0][i]->grantedDynBits, hQC->elementBits[i]->bitResLevelEl, + hQC->elementBits[i]->maxBitResBitsEl, hQC->maxBitFac, + hQC->bitResMode); + + *totalAvailableBits += hQC->elementBits[i]->bitResLevelEl; + /* get total corrected granted PE */ + qcOut[0]->totalGrantedPeCorr += qcElement[0][i]->grantedPeCorr; + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + + } /* -end- element loop */ + + *totalAvailableBits = fMin(hQC->maxBitsPerFrame, (*totalAvailableBits)); + + return AAC_ENC_OK; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits(INT* sumDynBitsConsumed, - QC_OUT_ELEMENT* qcElement[(8)], - CHANNEL_MAPPING* cm) -{ +static AAC_ENCODER_ERROR FDKaacEnc_updateUsedDynBits( + INT* sumDynBitsConsumed, QC_OUT_ELEMENT* qcElement[((8))], + CHANNEL_MAPPING* cm) { INT i; *sumDynBitsConsumed = 0; - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* sum up bits consumed */ - *sumDynBitsConsumed += qcElement[i]->dynBitsUsed; - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* sum up bits consumed */ + *sumDynBitsConsumed += qcElement[i]->dynBitsUsed; + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - } /* -end- element loop */ + } /* -end- element loop */ return AAC_ENC_OK; } +static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, INT nSubFrames) { + INT c, totalBits = 0; -static INT FDKaacEnc_getTotalConsumedDynBits(QC_OUT** qcOut, - INT nSubFrames) -{ - INT c, totalBits=0; - - /* sum up bit consumption for all sub frames */ - for (c=0; c<nSubFrames; c++) - { - /* bit consumption not valid if dynamic bits - not available in one sub frame */ - if (qcOut[c]->usedDynBits==-1) return -1; - totalBits += qcOut[c]->usedDynBits; - } - - return totalBits; + /* sum up bit consumption for all sub frames */ + for (c = 0; c < nSubFrames; c++) { + /* bit consumption not valid if dynamic bits + not available in one sub frame */ + if (qcOut[c]->usedDynBits == -1) return -1; + totalBits += qcOut[c]->usedDynBits; + } + return totalBits; } -static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut, - QC_OUT_ELEMENT* qcElement[(1)][(8)], - CHANNEL_MAPPING* cm, - INT globHdrBits, - INT nSubFrames) -{ - int c, i; - int totalUsedBits = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - int dataBits = 0; - for (i=0; i<cm->nElements; i++) - { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - dataBits += qcElement[c][i]->dynBitsUsed + qcElement[c][i]->staticBitsUsed + qcElement[c][i]->extBitsUsed; - } - } - dataBits += qcOut[c]->globalExtBits; - - totalUsedBits += (8 - (dataBits) % 8) % 8; - totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */ +static INT FDKaacEnc_getTotalConsumedBits(QC_OUT** qcOut, + QC_OUT_ELEMENT* qcElement[(1)][((8))], + CHANNEL_MAPPING* cm, INT globHdrBits, + INT nSubFrames) { + int c, i; + int totalUsedBits = 0; + + for (c = 0; c < nSubFrames; c++) { + int dataBits = 0; + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + dataBits += qcElement[c][i]->dynBitsUsed + + qcElement[c][i]->staticBitsUsed + + qcElement[c][i]->extBitsUsed; + } } - return totalUsedBits; + dataBits += qcOut[c]->globalExtBits; + + totalUsedBits += (8 - (dataBits) % 8) % 8; + totalUsedBits += dataBits + globHdrBits; /* header bits for every frame */ + } + return totalUsedBits; } static AAC_ENCODER_ERROR FDKaacEnc_BitResRedistribution( - QC_STATE *const hQC, - const CHANNEL_MAPPING *const cm, - const INT avgTotalBits - ) -{ - /* check bitreservoir fill level */ - if (hQC->bitResTot < 0) { - return AAC_ENC_BITRES_TOO_LOW; - } - else if (hQC->bitResTot > hQC->bitResTotMax) { - return AAC_ENC_BITRES_TOO_HIGH; + QC_STATE* const hQC, const CHANNEL_MAPPING* const cm, + const INT avgTotalBits) { + /* check bitreservoir fill level */ + if (hQC->bitResTot < 0) { + return AAC_ENC_BITRES_TOO_LOW; + } else if (hQC->bitResTot > hQC->bitResTotMax) { + return AAC_ENC_BITRES_TOO_HIGH; + } else { + INT i; + INT totalBits = 0, totalBits_max = 0; + + const int totalBitreservoir = + fMin(hQC->bitResTot, (hQC->maxBitsPerFrame - avgTotalBits)); + const int totalBitreservoirMax = + fMin(hQC->bitResTotMax, (hQC->maxBitsPerFrame - avgTotalBits)); + + for (i = (cm->nElements - 1); i >= 0; i--) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + hQC->elementBits[i]->bitResLevelEl = + fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoir); + totalBits += hQC->elementBits[i]->bitResLevelEl; + + hQC->elementBits[i]->maxBitResBitsEl = + fMultI(hQC->elementBits[i]->relativeBitsEl, totalBitreservoirMax); + totalBits_max += hQC->elementBits[i]->maxBitResBitsEl; + } } - else { - INT i, firstEl = cm->nElements-1; - INT totalBits = 0, totalBits_max = 0; - - int totalBitreservoir = FDKmin(hQC->bitResTot, (hQC->maxBitsPerFrame-avgTotalBits)); - int totalBitreservoirMax = FDKmin(hQC->bitResTotMax, (hQC->maxBitsPerFrame-avgTotalBits)); - - int sc_bitResTot = CountLeadingBits(totalBitreservoir); - int sc_bitResTotMax = CountLeadingBits(totalBitreservoirMax); - - for (i=(cm->nElements-1); i>=0; i--) { - if ((cm->elInfo[i].elType == ID_SCE) || (cm->elInfo[i].elType == ID_CPE) || - (cm->elInfo[i].elType == ID_LFE)) - { - hQC->elementBits[i]->bitResLevelEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoir<<sc_bitResTot))>>sc_bitResTot; - totalBits += hQC->elementBits[i]->bitResLevelEl; - - hQC->elementBits[i]->maxBitResBitsEl = (INT)fMult(hQC->elementBits[i]->relativeBitsEl, (FIXP_DBL)(totalBitreservoirMax<<sc_bitResTotMax))>>sc_bitResTotMax; - totalBits_max += hQC->elementBits[i]->maxBitResBitsEl; - - firstEl = i; - } + for (i = 0; i < cm->nElements; i++) { + if ((cm->elInfo[i].elType == ID_SCE) || + (cm->elInfo[i].elType == ID_CPE) || + (cm->elInfo[i].elType == ID_LFE)) { + int deltaBits = fMax(totalBitreservoir - totalBits, + -hQC->elementBits[i]->bitResLevelEl); + hQC->elementBits[i]->bitResLevelEl += deltaBits; + totalBits += deltaBits; + + deltaBits = fMax(totalBitreservoirMax - totalBits_max, + -hQC->elementBits[i]->maxBitResBitsEl); + hQC->elementBits[i]->maxBitResBitsEl += deltaBits; + totalBits_max += deltaBits; } - hQC->elementBits[firstEl]->bitResLevelEl += totalBitreservoir - totalBits; - hQC->elementBits[firstEl]->maxBitResBitsEl += totalBitreservoirMax - totalBits_max; } + } - return AAC_ENC_OK; + return AAC_ENC_OK; } - -AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - INT avgTotalBits, - CHANNEL_MAPPING* cm - ,AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ) -{ +AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, PSY_OUT** psyOut, + QC_OUT** qcOut, INT avgTotalBits, + CHANNEL_MAPPING* cm, + const AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { int i, c; AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; INT avgTotalDynBits = 0; /* maximal allowed dynamic bits for all frames */ @@ -814,363 +817,314 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, /* fastenc needs one time threshold simulation, in case of multiple frames, one more guess has to be calculated */ - /*-------------------------------------------- */ - /* helper pointer */ - QC_OUT_ELEMENT* qcElement[(1)][(8)]; + /*-------------------------------------------- */ + /* helper pointer */ + QC_OUT_ELEMENT* qcElement[(1)][((8))]; - /* work on a copy of qcChannel and qcElement */ - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; + /* work on a copy of qcChannel and qcElement */ + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - { - qcElement[c][i] = qcOut[c]->qcElement[i]; - } - } - } + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + { qcElement[c][i] = qcOut[c]->qcElement[i]; } } + } + } - /*-------------------------------------------- */ - /*-------------------------------------------- */ - if ( isConstantBitrateMode(hQC->bitrateMode) ) - { - /* calc granted dynamic bits for sub frame and - distribute it to each element */ - ErrorStatus = FDKaacEnc_prepareBitDistribution( - hQC, - psyOut, - qcOut, - cm, - qcElement, - avgTotalBits, - &totalAvailableBits, - &avgTotalDynBits); - - if (ErrorStatus != AAC_ENC_OK) { - return ErrorStatus; - } - } - else { - qcOut[0]->grantedDynBits = ((hQC->maxBitsPerFrame - (hQC->globHdrBits))&~7) - - (qcOut[0]->globalExtBits + qcOut[0]->staticBits + qcOut[0]->elementExtBits); - qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits; + /*-------------------------------------------- */ + /*-------------------------------------------- */ + if (isConstantBitrateMode(hQC->bitrateMode)) { + /* calc granted dynamic bits for sub frame and + distribute it to each element */ + ErrorStatus = FDKaacEnc_prepareBitDistribution( + hQC, psyOut, qcOut, cm, qcElement, avgTotalBits, &totalAvailableBits, + &avgTotalDynBits); + + if (ErrorStatus != AAC_ENC_OK) { + return ErrorStatus; + } + } else { + qcOut[0]->grantedDynBits = + ((hQC->maxBitsPerFrame - (hQC->globHdrBits)) & ~7) - + (qcOut[0]->globalExtBits + qcOut[0]->staticBits + + qcOut[0]->elementExtBits); + qcOut[0]->maxDynBits = qcOut[0]->grantedDynBits; + + totalAvailableBits = hQC->maxBitsPerFrame; + avgTotalDynBits = 0; + } - totalAvailableBits = hQC->maxBitsPerFrame; - avgTotalDynBits = 0; - } + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + /* for CBR and VBR mode */ + FDKaacEnc_AdjustThresholds(hQC->hAdjThr, qcElement[c], qcOut[c], + psyOut[c]->psyOutElement, + isConstantBitrateMode(hQC->bitrateMode), cm); -#ifdef PNS_PRECOUNT_ENABLE - /* Calculate estimated pns bits and substract them from grantedDynBits to get a more accurate number of available bits. */ - if (syntaxFlags & (AC_LD|AC_ELD)) - { - int estimatedPnsBits = 0, ch; + } /* -end- sub frame counter */ - for (ch=0; ch<cm->nChannels; ch++) { - qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits = noisePreCount(psyOut[0]->pPsyOutChannels[ch]->noiseNrg, psyOut[0]->pPsyOutChannels[ch]->maxSfbPerGroup); - estimatedPnsBits += qcOut[0]->pQcOutChannels[ch]->sectionData.noiseNrgBits; + /*-------------------------------------------- */ + INT iterations[(1)][((8))]; + INT chConstraintsFulfilled[(1)][((8))][(2)]; + INT calculateQuant[(1)][((8))][(2)]; + INT constraintsFulfilled[(1)][((8))]; + /*-------------------------------------------- */ + + /* for ( all sub frames ) ... */ + for (c = 0; c < nSubFrames; c++) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + INT ch, nChannels = elInfo.nChannelsInEl; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* Turn thresholds into scalefactors, optimize bit consumption and + * verify conformance */ + FDKaacEnc_EstimateScaleFactors( + psyOut[c]->psyOutElement[i]->psyOutChannel, + qcElement[c][i]->qcOutChannel, hQC->invQuant, hQC->dZoneQuantEnable, + cm->elInfo[i].nChannelsInEl); + + /*-------------------------------------------- */ + constraintsFulfilled[c][i] = 1; + iterations[c][i] = 0; + + for (ch = 0; ch < nChannels; ch++) { + chConstraintsFulfilled[c][i][ch] = 1; + calculateQuant[c][i][ch] = 1; } - qcOut[0]->grantedDynBits -= estimatedPnsBits; - } -#endif - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - /* for CBR and VBR mode */ - FDKaacEnc_AdjustThresholds(hQC->hAdjThr->adjThrStateElem, - qcElement[c], - qcOut[c], - psyOut[c]->psyOutElement, - isConstantBitrateMode(hQC->bitrateMode), - hQC->hAdjThr->maxIter2ndGuess, - cm); + /*-------------------------------------------- */ - } /* -end- sub frame counter */ + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - /*-------------------------------------------- */ - INT iterations[(1)][(8)]; - INT chConstraintsFulfilled[(1)][(8)][(2)]; - INT calculateQuant[(1)][(8)][(2)]; - INT constraintsFulfilled[(1)][(8)]; - /*-------------------------------------------- */ + } /* -end- element loop */ + qcOut[c]->usedDynBits = -1; - /* for ( all sub frames ) ... */ - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; i<cm->nElements; i++) + } /* -end- sub frame counter */ + + INT quantizationDone = 0; + INT sumDynBitsConsumedTotal = 0; + INT decreaseBitConsumption = -1; /* no direction yet! */ + + /*-------------------------------------------- */ + /* -start- Quantization loop ... */ + /*-------------------------------------------- */ + do /* until max allowed bits per frame and maxDynBits!=-1*/ + { + quantizationDone = 0; + + c = 0; /* get frame to process */ + + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; + INT ch, nChannels = elInfo.nChannelsInEl; + + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + do /* until element bits < nChannels*MIN_BUFSIZE_PER_EFF_CHAN */ + { + do /* until spectral values < MAX_QUANT */ { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; + /*-------------------------------------------- */ + if (!constraintsFulfilled[c][i]) { + if ((ErrorStatus = FDKaacEnc_reduceBitConsumption( + &iterations[c][i], hQC->maxIterations, + (decreaseBitConsumption) ? 1 : -1, + chConstraintsFulfilled[c][i], calculateQuant[c][i], + nChannels, psyOut[c]->psyOutElement[i], qcOut[c], + qcElement[c][i], hQC->elementBits[i], aot, syntaxFlags, + epConfig)) != AAC_ENC_OK) { + return ErrorStatus; + } + } - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* Turn thresholds into scalefactors, optimize bit consumption and verify conformance */ - FDKaacEnc_EstimateScaleFactors(psyOut[c]->psyOutElement[i]->psyOutChannel, - qcElement[c][i]->qcOutChannel, - hQC->invQuant, - hQC->dZoneQuantEnable, - cm->elInfo[i].nChannelsInEl); + /*-------------------------------------------- */ + /*-------------------------------------------- */ + constraintsFulfilled[c][i] = 1; + + /*-------------------------------------------- */ + /* quantize spectrum (per each channel) */ + for (ch = 0; ch < nChannels; ch++) { + /*-------------------------------------------- */ + chConstraintsFulfilled[c][i][ch] = 1; + + /*-------------------------------------------- */ + + if (calculateQuant[c][i][ch]) { + QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; + PSY_OUT_CHANNEL* psyOutCh = + psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; + + calculateQuant[c][i][ch] = + 0; /* calculate quantization only if necessary */ + + /*-------------------------------------------- */ + FDKaacEnc_QuantizeSpectrum( + psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup, + psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets, + qcOutCh->mdctSpectrum, qcOutCh->globalGain, qcOutCh->scf, + qcOutCh->quantSpec, hQC->dZoneQuantEnable); + + /*-------------------------------------------- */ + if (FDKaacEnc_calcMaxValueInSfb( + psyOutCh->sfbCnt, psyOutCh->maxSfbPerGroup, + psyOutCh->sfbPerGroup, psyOutCh->sfbOffsets, + qcOutCh->quantSpec, + qcOutCh->maxValueInSfb) > MAX_QUANT) { + chConstraintsFulfilled[c][i][ch] = 0; + constraintsFulfilled[c][i] = 0; + /* if quanizted value out of range; increase global gain! */ + decreaseBitConsumption = 1; + } + /*-------------------------------------------- */ - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1; - iterations[c][i] = 0 ; + } /* if calculateQuant[c][i][ch] */ - for (ch = 0; ch < nChannels; ch++) - { - chConstraintsFulfilled[c][i][ch] = 1; - calculateQuant[c][i][ch] = 1; - } + } /* channel loop */ - /*-------------------------------------------- */ + /*-------------------------------------------- */ + /* quantize spectrum (per each channel) */ - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ + /*-------------------------------------------- */ - } /* -end- element loop */ + } while (!constraintsFulfilled[c][i]); /* does not regard bit + consumption */ - qcOut[c]->usedDynBits = -1; + /*-------------------------------------------- */ + /*-------------------------------------------- */ + qcElement[c][i]->dynBitsUsed = 0; /* reset dynamic bits */ + + /* quantization valid in current channel! */ + for (ch = 0; ch < nChannels; ch++) { + QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; + PSY_OUT_CHANNEL* psyOutCh = + psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; + + /* count dynamic bits */ + INT chDynBits = FDKaacEnc_dynBitCount( + hQC->hBitCounter, qcOutCh->quantSpec, qcOutCh->maxValueInSfb, + qcOutCh->scf, psyOutCh->lastWindowSequence, psyOutCh->sfbCnt, + psyOutCh->maxSfbPerGroup, psyOutCh->sfbPerGroup, + psyOutCh->sfbOffsets, &qcOutCh->sectionData, psyOutCh->noiseNrg, + psyOutCh->isBook, psyOutCh->isScale, syntaxFlags); + + /* sum up dynamic channel bits */ + qcElement[c][i]->dynBitsUsed += chDynBits; + } - } /* -end- sub frame counter */ + /* save dynBitsUsed for correction of bits2pe relation */ + if (hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast == -1) { + hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast = + qcElement[c][i]->dynBitsUsed; + } + /* hold total bit consumption in present element below maximum allowed + */ + if (qcElement[c][i]->dynBitsUsed > + ((nChannels * MIN_BUFSIZE_PER_EFF_CHAN) - + qcElement[c][i]->staticBitsUsed - + qcElement[c][i]->extBitsUsed)) { + constraintsFulfilled[c][i] = 0; + } + } while (!constraintsFulfilled[c][i]); - INT quantizationDone = 0; - INT sumDynBitsConsumedTotal = 0; - INT decreaseBitConsumption = -1; /* no direction yet! */ + } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - /*-------------------------------------------- */ - /* -start- Quantization loop ... */ - /*-------------------------------------------- */ - do /* until max allowed bits per frame and maxDynBits!=-1*/ - { - quantizationDone = 0; - - c = 0; /* get frame to process */ - - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - INT ch, nChannels = elInfo.nChannelsInEl; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - do /* until spectral values < MAX_QUANT */ - { - /*-------------------------------------------- */ - if (!constraintsFulfilled[c][i]) - { - FDKaacEnc_reduceBitConsumption(&iterations[c][i], - hQC->maxIterations, - (decreaseBitConsumption) ? 1 : -1, - chConstraintsFulfilled[c][i], - calculateQuant[c][i], - nChannels, - psyOut[c]->psyOutElement[i], - qcOut[c], - qcElement[c][i], - hQC->elementBits[i], - aot, - syntaxFlags, - epConfig); - } - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - constraintsFulfilled[c][i] = 1 ; - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - for (ch = 0; ch < nChannels; ch++) - { - /*-------------------------------------------- */ - chConstraintsFulfilled[c][i][ch] = 1; - - /*-------------------------------------------- */ - - if (calculateQuant[c][i][ch]) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL* psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - calculateQuant[c][i][ch] = 0; /* calculate quantization only if necessary */ - - /*-------------------------------------------- */ - FDKaacEnc_QuantizeSpectrum(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->mdctSpectrum, - qcOutCh->globalGain, - qcOutCh->scf, - qcOutCh->quantSpec, - hQC->dZoneQuantEnable); - - /*-------------------------------------------- */ - if (FDKaacEnc_calcMaxValueInSfb(psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb) > MAX_QUANT) - { - chConstraintsFulfilled[c][i][ch] = 0; - constraintsFulfilled[c][i] = 0 ; - /* if quanizted value out of range; increase global gain! */ - decreaseBitConsumption = 1; - } - - /*-------------------------------------------- */ - - } /* if calculateQuant[c][i][ch] */ - - } /* channel loop */ - - /*-------------------------------------------- */ - /* quantize spectrum (per each channel) */ - - /*-------------------------------------------- */ - - } while (!constraintsFulfilled[c][i]) ; /* does not regard bit consumption */ - - - /*-------------------------------------------- */ - /*-------------------------------------------- */ - qcElement[c][i]->dynBitsUsed = 0 ; /* reset dynamic bits */ - - /* quantization valid in current channel! */ - for (ch = 0; ch < nChannels; ch++) - { - QC_OUT_CHANNEL* qcOutCh = qcElement[c][i]->qcOutChannel[ch]; - PSY_OUT_CHANNEL *psyOutCh = psyOut[c]->psyOutElement[i]->psyOutChannel[ch]; - - /* count dynamic bits */ - INT chDynBits = FDKaacEnc_dynBitCount(hQC->hBitCounter, - qcOutCh->quantSpec, - qcOutCh->maxValueInSfb, - qcOutCh->scf, - psyOutCh->lastWindowSequence, - psyOutCh->sfbCnt, - psyOutCh->maxSfbPerGroup, - psyOutCh->sfbPerGroup, - psyOutCh->sfbOffsets, - &qcOutCh->sectionData, - psyOutCh->noiseNrg, - psyOutCh->isBook, - psyOutCh->isScale, - syntaxFlags) ; - - /* sum up dynamic channel bits */ - qcElement[c][i]->dynBitsUsed += chDynBits; - } - - /* save dynBitsUsed for correction of bits2pe relation */ - if(hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast==-1) { - hQC->hAdjThr->adjThrStateElem[i]->dynBitsLast = qcElement[c][i]->dynBitsUsed; - } - } /* -end- if(ID_SCE || ID_CPE || ID_LFE) */ - - } /* -end- element loop */ - - /* update dynBits of current subFrame */ - FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, - qcElement[c], - cm); - - /* get total consumed bits, dyn bits in all sub frames have to be valid */ - sumDynBitsConsumedTotal = FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames); - - if (sumDynBitsConsumedTotal==-1) - { - quantizationDone = 0; /* bit consumption not valid in all sub frames */ - } - else - { - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - - /* in all frames are valid dynamic bits */ - if ( ((sumBitsConsumedTotal < totalAvailableBits) || qcOut[c]->usedDynBits==0) && (decreaseBitConsumption==1) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames) - /*()*/ ) - { - quantizationDone = 1; /* exit bit adjustment */ - } - if (sumBitsConsumedTotal > totalAvailableBits && (decreaseBitConsumption==0) ) -// /*()*/ ) - { - quantizationDone = 0; /* reset! */ - break; - } - } + } /* -end- element loop */ + /* update dynBits of current subFrame */ + FDKaacEnc_updateUsedDynBits(&qcOut[c]->usedDynBits, qcElement[c], cm); - /*-------------------------------------------- */ + /* get total consumed bits, dyn bits in all sub frames have to be valid */ + sumDynBitsConsumedTotal = + FDKaacEnc_getTotalConsumedDynBits(qcOut, nSubFrames); - int emergencyIterations = 1; - int dynBitsOvershoot = 0; - - for (c = 0 ; c < nSubFrames ; c++ ) - { - for (i=0; i<cm->nElements; i++) - { - ELEMENT_INFO elInfo = cm->elInfo[i]; - - if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || - (elInfo.elType == ID_LFE)) - { - /* iteration limitation */ - emergencyIterations &= ((iterations[c][i] < hQC->maxIterations) ? 0 : 1); - } - } - /* detection if used dyn bits exceeds the maximal allowed criterion */ - dynBitsOvershoot |= ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0); - } + if (sumDynBitsConsumedTotal == -1) { + quantizationDone = 0; /* bit consumption not valid in all sub frames */ + } else { + int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits( + qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - if (quantizationDone==0 || dynBitsOvershoot) - { + /* in all frames are valid dynamic bits */ + if (((sumBitsConsumedTotal < totalAvailableBits) || + sumDynBitsConsumedTotal == 0) && + (decreaseBitConsumption == 1) && + checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames) + /*()*/) { + quantizationDone = 1; /* exit bit adjustment */ + } + if (sumBitsConsumedTotal > totalAvailableBits && + (decreaseBitConsumption == 0)) { + quantizationDone = 0; /* reset! */ + } + } - int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits(qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); + /*-------------------------------------------- */ - if ( (sumDynBitsConsumedTotal >= avgTotalDynBits) || (sumDynBitsConsumedTotal==0) ) { - quantizationDone = 1; - } - if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) { - quantizationDone = 1; - } - if ((sumBitsConsumedTotal > totalAvailableBits) || !checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - quantizationDone = 0; - } - if ((sumBitsConsumedTotal < totalAvailableBits) && checkMinFrameBitsDemand(qcOut,hQC->minBitsPerFrame,nSubFrames)) { - decreaseBitConsumption = 0; - } - else { - decreaseBitConsumption = 1; - } + int emergencyIterations = 1; + int dynBitsOvershoot = 0; - if (dynBitsOvershoot) { - quantizationDone = 0; - decreaseBitConsumption = 1; - } + for (c = 0; c < nSubFrames; c++) { + for (i = 0; i < cm->nElements; i++) { + ELEMENT_INFO elInfo = cm->elInfo[i]; - /* reset constraints fullfilled flags */ - FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled)); - FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled)); + if ((elInfo.elType == ID_SCE) || (elInfo.elType == ID_CPE) || + (elInfo.elType == ID_LFE)) { + /* iteration limitation */ + emergencyIterations &= + ((iterations[c][i] < hQC->maxIterations) ? 0 : 1); + } + } + /* detection if used dyn bits exceeds the maximal allowed criterion */ + dynBitsOvershoot |= + ((qcOut[c]->usedDynBits > qcOut[c]->maxDynBits) ? 1 : 0); + } + if (quantizationDone == 0 || dynBitsOvershoot) { + int sumBitsConsumedTotal = FDKaacEnc_getTotalConsumedBits( + qcOut, qcElement, cm, hQC->globHdrBits, nSubFrames); - }/* quantizationDone */ + if ((sumDynBitsConsumedTotal >= avgTotalDynBits) || + (sumDynBitsConsumedTotal == 0)) { + quantizationDone = 1; + } + if (emergencyIterations && (sumBitsConsumedTotal < totalAvailableBits)) { + quantizationDone = 1; + } + if ((sumBitsConsumedTotal > totalAvailableBits) || + !checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) { + quantizationDone = 0; + } + if ((sumBitsConsumedTotal < totalAvailableBits) && + checkMinFrameBitsDemand(qcOut, hQC->minBitsPerFrame, nSubFrames)) { + decreaseBitConsumption = 0; + } else { + decreaseBitConsumption = 1; + } - } while (!quantizationDone) ; + if (dynBitsOvershoot) { + quantizationDone = 0; + decreaseBitConsumption = 1; + } + + /* reset constraints fullfilled flags */ + FDKmemclear(constraintsFulfilled, sizeof(constraintsFulfilled)); + FDKmemclear(chConstraintsFulfilled, sizeof(chConstraintsFulfilled)); - /*-------------------------------------------- */ - /* ... -end- Quantization loop */ - /*-------------------------------------------- */ + } /* quantizationDone */ + + } while (!quantizationDone); + + /*-------------------------------------------- */ + /* ... -end- Quantization loop */ + /*-------------------------------------------- */ /*-------------------------------------------- */ /*-------------------------------------------- */ @@ -1178,112 +1132,98 @@ AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, return AAC_ENC_OK; } - -static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption(int* iterations, - const int maxIterations, - int gainAdjustment, - int* chConstraintsFulfilled, - int* calculateQuant, - int nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT* qcOutElement, - ELEMENT_BITS* elBits, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ +static AAC_ENCODER_ERROR FDKaacEnc_reduceBitConsumption( + int* iterations, const int maxIterations, int gainAdjustment, + int* chConstraintsFulfilled, int* calculateQuant, int nChannels, + PSY_OUT_ELEMENT* psyOutElement, QC_OUT* qcOut, QC_OUT_ELEMENT* qcOutElement, + ELEMENT_BITS* elBits, AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, + SCHAR epConfig) { int ch; /** SOLVING PROBLEM **/ - if ((*iterations)++ >= maxIterations) - { - if (qcOutElement->dynBitsUsed==0) { + if ((*iterations) < maxIterations) { + /* increase gain (+ next iteration) */ + for (ch = 0; ch < nChannels; ch++) { + if (!chConstraintsFulfilled[ch]) { + qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment; + calculateQuant[ch] = 1; /* global gain has changed, recalculate + quantization in next iteration! */ + } } - /* crash recovery */ - else { + } else if ((*iterations) == maxIterations) { + if (qcOutElement->dynBitsUsed == 0) { + return AAC_ENC_QUANT_ERROR; + } else { + /* crash recovery */ INT bitsToSave = 0; - if ( (bitsToSave = fixMax((qcOutElement->dynBitsUsed + 8) - (elBits->bitResLevelEl + qcOutElement->grantedDynBits), - (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) - (elBits->maxBitsEl))) > 0 ) - { - FDKaacEnc_crashRecovery(nChannels, - psyOutElement, - qcOut, - qcOutElement, - bitsToSave, - aot, - syntaxFlags, - epConfig) ; - } - else - { - for (ch = 0; ch < nChannels; ch++) - { + if ((bitsToSave = fixMax( + (qcOutElement->dynBitsUsed + 8) - + (elBits->bitResLevelEl + qcOutElement->grantedDynBits), + (qcOutElement->dynBitsUsed + qcOutElement->staticBitsUsed + 8) - + (elBits->maxBitsEl))) > 0) { + FDKaacEnc_crashRecovery(nChannels, psyOutElement, qcOut, qcOutElement, + bitsToSave, aot, syntaxFlags, epConfig); + } else { + for (ch = 0; ch < nChannels; ch++) { qcOutElement->qcOutChannel[ch]->globalGain += 1; + } } - } - for (ch = 0; ch < nChannels; ch++) - { - calculateQuant[ch] = 1; - } - } - } - else /* iterations >= maxIterations */ - { - /* increase gain (+ next iteration) */ - for (ch = 0; ch < nChannels; ch++) - { - if(!chConstraintsFulfilled[ch]) - { - qcOutElement->qcOutChannel[ch]->globalGain += gainAdjustment ; - calculateQuant[ch] = 1; /* global gain has changed, recalculate quantization in next iteration! */ + for (ch = 0; ch < nChannels; ch++) { + calculateQuant[ch] = 1; } } + } else { + /* (*iterations) > maxIterations */ + return AAC_ENC_QUANT_ERROR; } + (*iterations)++; return AAC_ENC_OK; } -AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, - QC_STATE* qcKernel, - ELEMENT_BITS* RESTRICT elBits[(8)], - QC_OUT** qcOut) -{ +AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, + QC_STATE* qcKernel, + ELEMENT_BITS* RESTRICT elBits[((8))], + QC_OUT** qcOut) { switch (qcKernel->bitrateMode) { case QCDATA_BR_MODE_SFR: break; case QCDATA_BR_MODE_FF: - break; - + break; case QCDATA_BR_MODE_VBR_1: case QCDATA_BR_MODE_VBR_2: case QCDATA_BR_MODE_VBR_3: case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_5: - qcOut[0]->totFillBits = (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits)&7; /* precalculate alignment bits */ - qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; - qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; + qcOut[0]->totFillBits = + (qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits) & + 7; /* precalculate alignment bits */ + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += + (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; - case QCDATA_BR_MODE_CBR: case QCDATA_BR_MODE_INVALID: default: - INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot ; + INT bitResSpace = qcKernel->bitResTotMax - qcKernel->bitResTot; /* processing fill-bits */ - INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits ; - qcOut[0]->totFillBits = fixMax((deltaBitRes&7), (deltaBitRes - (fixMax(0,bitResSpace-7)&~7))); - qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + qcOut[0]->globalExtBits; - qcOut[0]->totFillBits += ( fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; + INT deltaBitRes = qcOut[0]->grantedDynBits - qcOut[0]->usedDynBits; + qcOut[0]->totFillBits = fixMax( + (deltaBitRes & 7), (deltaBitRes - (fixMax(0, bitResSpace - 7) & ~7))); + qcOut[0]->totalBits = qcOut[0]->staticBits + qcOut[0]->usedDynBits + + qcOut[0]->totFillBits + qcOut[0]->elementExtBits + + qcOut[0]->globalExtBits; + qcOut[0]->totFillBits += + (fixMax(0, qcKernel->minBitsPerFrame - qcOut[0]->totalBits) + 7) & ~7; break; } /* switch (qcKernel->bitrateMode) */ return AAC_ENC_OK; } - - - /********************************************************************************* functionname: FDKaacEnc_calcMaxValueInSfb @@ -1292,34 +1232,29 @@ AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, **********************************************************************************/ -static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *RESTRICT sfbOffset, - SHORT *RESTRICT quantSpectrum, - UINT *RESTRICT maxValue) -{ - INT sfbOffs,sfb; +static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, INT maxSfbPerGroup, + INT sfbPerGroup, INT* RESTRICT sfbOffset, + SHORT* RESTRICT quantSpectrum, + UINT* RESTRICT maxValue) { + INT sfbOffs, sfb; INT maxValueAll = 0; - for (sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) - { + for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { INT line; INT maxThisSfb = 0; - for (line = sfbOffset[sfbOffs+sfb]; line < sfbOffset[sfbOffs+sfb+1]; line++) - { + for (line = sfbOffset[sfbOffs + sfb]; line < sfbOffset[sfbOffs + sfb + 1]; + line++) { INT tmp = fixp_abs(quantSpectrum[line]); maxThisSfb = fixMax(tmp, maxThisSfb); } - maxValue[sfbOffs+sfb] = maxThisSfb; + maxValue[sfbOffs + sfb] = maxThisSfb; maxValueAll = fixMax(maxThisSfb, maxValueAll); } return maxValueAll; } - /********************************************************************************* functionname: FDKaacEnc_updateBitres @@ -1327,21 +1262,18 @@ static INT FDKaacEnc_calcMaxValueInSfb(INT sfbCnt, return: **********************************************************************************/ -void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, - QC_STATE* qcKernel, - QC_OUT** qcOut) -{ +void FDKaacEnc_updateBitres(CHANNEL_MAPPING* cm, QC_STATE* qcKernel, + QC_OUT** qcOut) { switch (qcKernel->bitrateMode) { - case QCDATA_BR_MODE_FF: case QCDATA_BR_MODE_VBR_1: case QCDATA_BR_MODE_VBR_2: case QCDATA_BR_MODE_VBR_3: case QCDATA_BR_MODE_VBR_4: case QCDATA_BR_MODE_VBR_5: /* variable bitrate */ - qcKernel->bitResTot = FDKmin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax); + qcKernel->bitResTot = + fMin(qcKernel->maxBitsPerFrame, qcKernel->bitResTotMax); break; - case QCDATA_BR_MODE_CBR: case QCDATA_BR_MODE_SFR: case QCDATA_BR_MODE_INVALID: @@ -1349,7 +1281,9 @@ void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, int c = 0; /* constant bitrate */ { - qcKernel->bitResTot += qcOut[c]->grantedDynBits - (qcOut[c]->usedDynBits + qcOut[c]->totFillBits + qcOut[c]->alignBits); + qcKernel->bitResTot += qcOut[c]->grantedDynBits - + (qcOut[c]->usedDynBits + qcOut[c]->totFillBits + + qcOut[c]->alignBits); } break; } @@ -1362,57 +1296,59 @@ void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, return: **********************************************************************************/ -AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, - QC_STATE *qcKernel, - QC_OUT *qcOut, - QC_OUT_ELEMENT** qcElement, - HANDLE_TRANSPORTENC hTpEnc, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ +AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( + CHANNEL_MAPPING* cm, QC_STATE* qcKernel, QC_OUT* qcOut, + QC_OUT_ELEMENT** qcElement, HANDLE_TRANSPORTENC hTpEnc, + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig) { QC_OUT_EXTENSION fillExtPayload; INT totFillBits, alignBits; /* Get total consumed bits in AU */ - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - qcOut->elementExtBits + qcOut->globalExtBits; - - if (qcKernel->bitrateMode==QCDATA_BR_MODE_CBR) { + qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + + qcOut->totFillBits + qcOut->elementExtBits + + qcOut->globalExtBits; - /* Now we can get the exact transport bit amount, and hopefully it is equal to the estimated value */ + if (qcKernel->bitrateMode == QCDATA_BR_MODE_CBR) { + /* Now we can get the exact transport bit amount, and hopefully it is equal + * to the estimated value */ INT exactTpBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); if (exactTpBits != qcKernel->globHdrBits) { INT diffFillBits = 0; - /* How many bits can be taken by bitreservoir */ - const INT bitresSpace = qcKernel->bitResTotMax - (qcKernel->bitResTot + (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits) ) ); + /* How many bits can be take by bitreservoir */ + const INT bitresSpace = + qcKernel->bitResTotMax - + (qcKernel->bitResTot + + (qcOut->grantedDynBits - (qcOut->usedDynBits + qcOut->totFillBits))); /* Number of bits which can be moved to bitreservoir. */ const INT bitsToBitres = qcKernel->globHdrBits - exactTpBits; - FDK_ASSERT(bitsToBitres>=0); /* is always positive */ + FDK_ASSERT(bitsToBitres >= 0); /* is always positive */ - /* If bitreservoir can not take all bits, move ramaining bits to fillbits */ - diffFillBits = FDKmax(0, bitsToBitres - bitresSpace); + /* If bitreservoir can not take all bits, move ramaining bits to fillbits + */ + diffFillBits = fMax(0, bitsToBitres - bitresSpace); /* Assure previous alignment */ - diffFillBits = (diffFillBits+7)&~7; + diffFillBits = (diffFillBits + 7) & ~7; /* Move as many bits as possible to bitreservoir */ - qcKernel->bitResTot += (bitsToBitres-diffFillBits); + qcKernel->bitResTot += (bitsToBitres - diffFillBits); /* Write remaing bits as fill bits */ - qcOut->totFillBits += diffFillBits; - qcOut->totalBits += diffFillBits; - qcOut->grantedDynBits += diffFillBits; + qcOut->totFillBits += diffFillBits; + qcOut->totalBits += diffFillBits; + qcOut->grantedDynBits += diffFillBits; /* Get new header bits */ - qcKernel->globHdrBits = transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); + qcKernel->globHdrBits = + transportEnc_GetStaticBits(hTpEnc, qcOut->totalBits); if (qcKernel->globHdrBits != exactTpBits) { - /* In previous step, fill bits and corresponding total bits were changed when bitreservoir was completely filled. - Now we can take the too much taken bits caused by header overhead from bitreservoir. + /* In previous step, fill bits and corresponding total bits were changed + when bitreservoir was completely filled. Now we can take the too much + taken bits caused by header overhead from bitreservoir. */ qcKernel->bitResTot -= (qcKernel->globHdrBits - exactTpBits); } @@ -1432,26 +1368,28 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, fillExtPayload.type = EXT_FILL_DATA; fillExtPayload.nPayloadBits = totFillBits; - /* ask bitstream encoder how many of that bits can be written in a fill extension data entity */ - qcOut->totFillBits = FDKaacEnc_writeExtensionData( NULL, - &fillExtPayload, - 0, 0, - syntaxFlags, - aot, - epConfig ); + /* ask bitstream encoder how many of that bits can be written in a fill + * extension data entity */ + qcOut->totFillBits = FDKaacEnc_writeExtensionData(NULL, &fillExtPayload, 0, 0, + syntaxFlags, aot, epConfig); /* now distribute extra fillbits and alignbits */ - alignBits = 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits - + qcOut->totFillBits + qcOut->globalExtBits -1)%8; + alignBits = + 7 - (qcOut->staticBits + qcOut->usedDynBits + qcOut->elementExtBits + + qcOut->totFillBits + qcOut->globalExtBits - 1) % + 8; /* Maybe we could remove this */ - if( ((alignBits + qcOut->totFillBits - totFillBits)==8) && (qcOut->totFillBits>8) ) - qcOut->totFillBits -= 8; + if (((alignBits + qcOut->totFillBits - totFillBits) == 8) && + (qcOut->totFillBits > 8)) + qcOut->totFillBits -= 8; - qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + qcOut->totFillBits + - alignBits + qcOut->elementExtBits + qcOut->globalExtBits; + qcOut->totalBits = qcOut->staticBits + qcOut->usedDynBits + + qcOut->totFillBits + alignBits + qcOut->elementExtBits + + qcOut->globalExtBits; - if ( (qcOut->totalBits>qcKernel->maxBitsPerFrame) || (qcOut->totalBits<qcKernel->minBitsPerFrame) ) { + if ((qcOut->totalBits > qcKernel->maxBitsPerFrame) || + (qcOut->totalBits < qcKernel->minBitsPerFrame)) { return AAC_ENC_QUANT_ERROR; } @@ -1460,8 +1398,6 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, return AAC_ENC_OK; } - - /********************************************************************************* functionname: FDKaacEnc_crashRecovery @@ -1472,93 +1408,82 @@ AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption(CHANNEL_MAPPING *cm, **********************************************************************************/ -static void FDKaacEnc_crashRecovery(INT nChannels, - PSY_OUT_ELEMENT* psyOutElement, - QC_OUT* qcOut, - QC_OUT_ELEMENT *qcElement, - INT bitsToSave, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig) -{ - INT ch ; - INT savedBits = 0 ; - INT sfb, sfbGrp ; - INT bitsPerScf[(2)][MAX_GROUPED_SFB] ; - INT sectionToScf[(2)][MAX_GROUPED_SFB] ; - INT *sfbOffset ; - INT sect, statBitsNew ; - QC_OUT_CHANNEL **qcChannel = qcElement->qcOutChannel; - PSY_OUT_CHANNEL **psyChannel = psyOutElement->psyOutChannel; +static void FDKaacEnc_crashRecovery(INT nChannels, + PSY_OUT_ELEMENT* psyOutElement, + QC_OUT* qcOut, QC_OUT_ELEMENT* qcElement, + INT bitsToSave, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig) { + INT ch; + INT savedBits = 0; + INT sfb, sfbGrp; + INT bitsPerScf[(2)][MAX_GROUPED_SFB]; + INT sectionToScf[(2)][MAX_GROUPED_SFB]; + INT* sfbOffset; + INT sect, statBitsNew; + QC_OUT_CHANNEL** qcChannel = qcElement->qcOutChannel; + PSY_OUT_CHANNEL** psyChannel = psyOutElement->psyOutChannel; /* create a table which converts frq-bins to bit-demand... [bitsPerScf] */ /* ...and another one which holds the corresponding sections [sectionToScf] */ - for (ch = 0; ch < nChannels; ch++) - { - sfbOffset = psyChannel[ch]->sfbOffsets ; + for (ch = 0; ch < nChannels; ch++) { + sfbOffset = psyChannel[ch]->sfbOffsets; - for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) - { - INT sfb ; - INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook ; + for (sect = 0; sect < qcChannel[ch]->sectionData.noOfSections; sect++) { + INT codeBook = qcChannel[ch]->sectionData.huffsection[sect].codeBook; for (sfb = qcChannel[ch]->sectionData.huffsection[sect].sfbStart; sfb < qcChannel[ch]->sectionData.huffsection[sect].sfbStart + - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt; - sfb++) - { + qcChannel[ch]->sectionData.huffsection[sect].sfbCnt; + sfb++) { bitsPerScf[ch][sfb] = 0; - if ( (codeBook != CODE_BOOK_PNS_NO) /*&& - (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/ ) - { - INT sfbStartLine = sfbOffset[sfb] ; - INT noOfLines = sfbOffset[sfb+1] - sfbStartLine ; - bitsPerScf[ch][sfb] = FDKaacEnc_countValues(&(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook) ; + if ((codeBook != CODE_BOOK_PNS_NO) /*&& + (sfb < (qcChannel[ch]->sectionData.noOfGroups*qcChannel[ch]->sectionData.maxSfbPerGroup))*/) { + INT sfbStartLine = sfbOffset[sfb]; + INT noOfLines = sfbOffset[sfb + 1] - sfbStartLine; + bitsPerScf[ch][sfb] = FDKaacEnc_countValues( + &(qcChannel[ch]->quantSpec[sfbStartLine]), noOfLines, codeBook); } - sectionToScf[ch][sfb] = sect ; + sectionToScf[ch][sfb] = sect; } - } } /* LOWER [maxSfb] IN BOTH CHANNELS!! */ - /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ; */ + /* Attention: in case of stereo: maxSfbL == maxSfbR, GroupingL == GroupingR ; + */ - for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup-1; sfb >= 0; sfb--) - { - for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt; sfbGrp += psyChannel[0]->sfbPerGroup) - { - for (ch = 0; ch < nChannels; ch++) - { - int sect = sectionToScf[ch][sfbGrp+sfb]; - qcChannel[ch]->sectionData.huffsection[sect].sfbCnt-- ; - savedBits += bitsPerScf[ch][sfbGrp+sfb] ; + for (sfb = qcChannel[0]->sectionData.maxSfbPerGroup - 1; sfb >= 0; sfb--) { + for (sfbGrp = 0; sfbGrp < psyChannel[0]->sfbCnt; + sfbGrp += psyChannel[0]->sfbPerGroup) { + for (ch = 0; ch < nChannels; ch++) { + sect = sectionToScf[ch][sfbGrp + sfb]; + qcChannel[ch]->sectionData.huffsection[sect].sfbCnt--; + savedBits += bitsPerScf[ch][sfbGrp + sfb]; if (qcChannel[ch]->sectionData.huffsection[sect].sfbCnt == 0) { - savedBits += (psyChannel[ch]->lastWindowSequence!=SHORT_WINDOW) ? FDKaacEnc_sideInfoTabLong[0] - : FDKaacEnc_sideInfoTabShort[0]; + savedBits += (psyChannel[ch]->lastWindowSequence != SHORT_WINDOW) + ? FDKaacEnc_sideInfoTabLong[0] + : FDKaacEnc_sideInfoTabShort[0]; } } } /* ...have enough bits been saved? */ - if (savedBits >= bitsToSave) - break ; + if (savedBits >= bitsToSave) break; } /* sfb loop */ /* if not enough bits saved, clean whole spectrum and remove side info overhead */ if (sfb == -1) { - sfb = 0 ; + sfb = 0; } - for (ch = 0; ch < nChannels; ch++) - { - qcChannel[ch]->sectionData.maxSfbPerGroup = sfb ; - psyChannel[ch]->maxSfbPerGroup = sfb ; + for (ch = 0; ch < nChannels; ch++) { + qcChannel[ch]->sectionData.maxSfbPerGroup = sfb; + psyChannel[ch]->maxSfbPerGroup = sfb; /* when no spectrum is coded save tools info in bitstream */ - if(sfb==0) { + if (sfb == 0) { FDKmemclear(&psyChannel[ch]->tnsInfo, sizeof(TNS_INFO)); FDKmemclear(&psyOutElement->toolsInfo, sizeof(TOOLSINFO)); } @@ -1572,14 +1497,9 @@ static void FDKaacEnc_crashRecovery(INT nChannels, elInfo.nChannelsInEl = nChannels; elInfo.elType = (nChannels == 2) ? ID_CPE : ID_SCE; - FDKaacEnc_ChannelElementWrite( NULL, &elInfo, NULL, - psyOutElement, - psyChannel, - syntaxFlags, - aot, - epConfig, - &statBitsNew, - 0 ); + FDKaacEnc_ChannelElementWrite(NULL, &elInfo, NULL, psyOutElement, + psyChannel, syntaxFlags, aot, epConfig, + &statBitsNew, 0); } savedBits = qcElement->staticBitsUsed - statBitsNew; @@ -1588,30 +1508,23 @@ static void FDKaacEnc_crashRecovery(INT nChannels, qcElement->staticBitsUsed -= savedBits; qcElement->grantedDynBits += savedBits; - qcOut->staticBits -= savedBits; + qcOut->staticBits -= savedBits; qcOut->grantedDynBits += savedBits; - qcOut->maxDynBits += savedBits; - - + qcOut->maxDynBits += savedBits; } - - -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) -{ +void FDKaacEnc_QCClose(QC_STATE** phQCstate, QC_OUT** phQC) { int n, i; - if (phQC!=NULL) { - - for (n=0;n<(1);n++) { + if (phQC != NULL) { + for (n = 0; n < (1); n++) { if (phQC[n] != NULL) { - QC_OUT *hQC = phQC[n]; - for (i=0; i<(8); i++) { + QC_OUT* hQC = phQC[n]; + for (i = 0; i < (8); i++) { } - for (i=0; i<(8); i++) { - if (hQC->qcElement[i]) - FreeRam_aacEnc_QCelement(&hQC->qcElement[i]); + for (i = 0; i < ((8)); i++) { + if (hQC->qcElement[i]) FreeRam_aacEnc_QCelement(&hQC->qcElement[i]); } FreeRam_aacEnc_QCout(&phQC[n]); @@ -1619,18 +1532,17 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) } } - if (phQCstate!=NULL) { + if (phQCstate != NULL) { if (*phQCstate != NULL) { - QC_STATE *hQCstate = *phQCstate; + QC_STATE* hQCstate = *phQCstate; - if (hQCstate->hAdjThr != NULL) - FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr); + if (hQCstate->hAdjThr != NULL) FDKaacEnc_AdjThrClose(&hQCstate->hAdjThr); if (hQCstate->hBitCounter != NULL) FDKaacEnc_BCClose(&hQCstate->hBitCounter); - for (i=0; i<(8); i++) { - if (hQCstate->elementBits[i]!=NULL) { + for (i = 0; i < ((8)); i++) { + if (hQCstate->elementBits[i] != NULL) { FreeRam_aacEnc_ElementBits(&hQCstate->elementBits[i]); } } @@ -1638,4 +1550,3 @@ void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC) } } } - diff --git a/libAACenc/src/qc_main.h b/libAACenc/src/qc_main.h index 4e8c042..b9e8e2d 100644 --- a/libAACenc/src/qc_main.h +++ b/libAACenc/src/qc_main.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Quantizing & coding + Description: Quantizing & coding -******************************************************************************/ -#ifndef _QC_MAIN_H -#define _QC_MAIN_H +*******************************************************************************/ +#ifndef QC_MAIN_H +#define QC_MAIN_H #include "aacenc.h" #include "qc_data.h" @@ -99,72 +111,48 @@ amm-info@iis.fraunhofer.de /* Quantizing & coding stage */ -AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, - const INT nElements, - const INT nChannels, - const INT nSubFrames - ,UCHAR *dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_QCOutNew(QC_OUT **phQC, const INT nElements, + const INT nChannels, const INT nSubFrames, + UCHAR *dynamic_RAM); -AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], - const INT nSubFrames, +AAC_ENCODER_ERROR FDKaacEnc_QCOutInit(QC_OUT *phQC[(1)], const INT nSubFrames, const CHANNEL_MAPPING *cm); -AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, - INT nElements - ,UCHAR* dynamic_RAM - ); +AAC_ENCODER_ERROR FDKaacEnc_QCNew(QC_STATE **phQC, INT nElements, + UCHAR *dynamic_RAM); -AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init); +AAC_ENCODER_ERROR FDKaacEnc_QCInit(QC_STATE *hQC, struct QC_INIT *init, + const ULONG initFlags); AAC_ENCODER_ERROR FDKaacEnc_QCMainPrepare( - ELEMENT_INFO *elInfo, - ATS_ELEMENT* RESTRICT adjThrStateElement, - PSY_OUT_ELEMENT* RESTRICT psyOutElement, - QC_OUT_ELEMENT* RESTRICT qcOutElement, /* returns error code */ - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - - -AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE* RESTRICT hQC, - PSY_OUT** psyOut, - QC_OUT** qcOut, - INT avgTotalBits, - CHANNEL_MAPPING* cm - ,AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); - -AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING* cm, - QC_STATE* qcKernel, - ELEMENT_BITS* RESTRICT elBits[(8)], - QC_OUT** qcOut); - - -void FDKaacEnc_updateBitres( CHANNEL_MAPPING *cm, - QC_STATE *qcKernel, - QC_OUT **qcOut); - -AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( CHANNEL_MAPPING *cm, - QC_STATE *hQC, - QC_OUT *qcOut, - QC_OUT_ELEMENT** qcElement, - HANDLE_TRANSPORTENC hTpEnc, - AUDIO_OBJECT_TYPE aot, - UINT syntaxFlags, - SCHAR epConfig - ); + ELEMENT_INFO *elInfo, ATS_ELEMENT *RESTRICT adjThrStateElement, + PSY_OUT_ELEMENT *RESTRICT psyOutElement, + QC_OUT_ELEMENT *RESTRICT qcOutElement, /* returns error code */ + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig); + +AAC_ENCODER_ERROR FDKaacEnc_QCMain(QC_STATE *RESTRICT hQC, PSY_OUT **psyOut, + QC_OUT **qcOut, INT avgTotalBits, + CHANNEL_MAPPING *cm, AUDIO_OBJECT_TYPE aot, + UINT syntaxFlags, SCHAR epConfig); + +AAC_ENCODER_ERROR FDKaacEnc_updateFillBits(CHANNEL_MAPPING *cm, + QC_STATE *qcKernel, + ELEMENT_BITS *RESTRICT elBits[((8))], + QC_OUT **qcOut); + +void FDKaacEnc_updateBitres(CHANNEL_MAPPING *cm, QC_STATE *qcKernel, + QC_OUT **qcOut); + +AAC_ENCODER_ERROR FDKaacEnc_FinalizeBitConsumption( + CHANNEL_MAPPING *cm, QC_STATE *hQC, QC_OUT *qcOut, + QC_OUT_ELEMENT **qcElement, HANDLE_TRANSPORTENC hTpEnc, + AUDIO_OBJECT_TYPE aot, UINT syntaxFlags, SCHAR epConfig); AAC_ENCODER_ERROR FDKaacEnc_AdjustBitrate(QC_STATE *RESTRICT hQC, - CHANNEL_MAPPING *RESTRICT cm, - INT *avgTotalBits, - INT bitRate, - INT sampleRate, - INT granuleLength); + CHANNEL_MAPPING *RESTRICT cm, + INT *avgTotalBits, INT bitRate, + INT sampleRate, INT granuleLength); -void FDKaacEnc_QCClose (QC_STATE **phQCstate, QC_OUT **phQC); +void FDKaacEnc_QCClose(QC_STATE **phQCstate, QC_OUT **phQC); -#endif /* _QC_MAIN_H */ +#endif /* QC_MAIN_H */ diff --git a/libAACenc/src/quantize.cpp b/libAACenc/src/quantize.cpp index a74da0e..4d25263 100644 --- a/libAACenc/src/quantize.cpp +++ b/libAACenc/src/quantize.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,14 +90,15 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Quantization + Description: Quantization -******************************************************************************/ +*******************************************************************************/ #include "quantize.h" @@ -101,60 +113,61 @@ amm-info@iis.fraunhofer.de output: quantized spectrum *****************************************************************************/ -static void FDKaacEnc_quantizeLines(INT gain, - INT noOfLines, - FIXP_DBL *mdctSpectrum, - SHORT *quaSpectrum, - INT dZoneQuantEnable) -{ - int line; +static void FDKaacEnc_quantizeLines(INT gain, INT noOfLines, + const FIXP_DBL *mdctSpectrum, + SHORT *quaSpectrum, INT dZoneQuantEnable) { + int line; FIXP_DBL k = FL2FXCONST_DBL(0.0f); - FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain)&3]; - INT quantizershift = ((-gain)>>2)+1; - const INT kShift=16; + FIXP_QTD quantizer = FDKaacEnc_quantTableQ[(-gain) & 3]; + INT quantizershift = ((-gain) >> 2) + 1; + const INT kShift = 16; if (dZoneQuantEnable) - k = FL2FXCONST_DBL(0.23f)>>kShift; + k = FL2FXCONST_DBL(0.23f) >> kShift; else - k = FL2FXCONST_DBL(-0.0946f + 0.5f)>>kShift; + k = FL2FXCONST_DBL(-0.0946f + 0.5f) >> kShift; - for (line = 0; line < noOfLines; line++) - { - FIXP_DBL accu = fMultDiv2(mdctSpectrum[line],quantizer); + for (line = 0; line < noOfLines; line++) { + FIXP_DBL accu = fMultDiv2(mdctSpectrum[line], quantizer); - if (accu < FL2FXCONST_DBL(0.0f)) - { - accu=-accu; + if (accu < FL2FXCONST_DBL(0.0f)) { + accu = -accu; /* normalize */ - INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not + necessary here since test + value is always > 0 */ accu <<= accuShift; - INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); - INT totalShift = quantizershift-accuShift+1; - accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); - totalShift = (16-4)-(3*(totalShift>>2)); - FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu >>= fixMin(totalShift,DFRACT_BITS-1); - quaSpectrum[line] = (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS-1-16))); - } - else if(accu > FL2FXCONST_DBL(0.0f)) - { + INT tabIndex = + (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); + INT totalShift = quantizershift - accuShift + 1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex], + FDKaacEnc_quantTableE[totalShift & 3]); + totalShift = (16 - 4) - (3 * (totalShift >> 2)); + FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */ + accu >>= fixMin(totalShift, DFRACT_BITS - 1); + quaSpectrum[line] = + (SHORT)(-((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16))); + } else if (accu > FL2FXCONST_DBL(0.0f)) { /* normalize */ - INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not necessary here since test value is always > 0 */ + INT accuShift = CntLeadingZeros(accu) - 1; /* CountLeadingBits() is not + necessary here since test + value is always > 0 */ accu <<= accuShift; - INT tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); - INT totalShift = quantizershift-accuShift+1; - accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex],FDKaacEnc_quantTableE[totalShift&3]); - totalShift = (16-4)-(3*(totalShift>>2)); - FDK_ASSERT(totalShift >=0); /* MAX_QUANT_VIOLATION */ - accu >>= fixMin(totalShift,DFRACT_BITS-1); - quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS-1-16)); + INT tabIndex = + (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); + INT totalShift = quantizershift - accuShift + 1; + accu = fMultDiv2(FDKaacEnc_mTab_3_4[tabIndex], + FDKaacEnc_quantTableE[totalShift & 3]); + totalShift = (16 - 4) - (3 * (totalShift >> 2)); + FDK_ASSERT(totalShift >= 0); /* MAX_QUANT_VIOLATION */ + accu >>= fixMin(totalShift, DFRACT_BITS - 1); + quaSpectrum[line] = (SHORT)((LONG)(k + accu) >> (DFRACT_BITS - 1 - 16)); + } else { + quaSpectrum[line] = 0; } - else - quaSpectrum[line]=0; } } - /***************************************************************************** functionname:iFDKaacEnc_quantizeLines @@ -164,90 +177,90 @@ static void FDKaacEnc_quantizeLines(INT gain, output: spectral data *****************************************************************************/ -static void FDKaacEnc_invQuantizeLines(INT gain, - INT noOfLines, - SHORT *quantSpectrum, - FIXP_DBL *mdctSpectrum) +static void FDKaacEnc_invQuantizeLines(INT gain, INT noOfLines, + SHORT *quantSpectrum, + FIXP_DBL *mdctSpectrum) { INT iquantizermod; INT iquantizershift; INT line; - iquantizermod = gain&3; - iquantizershift = gain>>2; + iquantizermod = gain & 3; + iquantizershift = gain >> 2; for (line = 0; line < noOfLines; line++) { - - if(quantSpectrum[line] < 0) { + if (quantSpectrum[line] < 0) { FIXP_DBL accu; - INT ex,specExp,tabIndex; - FIXP_DBL s,t; + INT ex, specExp, tabIndex; + FIXP_DBL s, t; - accu = (FIXP_DBL) -quantSpectrum[line]; + accu = (FIXP_DBL)-quantSpectrum[line]; ex = CountLeadingBits(accu); accu <<= ex; - specExp = (DFRACT_BITS-1) - ex; + specExp = (DFRACT_BITS - 1) - ex; - FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ - tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); /* calculate "mantissa" ^4/3 */ s = FDKaacEnc_mTab_4_3Elc[tabIndex]; - /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + /* get approperiate exponent multiplier for specExp^3/4 combined with + * scfMod */ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; /* multiply "mantissa" ^4/3 with exponent multiplier */ - accu = fMult(s,t); + accu = fMult(s, t); /* get approperiate exponent shifter */ - specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] - + 1; /* -1 to avoid overflows in accu */ - if ((-iquantizershift-specExp) < 0) - accu <<= -(-iquantizershift-specExp); + if ((-iquantizershift - specExp) < 0) + accu <<= -(-iquantizershift - specExp); else - accu >>= -iquantizershift-specExp; + accu >>= -iquantizershift - specExp; mdctSpectrum[line] = -accu; - } - else if (quantSpectrum[line] > 0) { + } else if (quantSpectrum[line] > 0) { FIXP_DBL accu; - INT ex,specExp,tabIndex; - FIXP_DBL s,t; + INT ex, specExp, tabIndex; + FIXP_DBL s, t; accu = (FIXP_DBL)(INT)quantSpectrum[line]; ex = CountLeadingBits(accu); accu <<= ex; - specExp = (DFRACT_BITS-1) - ex; + specExp = (DFRACT_BITS - 1) - ex; - FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ + FDK_ASSERT(specExp < 14); /* this fails if abs(value) > 8191 */ - tabIndex = (INT)(accu>>(DFRACT_BITS-2-MANT_DIGITS))&(~MANT_SIZE); + tabIndex = (INT)(accu >> (DFRACT_BITS - 2 - MANT_DIGITS)) & (~MANT_SIZE); /* calculate "mantissa" ^4/3 */ s = FDKaacEnc_mTab_4_3Elc[tabIndex]; - /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ + /* get approperiate exponent multiplier for specExp^3/4 combined with + * scfMod */ t = FDKaacEnc_specExpMantTableCombElc[iquantizermod][specExp]; /* multiply "mantissa" ^4/3 with exponent multiplier */ - accu = fMult(s,t); + accu = fMult(s, t); /* get approperiate exponent shifter */ - specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp]-1; /* -1 to avoid overflows in accu */ + specExp = FDKaacEnc_specExpTableComb[iquantizermod][specExp] - + 1; /* -1 to avoid overflows in accu */ - if (( -iquantizershift-specExp) < 0) - accu <<= -(-iquantizershift-specExp); + if ((-iquantizershift - specExp) < 0) + accu <<= -(-iquantizershift - specExp); else - accu >>= -iquantizershift-specExp; + accu >>= -iquantizershift - specExp; mdctSpectrum[line] = accu; - } - else { + } else { mdctSpectrum[line] = FL2FXCONST_DBL(0.0f); } } @@ -262,34 +275,29 @@ static void FDKaacEnc_invQuantizeLines(INT gain, output: quantized spectrum *****************************************************************************/ -void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *sfbOffset, - FIXP_DBL *mdctSpectrum, - INT globalGain, - INT *scalefactors, - SHORT *quantizedSpectrum, - INT dZoneQuantEnable) -{ - INT sfbOffs,sfb; +void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup, + const INT *sfbOffset, + const FIXP_DBL *mdctSpectrum, INT globalGain, + const INT *scalefactors, + SHORT *quantizedSpectrum, + INT dZoneQuantEnable) { + INT sfbOffs, sfb; /* in FDKaacEnc_quantizeLines quaSpectrum is calculated with: spec^(3/4) * 2^(-3/16*QSS) * 2^(3/4*scale) + k simplify scaling calculation and reduce QSS before: spec^(3/4) * 2^(-3/16*(QSS - 4*scale)) */ - for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) - for (sfb = 0; sfb < maxSfbPerGroup; sfb++) - { - INT scalefactor = scalefactors[sfbOffs+sfb] ; + for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { + INT scalefactor = scalefactors[sfbOffs + sfb]; - FDKaacEnc_quantizeLines(globalGain - scalefactor, /* QSS */ - sfbOffset[sfbOffs+sfb+1] - sfbOffset[sfbOffs+sfb], - mdctSpectrum + sfbOffset[sfbOffs+sfb], - quantizedSpectrum + sfbOffset[sfbOffs+sfb], - dZoneQuantEnable); - } + FDKaacEnc_quantizeLines( + globalGain - scalefactor, /* QSS */ + sfbOffset[sfbOffs + sfb + 1] - sfbOffset[sfbOffs + sfb], + mdctSpectrum + sfbOffset[sfbOffs + sfb], + quantizedSpectrum + sfbOffset[sfbOffs + sfb], dZoneQuantEnable); + } } /***************************************************************************** @@ -301,41 +309,34 @@ void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, output: *****************************************************************************/ -FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - INT dZoneQuantEnable - ) -{ - INT i,scale; +FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum, + SHORT *quantSpectrum, INT noOfLines, INT gain, + INT dZoneQuantEnable) { + INT i, scale; FIXP_DBL xfsf; FIXP_DBL diff; FIXP_DBL invQuantSpec; xfsf = FL2FXCONST_DBL(0.0f); - for (i=0; i<noOfLines; i++) { + for (i = 0; i < noOfLines; i++) { /* quantization */ - FDKaacEnc_quantizeLines(gain, - 1, - &mdctSpectrum[i], - &quantSpectrum[i], - dZoneQuantEnable); + FDKaacEnc_quantizeLines(gain, 1, &mdctSpectrum[i], &quantSpectrum[i], + dZoneQuantEnable); - if (fAbs(quantSpectrum[i])>MAX_QUANT) { + if (fAbs(quantSpectrum[i]) > MAX_QUANT) { return FL2FXCONST_DBL(0.0f); } /* inverse quantization */ - FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec); /* dist */ - diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1)); scale = CountLeadingBits(diff); diff = scaleValue(diff, scale); diff = fPow2(diff); - scale = fixMin(2*(scale-1), DFRACT_BITS-1); + scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1); diff = scaleValue(diff, -scale); @@ -358,48 +359,43 @@ FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, *****************************************************************************/ void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - FIXP_DBL *en, - FIXP_DBL *dist) -{ - INT i,scale; + SHORT *quantSpectrum, INT noOfLines, + INT gain, FIXP_DBL *en, + FIXP_DBL *dist) { + INT i, scale; FIXP_DBL invQuantSpec; FIXP_DBL diff; FIXP_DBL energy = FL2FXCONST_DBL(0.0f); FIXP_DBL distortion = FL2FXCONST_DBL(0.0f); - for (i=0; i<noOfLines; i++) { - - if (fAbs(quantSpectrum[i])>MAX_QUANT) { - *en = FL2FXCONST_DBL(0.0f); + for (i = 0; i < noOfLines; i++) { + if (fAbs(quantSpectrum[i]) > MAX_QUANT) { + *en = FL2FXCONST_DBL(0.0f); *dist = FL2FXCONST_DBL(0.0f); return; } /* inverse quantization */ - FDKaacEnc_invQuantizeLines(gain,1,&quantSpectrum[i],&invQuantSpec); + FDKaacEnc_invQuantizeLines(gain, 1, &quantSpectrum[i], &invQuantSpec); /* energy */ energy += fPow2(invQuantSpec); /* dist */ - diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i]>>1)); + diff = fixp_abs(fixp_abs(invQuantSpec) - fixp_abs(mdctSpectrum[i] >> 1)); scale = CountLeadingBits(diff); diff = scaleValue(diff, scale); diff = fPow2(diff); - scale = fixMin(2*(scale-1), DFRACT_BITS-1); + scale = fixMin(2 * (scale - 1), DFRACT_BITS - 1); diff = scaleValue(diff, -scale); distortion += diff; } - *en = CalcLdData(energy)+FL2FXCONST_DBL(0.03125f); + *en = CalcLdData(energy) + FL2FXCONST_DBL(0.03125f); *dist = CalcLdData(distortion); } - diff --git a/libAACenc/src/quantize.h b/libAACenc/src/quantize.h index 16d3d4e..dfc2206 100644 --- a/libAACenc/src/quantize.h +++ b/libAACenc/src/quantize.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,17 +90,18 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Quantization + Description: Quantization -******************************************************************************/ +*******************************************************************************/ -#ifndef _QUANTIZE_H_ -#define _QUANTIZE_H_ +#ifndef QUANTIZE_H +#define QUANTIZE_H #include "common_fix.h" @@ -97,25 +109,19 @@ amm-info@iis.fraunhofer.de #define MAX_QUANT 8191 -void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, - INT maxSfbPerGroup, - INT sfbPerGroup, - INT *sfbOffset, FIXP_DBL *mdctSpectrum, - INT globalGain, INT *scalefactors, - SHORT *quantizedSpectrum, - INT dZoneQuantEnable); +void FDKaacEnc_QuantizeSpectrum(INT sfbCnt, INT maxSfbPerGroup, INT sfbPerGroup, + const INT *sfbOffset, + const FIXP_DBL *mdctSpectrum, INT globalGain, + const INT *scalefactors, + SHORT *quantizedSpectrum, INT dZoneQuantEnable); -FIXP_DBL FDKaacEnc_calcSfbDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - INT dZoneQuantEnable); +FIXP_DBL FDKaacEnc_calcSfbDist(const FIXP_DBL *mdctSpectrum, + SHORT *quantSpectrum, INT noOfLines, INT gain, + INT dZoneQuantEnable); void FDKaacEnc_calcSfbQuantEnergyAndDist(FIXP_DBL *mdctSpectrum, - SHORT *quantSpectrum, - INT noOfLines, - INT gain, - FIXP_DBL *en, - FIXP_DBL *dist); + SHORT *quantSpectrum, INT noOfLines, + INT gain, FIXP_DBL *en, + FIXP_DBL *dist); -#endif /* _QUANTIZE_H_ */ +#endif /* QUANTIZE_H */ diff --git a/libAACenc/src/sf_estim.cpp b/libAACenc/src/sf_estim.cpp index 1cb243b..17a8ae2 100644 --- a/libAACenc/src/sf_estim.cpp +++ b/libAACenc/src/sf_estim.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,33 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: Scale factor estimation + Description: Scale factor estimation -******************************************************************************/ +*******************************************************************************/ #include "sf_estim.h" #include "aacEnc_rom.h" #include "quantize.h" #include "bit_cnt.h" +#ifdef __arm__ +#endif - - +#define UPCOUNT_LIMIT 1 #define AS_PE_FAC_SHIFT 7 -#define DIST_FAC_SHIFT 3 +#define DIST_FAC_SHIFT 3 #define AS_PE_FAC_FLOAT (float)(1 << AS_PE_FAC_SHIFT) static const INT MAX_SCF_DELTA = 60; - -static const FIXP_DBL PE_C1 = FL2FXCONST_DBL(3.0f/AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */ -static const FIXP_DBL PE_C2 = FL2FXCONST_DBL(1.3219281f/AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */ -static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */ - +static const FIXP_DBL PE_C1 = FL2FXCONST_DBL( + 3.0f / AS_PE_FAC_FLOAT); /* (log(8.0)/log(2)) >> AS_PE_FAC_SHIFT */ +static const FIXP_DBL PE_C2 = FL2FXCONST_DBL( + 1.3219281f / AS_PE_FAC_FLOAT); /* (log(2.5)/log(2)) >> AS_PE_FAC_SHIFT */ +static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* 1-C2/C1 */ /* Function; FDKaacEnc_FDKaacEnc_CalcFormFactorChannel @@ -113,30 +126,32 @@ static const FIXP_DBL PE_C3 = FL2FXCONST_DBL(0.5593573f); /* Description: Calculates the formfactor sf: scale factor of the mdct spectrum - sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * (2^FORM_FAC_SHIFT)) + sfbFormFactorLdData is scaled with the factor 1/(((2^sf)^0.5) * + (2^FORM_FAC_SHIFT)) */ -static void -FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData, - PSY_OUT_CHANNEL *RESTRICT psyOutChan) -{ +static void FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( + FIXP_DBL *RESTRICT sfbFormFactorLdData, + PSY_OUT_CHANNEL *RESTRICT psyOutChan) { INT j, sfb, sfbGrp; FIXP_DBL formFactor; int tmp0 = psyOutChan->sfbCnt; int tmp1 = psyOutChan->maxSfbPerGroup; int step = psyOutChan->sfbPerGroup; - for(sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) { + for (sfbGrp = 0; sfbGrp < tmp0; sfbGrp += step) { for (sfb = 0; sfb < tmp1; sfb++) { formFactor = FL2FXCONST_DBL(0.0f); /* calc sum of sqrt(spec) */ - for(j=psyOutChan->sfbOffsets[sfbGrp+sfb]; j<psyOutChan->sfbOffsets[sfbGrp+sfb+1]; j++ ) { - formFactor += sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j]))>>FORM_FAC_SHIFT; + for (j = psyOutChan->sfbOffsets[sfbGrp + sfb]; + j < psyOutChan->sfbOffsets[sfbGrp + sfb + 1]; j++) { + formFactor += + sqrtFixp(fixp_abs(psyOutChan->mdctSpectrum[j])) >> FORM_FAC_SHIFT; } - sfbFormFactorLdData[sfbGrp+sfb] = CalcLdData(formFactor); + sfbFormFactorLdData[sfbGrp + sfb] = CalcLdData(formFactor); } /* set sfbFormFactor for sfbs with zero spec to zero. Just for debugging. */ - for ( ; sfb < psyOutChan->sfbPerGroup; sfb++) { - sfbFormFactorLdData[sfbGrp+sfb] = FL2FXCONST_DBL(-1.0f); + for (; sfb < psyOutChan->sfbPerGroup; sfb++) { + sfbFormFactorLdData[sfbGrp + sfb] = FL2FXCONST_DBL(-1.0f); } } } @@ -144,17 +159,17 @@ FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(FIXP_DBL *RESTRICT sfbFormFactorLdData /* Function: FDKaacEnc_CalcFormFactor - Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each channel + Description: Calls FDKaacEnc_FDKaacEnc_CalcFormFactorChannel() for each + channel */ -void -FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - const INT nChannels) -{ +void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], + PSY_OUT_CHANNEL *psyOutChannel[(2)], + const INT nChannels) { INT j; - for (j=0; j<nChannels; j++) { - FDKaacEnc_FDKaacEnc_CalcFormFactorChannel(qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]); + for (j = 0; j < nChannels; j++) { + FDKaacEnc_FDKaacEnc_CalcFormFactorChannel( + qcOutChannel[j]->sfbFormFactorLdData, psyOutChannel[j]); } } @@ -165,40 +180,44 @@ FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], sfbNRelevantLines is scaled with the factor 1/((2^FORM_FAC_SHIFT) * 2.0) */ -static void -FDKaacEnc_calcSfbRelevantLines( const FIXP_DBL *const sfbFormFactorLdData, - const FIXP_DBL *const sfbEnergyLdData, - const FIXP_DBL *const sfbThresholdLdData, - const INT *const sfbOffsets, - const INT sfbCnt, - const INT sfbPerGroup, - const INT maxSfbPerGroup, - FIXP_DBL *sfbNRelevantLines) -{ +static void FDKaacEnc_calcSfbRelevantLines( + const FIXP_DBL *const sfbFormFactorLdData, + const FIXP_DBL *const sfbEnergyLdData, + const FIXP_DBL *const sfbThresholdLdData, const INT *const sfbOffsets, + const INT sfbCnt, const INT sfbPerGroup, const INT maxSfbPerGroup, + FIXP_DBL *sfbNRelevantLines) { INT sfbOffs, sfb; FIXP_DBL sfbWidthLdData; - FIXP_DBL asPeFacLdData = FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */ + FIXP_DBL asPeFacLdData = + FL2FXCONST_DBL(0.109375); /* AS_PE_FAC_SHIFT*ld64(2) */ FIXP_DBL accu; - /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * 64); */ + /* sfbNRelevantLines[i] = 2^( (sfbFormFactorLdData[i] - 0.25 * + * (sfbEnergyLdData[i] - ld64(sfbWidth[i]/(2^7)) - AS_PE_FAC_SHIFT*ld64(2)) * + * 64); */ FDKmemclear(sfbNRelevantLines, sfbCnt * sizeof(FIXP_DBL)); - for (sfbOffs=0; sfbOffs<sfbCnt; sfbOffs+=sfbPerGroup) { - for(sfb=0; sfb<maxSfbPerGroup; sfb++) { + for (sfbOffs = 0; sfbOffs < sfbCnt; sfbOffs += sfbPerGroup) { + for (sfb = 0; sfb < maxSfbPerGroup; sfb++) { /* calc sum of sqrt(spec) */ - if((FIXP_DBL)sfbEnergyLdData[sfbOffs+sfb] > (FIXP_DBL)sfbThresholdLdData[sfbOffs+sfb]) { - INT sfbWidth = sfbOffsets[sfbOffs+sfb+1] - sfbOffsets[sfbOffs+sfb]; - - /* avgFormFactorLdData = sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */ - /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / avgFormFactorLdData; */ - sfbWidthLdData = (FIXP_DBL)(sfbWidth << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); + if ((FIXP_DBL)sfbEnergyLdData[sfbOffs + sfb] > + (FIXP_DBL)sfbThresholdLdData[sfbOffs + sfb]) { + INT sfbWidth = + sfbOffsets[sfbOffs + sfb + 1] - sfbOffsets[sfbOffs + sfb]; + + /* avgFormFactorLdData = + * sqrtFixp(sqrtFixp(sfbEnergyLdData[sfbOffs+sfb]/sfbWidth)); */ + /* sfbNRelevantLines[sfbOffs+sfb] = sfbFormFactor[sfbOffs+sfb] / + * avgFormFactorLdData; */ + sfbWidthLdData = + (FIXP_DBL)(sfbWidth << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); sfbWidthLdData = CalcLdData(sfbWidthLdData); - accu = sfbEnergyLdData[sfbOffs+sfb] - sfbWidthLdData - asPeFacLdData; - accu = sfbFormFactorLdData[sfbOffs+sfb] - (accu >> 2); + accu = sfbEnergyLdData[sfbOffs + sfb] - sfbWidthLdData - asPeFacLdData; + accu = sfbFormFactorLdData[sfbOffs + sfb] - (accu >> 2); - sfbNRelevantLines[sfbOffs+sfb] = CalcInvLdData(accu) >> 1; + sfbNRelevantLines[sfbOffs + sfb] = CalcInvLdData(accu) >> 1; } } } @@ -211,14 +230,14 @@ FDKaacEnc_calcSfbRelevantLines( const FIXP_DBL *const sfbFormFactorLdData, scfBitsFract is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, INT scfRight) -{ +static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, + INT scfRight) { FIXP_DBL scfBitsFract; - scfBitsFract = (FIXP_DBL) ( FDKaacEnc_bitCountScalefactorDelta(scfLeft-scf) - + FDKaacEnc_bitCountScalefactorDelta(scf-scfRight) ); + scfBitsFract = (FIXP_DBL)(FDKaacEnc_bitCountScalefactorDelta(scfLeft - scf) + + FDKaacEnc_bitCountScalefactorDelta(scf - scfRight)); - scfBitsFract = scfBitsFract << (DFRACT_BITS-1-(2*AS_PE_FAC_SHIFT)); + scfBitsFract = scfBitsFract << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT)); return scfBitsFract; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ } @@ -228,21 +247,21 @@ static FIXP_DBL FDKaacEnc_countSingleScfBits(INT scf, INT scfLeft, INT scfRight) specPe is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, FIXP_DBL nLines) -{ +static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, + FIXP_DBL nLines) { FIXP_DBL specPe = FL2FXCONST_DBL(0.0f); FIXP_DBL ldRatio; FIXP_DBL scfFract; - scfFract = (FIXP_DBL)(scf << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); + scfFract = (FIXP_DBL)(scf << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); - ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f),scfFract); + ldRatio = sfbConstPePart - fMult(FL2FXCONST_DBL(0.375f), scfFract); if (ldRatio >= PE_C1) { - specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,ldRatio)); - } - else { - specPe = fMult(FL2FXCONST_DBL(0.7f),fMult(nLines,(PE_C2 + fMult(PE_C3,ldRatio)))); + specPe = fMult(FL2FXCONST_DBL(0.7f), fMult(nLines, ldRatio)); + } else { + specPe = fMult(FL2FXCONST_DBL(0.7f), + fMult(nLines, (PE_C2 + fMult(PE_C3, ldRatio)))); } return specPe; /* output scaled by 1/(2^(2*AS_PE_FAC)) */ @@ -253,12 +272,8 @@ static FIXP_DBL FDKaacEnc_calcSingleSpecPe(INT scf, FIXP_DBL sfbConstPePart, FIX scfBitsDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, - INT *scfNew, - INT sfbCnt, - INT startSfb, - INT stopSfb) -{ +static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, INT *scfNew, INT sfbCnt, + INT startSfb, INT stopSfb) { FIXP_DBL scfBitsFract; INT scfBitsDiff = 0; INT sfb = 0, sfbLast; @@ -266,32 +281,33 @@ static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, /* search for first relevant sfb */ sfbLast = startSfb; - while ((sfbLast<stopSfb) && (scfOld[sfbLast]==FDK_INT_MIN)) - sfbLast++; + while ((sfbLast < stopSfb) && (scfOld[sfbLast] == FDK_INT_MIN)) sfbLast++; /* search for previous relevant sfb and count diff */ sfbPrev = startSfb - 1; - while ((sfbPrev>=0) && (scfOld[sfbPrev]==FDK_INT_MIN)) - sfbPrev--; - if (sfbPrev>=0) - scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev]-scfNew[sfbLast]) - - FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev]-scfOld[sfbLast]); + while ((sfbPrev >= 0) && (scfOld[sfbPrev] == FDK_INT_MIN)) sfbPrev--; + if (sfbPrev >= 0) + scfBitsDiff += + FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbPrev] - scfNew[sfbLast]) - + FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbPrev] - scfOld[sfbLast]); /* now loop through all sfbs and count diffs of relevant sfbs */ - for (sfb=sfbLast+1; sfb<stopSfb; sfb++) { - if (scfOld[sfb]!=FDK_INT_MIN) { - scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast]-scfNew[sfb]) - - FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast]-scfOld[sfb]); + for (sfb = sfbLast + 1; sfb < stopSfb; sfb++) { + if (scfOld[sfb] != FDK_INT_MIN) { + scfBitsDiff += + FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfb]) - + FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfb]); sfbLast = sfb; } } /* search for next relevant sfb and count diff */ sfbNext = stopSfb; - while ((sfbNext<sfbCnt) && (scfOld[sfbNext]==FDK_INT_MIN)) - sfbNext++; - if (sfbNext<sfbCnt) - scfBitsDiff += FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast]-scfNew[sfbNext]) - - FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast]-scfOld[sfbNext]); + while ((sfbNext < sfbCnt) && (scfOld[sfbNext] == FDK_INT_MIN)) sfbNext++; + if (sfbNext < sfbCnt) + scfBitsDiff += + FDKaacEnc_bitCountScalefactorDelta(scfNew[sfbLast] - scfNew[sfbNext]) - + FDKaacEnc_bitCountScalefactorDelta(scfOld[sfbLast] - scfOld[sfbNext]); - scfBitsFract = (FIXP_DBL) (scfBitsDiff << (DFRACT_BITS-1-(2*AS_PE_FAC_SHIFT))); + scfBitsFract = + (FIXP_DBL)(scfBitsDiff << (DFRACT_BITS - 1 - (2 * AS_PE_FAC_SHIFT))); return scfBitsFract; } @@ -301,48 +317,51 @@ static FIXP_DBL FDKaacEnc_countScfBitsDiff(INT *scfOld, specPeDiff is scaled by 1/(2^(2*AS_PE_FAC_SHIFT)) */ -static FIXP_DBL FDKaacEnc_calcSpecPeDiff(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - INT *scfOld, - INT *scfNew, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines, - INT startSfb, - INT stopSfb) -{ +static FIXP_DBL FDKaacEnc_calcSpecPeDiff( + PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, INT *scfOld, + INT *scfNew, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, + FIXP_DBL *sfbNRelevantLines, INT startSfb, INT stopSfb) { FIXP_DBL specPeDiff = FL2FXCONST_DBL(0.0f); FIXP_DBL scfFract = FL2FXCONST_DBL(0.0f); INT sfb; /* loop through all sfbs and count pe difference */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { - if (scfOld[sfb]!=FDK_INT_MIN) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { + if (scfOld[sfb] != FDK_INT_MIN) { FIXP_DBL ldRatioOld, ldRatioNew, pOld, pNew; - /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f / sfbFormFactor[sfb]) * LOG2_1; */ - /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */ + /* sfbConstPePart[sfb] = (float)log(psyOutChan->sfbEnergy[sfb] * 6.75f / + * sfbFormFactor[sfb]) * LOG2_1; */ + /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for + * log2 */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ if (sfbConstPePart[sfb] == (FIXP_DBL)FDK_INT_MIN) - sfbConstPePart[sfb] = ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f); + sfbConstPePart[sfb] = + ((psyOutChan->sfbEnergyLdData[sfb] - sfbFormFactorLdData[sfb] - + FL2FXCONST_DBL(0.09375f)) >> + 1) + + FL2FXCONST_DBL(0.02152255861f); - scfFract = (FIXP_DBL) (scfOld[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); - ldRatioOld = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract); + scfFract = (FIXP_DBL)(scfOld[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); + ldRatioOld = + sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); - scfFract = (FIXP_DBL) (scfNew[sfb] << (DFRACT_BITS-1-AS_PE_FAC_SHIFT)); - ldRatioNew = sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f),scfFract); + scfFract = (FIXP_DBL)(scfNew[sfb] << (DFRACT_BITS - 1 - AS_PE_FAC_SHIFT)); + ldRatioNew = + sfbConstPePart[sfb] - fMult(FL2FXCONST_DBL(0.375f), scfFract); if (ldRatioOld >= PE_C1) pOld = ldRatioOld; else - pOld = PE_C2 + fMult(PE_C3,ldRatioOld); + pOld = PE_C2 + fMult(PE_C3, ldRatioOld); if (ldRatioNew >= PE_C1) pNew = ldRatioNew; else - pNew = PE_C2 + fMult(PE_C3,ldRatioNew); + pNew = PE_C2 + fMult(PE_C3, ldRatioNew); - specPeDiff += fMult(FL2FXCONST_DBL(0.7f),fMult(sfbNRelevantLines[sfb],(pNew - pOld))); + specPeDiff += fMult(FL2FXCONST_DBL(0.7f), + fMult(sfbNRelevantLines[sfb], (pNew - pOld))); } } @@ -352,123 +371,96 @@ static FIXP_DBL FDKaacEnc_calcSpecPeDiff(PSY_OUT_CHANNEL *psyOutChan, /* Function: FDKaacEnc_improveScf - Description: Calculate the distortion by quantization and inverse quantization of the spectrum with - various scalefactors. The scalefactor which provides the best results will be used. + Description: Calculate the distortion by quantization and inverse quantization + of the spectrum with various scalefactors. The scalefactor which provides the + best results will be used. */ -static INT FDKaacEnc_improveScf(FIXP_DBL *spec, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT sfbWidth, - FIXP_DBL threshLdData, - INT scf, - INT minScf, - FIXP_DBL *distLdData, - INT *minScfCalculated, - INT dZoneQuantEnable - ) -{ - FIXP_DBL sfbDistLdData; - INT scfBest = scf; - INT k; - FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */ - - /* calc real distortion */ - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpec, - sfbWidth, - scf, - dZoneQuantEnable); - *minScfCalculated = scf; - /* nmr > 1.25 -> try to improve nmr */ - if (sfbDistLdData > (threshLdData-distFactorLdData)) { - INT scfEstimated = scf; - FIXP_DBL sfbDistBestLdData = sfbDistLdData; - INT cnt; - /* improve by bigger scf ? */ - cnt = 0; - - while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 3)) { - scf++; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistBestLdData) { - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k<sfbWidth; k++) - quantSpec[k] = quantSpecTmp[k]; - } +static INT FDKaacEnc_improveScf(const FIXP_DBL *spec, SHORT *quantSpec, + SHORT *quantSpecTmp, INT sfbWidth, + FIXP_DBL threshLdData, INT scf, INT minScf, + FIXP_DBL *distLdData, INT *minScfCalculated, + INT dZoneQuantEnable) { + FIXP_DBL sfbDistLdData; + INT scfBest = scf; + INT k; + FIXP_DBL distFactorLdData = FL2FXCONST_DBL(-0.0050301265); /* ld64(1/1.25) */ + + /* calc real distortion */ + sfbDistLdData = + FDKaacEnc_calcSfbDist(spec, quantSpec, sfbWidth, scf, dZoneQuantEnable); + *minScfCalculated = scf; + /* nmr > 1.25 -> try to improve nmr */ + if (sfbDistLdData > (threshLdData - distFactorLdData)) { + INT scfEstimated = scf; + FIXP_DBL sfbDistBestLdData = sfbDistLdData; + INT cnt; + /* improve by bigger scf ? */ + cnt = 0; + + while ((sfbDistLdData > (threshLdData - distFactorLdData)) && + (cnt++ < UPCOUNT_LIMIT)) { + scf++; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistBestLdData) { + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - /* improve by smaller scf ? */ - cnt = 0; - scf = scfEstimated; - sfbDistLdData = sfbDistBestLdData; - while ((sfbDistLdData > (threshLdData-distFactorLdData)) && (cnt++ < 1) && (scf > minScf)) { - scf--; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistBestLdData) { - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k<sfbWidth; k++) - quantSpec[k] = quantSpecTmp[k]; - } - *minScfCalculated = scf; + } + /* improve by smaller scf ? */ + cnt = 0; + scf = scfEstimated; + sfbDistLdData = sfbDistBestLdData; + while ((sfbDistLdData > (threshLdData - distFactorLdData)) && (cnt++ < 1) && + (scf > minScf)) { + scf--; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistBestLdData) { + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - *distLdData = sfbDistBestLdData; - } - else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */ - FIXP_DBL sfbDistBestLdData = sfbDistLdData; - FIXP_DBL sfbDistAllowedLdData = fixMin(sfbDistLdData-distFactorLdData,threshLdData); - int cnt; - for (cnt=0; cnt<3; cnt++) { - scf++; - sfbDistLdData = FDKaacEnc_calcSfbDist(spec, - quantSpecTmp, - sfbWidth, - scf, - dZoneQuantEnable); - - if (sfbDistLdData < sfbDistAllowedLdData) { - *minScfCalculated = scfBest+1; - scfBest = scf; - sfbDistBestLdData = sfbDistLdData; - for (k=0; k<sfbWidth; k++) - quantSpec[k] = quantSpecTmp[k]; - } + *minScfCalculated = scf; + } + *distLdData = sfbDistBestLdData; + } else { /* nmr <= 1.25 -> try to find bigger scf to use less bits */ + FIXP_DBL sfbDistBestLdData = sfbDistLdData; + FIXP_DBL sfbDistAllowedLdData = + fixMin(sfbDistLdData - distFactorLdData, threshLdData); + int cnt; + for (cnt = 0; cnt < UPCOUNT_LIMIT; cnt++) { + scf++; + sfbDistLdData = FDKaacEnc_calcSfbDist(spec, quantSpecTmp, sfbWidth, scf, + dZoneQuantEnable); + + if (sfbDistLdData < sfbDistAllowedLdData) { + *minScfCalculated = scfBest + 1; + scfBest = scf; + sfbDistBestLdData = sfbDistLdData; + for (k = 0; k < sfbWidth; k++) quantSpec[k] = quantSpecTmp[k]; } - *distLdData = sfbDistBestLdData; - } + } + *distLdData = sfbDistBestLdData; + } - /* return best scalefactor */ - return scfBest; + /* return best scalefactor */ + return scfBest; } /* Function: FDKaacEnc_assimilateSingleScf */ -static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT dZoneQuantEnable, - INT *scf, - INT *minScf, - FIXP_DBL *sfbDist, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines, - INT *minScfCalculated, - INT restartOnSuccess) -{ +static void FDKaacEnc_assimilateSingleScf( + const PSY_OUT_CHANNEL *psyOutChan, const QC_OUT_CHANNEL *qcOutChannel, + SHORT *quantSpec, SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, + const INT *minScf, FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, + const FIXP_DBL *sfbFormFactorLdData, const FIXP_DBL *sfbNRelevantLines, + INT *minScfCalculated, INT restartOnSuccess) { INT sfbLast, sfbAct, sfbNext; INT scfAct, *scfLast, *scfNext, scfMin, scfMax; INT sfbWidth, sfbOffs; @@ -483,77 +475,82 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, FIXP_DBL deltaPeLast[MAX_GROUPED_SFB]; INT updateMinScfCalculated; - for (i=0; i<psyOutChan->sfbCnt; i++) { + for (i = 0; i < psyOutChan->sfbCnt; i++) { prevScfLast[i] = FDK_INT_MAX; prevScfNext[i] = FDK_INT_MAX; deltaPeLast[i] = (FIXP_DBL)FDK_INT_MAX; } sfbLast = -1; - sfbAct = -1; + sfbAct = -1; sfbNext = -1; scfLast = 0; scfNext = 0; - scfMin = FDK_INT_MAX; - scfMax = FDK_INT_MAX; + scfMin = FDK_INT_MAX; + scfMax = FDK_INT_MAX; do { /* search for new relevant sfb */ sfbNext++; while ((sfbNext < psyOutChan->sfbCnt) && (scf[sfbNext] == FDK_INT_MIN)) sfbNext++; - if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) { + if ((sfbLast >= 0) && (sfbAct >= 0) && (sfbNext < psyOutChan->sfbCnt)) { /* relevant scfs to the left and to the right */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = scf + sfbLast; scfNext = scf + sfbNext; - scfMin = fixMin(*scfLast, *scfNext); - scfMax = fixMax(*scfLast, *scfNext); - } - else if ((sfbLast==-1) && (sfbAct>=0) && (sfbNext<psyOutChan->sfbCnt)) { + scfMin = fixMin(*scfLast, *scfNext); + scfMax = fixMax(*scfLast, *scfNext); + } else if ((sfbLast == -1) && (sfbAct >= 0) && + (sfbNext < psyOutChan->sfbCnt)) { /* first relevant scf */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = &scfAct; scfNext = scf + sfbNext; - scfMin = *scfNext; - scfMax = *scfNext; - } - else if ((sfbLast>=0) && (sfbAct>=0) && (sfbNext==psyOutChan->sfbCnt)) { + scfMin = *scfNext; + scfMax = *scfNext; + } else if ((sfbLast >= 0) && (sfbAct >= 0) && + (sfbNext == psyOutChan->sfbCnt)) { /* last relevant scf */ - scfAct = scf[sfbAct]; + scfAct = scf[sfbAct]; scfLast = scf + sfbLast; scfNext = &scfAct; - scfMin = *scfLast; - scfMax = *scfLast; + scfMin = *scfLast; + scfMax = *scfLast; } - if (sfbAct>=0) - scfMin = fixMax(scfMin, minScf[sfbAct]); - - if ((sfbAct >= 0) && - (sfbLast>=0 || sfbNext<psyOutChan->sfbCnt) && - (scfAct > scfMin) && - (scfAct <= scfMin+MAX_SCF_DELTA) && - (scfAct >= scfMax-MAX_SCF_DELTA) && - (*scfLast != prevScfLast[sfbAct] || - *scfNext != prevScfNext[sfbAct] || + if (sfbAct >= 0) scfMin = fixMax(scfMin, minScf[sfbAct]); + + if ((sfbAct >= 0) && (sfbLast >= 0 || sfbNext < psyOutChan->sfbCnt) && + (scfAct > scfMin) && (scfAct <= scfMin + MAX_SCF_DELTA) && + (scfAct >= scfMax - MAX_SCF_DELTA) && + (scfAct <= + fixMin(scfMin, fixMin(*scfLast, *scfNext)) + MAX_SCF_DELTA) && + (*scfLast != prevScfLast[sfbAct] || *scfNext != prevScfNext[sfbAct] || deltaPe < deltaPeLast[sfbAct])) { /* bigger than neighbouring scf found, try to use smaller scf */ success = 0; - sfbWidth = psyOutChan->sfbOffsets[sfbAct+1] - psyOutChan->sfbOffsets[sfbAct]; + sfbWidth = + psyOutChan->sfbOffsets[sfbAct + 1] - psyOutChan->sfbOffsets[sfbAct]; sfbOffs = psyOutChan->sfbOffsets[sfbAct]; /* estimate required bits for actual scf */ enLdData = qcOutChannel->sfbEnergyLdData[sfbAct]; - /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * LOG2_1; */ - /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for log2 */ + /* sfbConstPePart[sfbAct] = (float)log(6.75f*en/sfbFormFactor[sfbAct]) * + * LOG2_1; */ + /* 0.02152255861f = log(6.75)/log(2)/AS_PE_FAC_FLOAT; LOG2_1 is 1.0 for + * log2 */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ if (sfbConstPePart[sfbAct] == (FIXP_DBL)FDK_INT_MIN) { - sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - FL2FXCONST_DBL(0.09375f)) >> 1) + FL2FXCONST_DBL(0.02152255861f); + sfbConstPePart[sfbAct] = ((enLdData - sfbFormFactorLdData[sfbAct] - + FL2FXCONST_DBL(0.09375f)) >> + 1) + + FL2FXCONST_DBL(0.02152255861f); } - sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct]) - +FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); + sfbPeOld = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], + sfbNRelevantLines[sfbAct]) + + FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); deltaPeNew = deltaPe; updateMinScfCalculated = 1; @@ -562,10 +559,12 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, /* estimate required bits for smaller scf */ scfAct--; /* check only if the same check was not done before */ - if (scfAct < minScfCalculated[sfbAct] && scfAct>=scfMax-MAX_SCF_DELTA){ + if (scfAct < minScfCalculated[sfbAct] && + scfAct >= scfMax - MAX_SCF_DELTA) { /* estimate required bits for new scf */ - sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct,sfbConstPePart[sfbAct],sfbNRelevantLines[sfbAct]) - +FDKaacEnc_countSingleScfBits(scfAct,*scfLast, *scfNext); + sfbPeNew = FDKaacEnc_calcSingleSpecPe(scfAct, sfbConstPePart[sfbAct], + sfbNRelevantLines[sfbAct]) + + FDKaacEnc_countSingleScfBits(scfAct, *scfLast, *scfNext); /* use new scf if no increase in pe and quantization error is smaller */ @@ -573,28 +572,24 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */ if (deltaPeTmp < FL2FXCONST_DBL(0.0006103515625f)) { /* distortion of new scf */ - sfbDistNew = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, - quantSpecTmp+sfbOffs, - sfbWidth, - scfAct, - dZoneQuantEnable); + sfbDistNew = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs, quantSpecTmp + sfbOffs, + sfbWidth, scfAct, dZoneQuantEnable); if (sfbDistNew < sfbDist[sfbAct]) { /* success, replace scf by new one */ scf[sfbAct] = scfAct; sfbDist[sfbAct] = sfbDistNew; - for (k=0; k<sfbWidth; k++) - quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k]; + for (k = 0; k < sfbWidth; k++) + quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k]; deltaPeNew = deltaPeTmp; success = 1; } /* mark as already checked */ - if (updateMinScfCalculated) - minScfCalculated[sfbAct] = scfAct; - } - else { + if (updateMinScfCalculated) minScfCalculated[sfbAct] = scfAct; + } else { /* from this scf value on not all new values have been checked */ updateMinScfCalculated = 0; } @@ -612,18 +607,17 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, if (success && restartOnSuccess) { /* start again at first sfb */ sfbLast = -1; - sfbAct = -1; + sfbAct = -1; sfbNext = -1; scfLast = 0; scfNext = 0; - scfMin = FDK_INT_MAX; - scfMax = FDK_INT_MAX; + scfMin = FDK_INT_MAX; + scfMax = FDK_INT_MAX; success = 0; - } - else { + } else { /* shift sfbs for next band */ sfbLast = sfbAct; - sfbAct = sfbNext; + sfbAct = sfbNext; } } while (sfbNext < psyOutChan->sfbCnt); } @@ -632,18 +626,11 @@ static void FDKaacEnc_assimilateSingleScf(PSY_OUT_CHANNEL *psyOutChan, Function: FDKaacEnc_assimilateMultipleScf */ -static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT dZoneQuantEnable, - INT *scf, - INT *minScf, - FIXP_DBL *sfbDist, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines) -{ +static void FDKaacEnc_assimilateMultipleScf( + PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec, + SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf, + FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, + FIXP_DBL *sfbNRelevantLines) { INT sfb, startSfb, stopSfb; INT scfTmp[MAX_GROUPED_SFB], scfMin, scfMax, scfAct; INT possibleRegionFound; @@ -658,31 +645,29 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, /* calc min and max scalfactors */ scfMin = FDK_INT_MAX; scfMax = FDK_INT_MIN; - for (sfb=0; sfb<sfbCnt; sfb++) { - if (scf[sfb]!=FDK_INT_MIN) { + for (sfb = 0; sfb < sfbCnt; sfb++) { + if (scf[sfb] != FDK_INT_MIN) { scfMin = fixMin(scfMin, scf[sfb]); scfMax = fixMax(scfMax, scf[sfb]); } } - if (scfMax != FDK_INT_MIN && scfMax <= scfMin+MAX_SCF_DELTA) { - + if (scfMax != FDK_INT_MIN && scfMax <= scfMin + MAX_SCF_DELTA) { scfAct = scfMax; do { /* try smaller scf */ scfAct--; - for (i=0; i<MAX_GROUPED_SFB; i++) - scfTmp[i] = scf[i]; + for (i = 0; i < MAX_GROUPED_SFB; i++) scfTmp[i] = scf[i]; stopSfb = 0; do { /* search for region where all scfs are bigger than scfAct */ sfb = stopSfb; - while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] <= scfAct)) + while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] <= scfAct)) sfb++; startSfb = sfb; sfb++; - while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN || scf[sfb] > scfAct)) + while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN || scf[sfb] > scfAct)) sfb++; stopSfb = sfb; @@ -690,7 +675,7 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, possibleRegionFound = 0; if (startSfb < sfbCnt) { possibleRegionFound = 1; - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) if (scfAct < minScf[sfb]) { possibleRegionFound = 0; @@ -702,40 +687,38 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, if (possibleRegionFound) { /* region found */ /* replace scfs in region by scfAct */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { - if (scfTmp[sfb] != FDK_INT_MIN) - scfTmp[sfb] = scfAct; + for (sfb = startSfb; sfb < stopSfb; sfb++) { + if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfAct; } /* estimate change in bit demand for new scfs */ - deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb); + deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, + startSfb, stopSfb); - deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines, - startSfb, stopSfb); + deltaSpecPe = FDKaacEnc_calcSpecPeDiff( + psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; /* new bit demand small enough ? */ /* 0.0006103515625f = 10.0f/(2^(2*AS_PE_FAC_SHIFT)) */ if (deltaPeNew < FL2FXCONST_DBL(0.0006103515625f)) { - /* quantize and calc sum of new distortion */ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scfTmp[sfb] != FDK_INT_MIN) { distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; - sfbWidth = psyOutChan->sfbOffsets[sfb+1] - psyOutChan->sfbOffsets[sfb]; + sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - + psyOutChan->sfbOffsets[sfb]; sfbOffs = psyOutChan->sfbOffsets[sfb]; - sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs, - quantSpecTmp+sfbOffs, - sfbWidth, - scfAct, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs, + quantSpecTmp + sfbOffs, sfbWidth, scfAct, dZoneQuantEnable); - if (sfbDistNew[sfb] >qcOutChannel->sfbThresholdLdData[sfb]) { + if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { /* no improvement, skip further dist. calculations */ distNewSum = distOldSum << 1; break; @@ -746,20 +729,19 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, /* distortion smaller ? -> use new scalefactors */ if (distNewSum < distOldSum) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) { - sfbWidth = psyOutChan->sfbOffsets[sfb+1] - + sfbWidth = psyOutChan->sfbOffsets[sfb + 1] - psyOutChan->sfbOffsets[sfb]; sfbOffs = psyOutChan->sfbOffsets[sfb]; scf[sfb] = scfAct; sfbDist[sfb] = sfbDistNew[sfb]; - for (k=0; k<sfbWidth; k++) - quantSpec[sfbOffs+k] = quantSpecTmp[sfbOffs+k]; + for (k = 0; k < sfbWidth; k++) + quantSpec[sfbOffs + k] = quantSpecTmp[sfbOffs + k]; } } } - } } @@ -773,18 +755,11 @@ static void FDKaacEnc_assimilateMultipleScf(PSY_OUT_CHANNEL *psyOutChan, Function: FDKaacEnc_FDKaacEnc_assimilateMultipleScf2 */ -static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutChan, - QC_OUT_CHANNEL *qcOutChannel, - SHORT *quantSpec, - SHORT *quantSpecTmp, - INT dZoneQuantEnable, - INT *scf, - INT *minScf, - FIXP_DBL *sfbDist, - FIXP_DBL *sfbConstPePart, - FIXP_DBL *sfbFormFactorLdData, - FIXP_DBL *sfbNRelevantLines) -{ +static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2( + PSY_OUT_CHANNEL *psyOutChan, QC_OUT_CHANNEL *qcOutChannel, SHORT *quantSpec, + SHORT *quantSpecTmp, INT dZoneQuantEnable, INT *scf, const INT *minScf, + FIXP_DBL *sfbDist, FIXP_DBL *sfbConstPePart, FIXP_DBL *sfbFormFactorLdData, + FIXP_DBL *sfbNRelevantLines) { INT sfb, startSfb, stopSfb; INT scfTmp[MAX_GROUPED_SFB], scfAct, scfNew; INT scfPrev, scfNext, scfPrevNextMin, scfPrevNextMax, scfLo, scfHi; @@ -798,13 +773,13 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh FIXP_DBL deltaPeNew = FL2FXCONST_DBL(0.0f); INT sfbCnt = psyOutChan->sfbCnt; INT bSuccess, bCheckScf; - INT i,k; + INT i, k; /* calc min and max scalfactors */ scfMin = FDK_INT_MAX; scfMax = FDK_INT_MIN; - for (sfb=0; sfb<sfbCnt; sfb++) { - if (scf[sfb]!=FDK_INT_MIN) { + for (sfb = 0; sfb < sfbCnt; sfb++) { + if (scf[sfb] != FDK_INT_MIN) { scfMin = fixMin(scfMin, scf[sfb]); scfMax = fixMax(scfMax, scf[sfb]); } @@ -817,12 +792,12 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh scfPrev = scfAct; sfb = stopSfb; - while (sfb<sfbCnt && (scf[sfb]==FDK_INT_MIN)) - sfb++; + while (sfb < sfbCnt && (scf[sfb] == FDK_INT_MIN)) sfb++; startSfb = sfb; scfAct = scf[startSfb]; sfb++; - while (sfb<sfbCnt && ((scf[sfb]==FDK_INT_MIN) || (scf[sfb]==scf[startSfb]))) + while (sfb < sfbCnt && + ((scf[sfb] == FDK_INT_MIN) || (scf[sfb] == scf[startSfb]))) sfb++; stopSfb = sfb; @@ -831,8 +806,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh else scfNext = scfAct; - if (scfPrev == FDK_INT_MIN) - scfPrev = scfAct; + if (scfPrev == FDK_INT_MIN) scfPrev = scfAct; scfPrevNextMax = fixMax(scfPrev, scfNext); scfPrevNextMin = fixMin(scfPrev, scfNext); @@ -847,39 +821,49 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh else scfLo = scfPrevNextMax; - if (startSfb < sfbCnt && scfHi-scfLo <= MAX_SCF_DELTA) { /* region found */ + if (startSfb < sfbCnt && + scfHi - scfLo <= MAX_SCF_DELTA) { /* region found */ /* 1. try to save bits by coarser quantization */ if (scfHi > scf[startSfb]) { /* calculate the allowed distortion */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) { - /* sfbDistMax[sfb] = (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); */ - /* sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); */ + /* sfbDistMax[sfb] = + * (float)pow(qcOutChannel->sfbThreshold[sfb]*sfbDist[sfb]*sfbDist[sfb],1.0f/3.0f); + */ + /* sfbDistMax[sfb] = + * fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergy[sfb]*FL2FXCONST_DBL(1.e-3f)); + */ /* -0.15571537944 = ld64(1.e-3f)*/ - sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f/3.0f),qcOutChannel->sfbThresholdLdData[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb])+fMult(FL2FXCONST_DBL(1.0f/3.0f),sfbDist[sfb]); - sfbDistMax[sfb] = fixMax(sfbDistMax[sfb],qcOutChannel->sfbEnergyLdData[sfb]-FL2FXCONST_DBL(0.15571537944)); - sfbDistMax[sfb] = fixMin(sfbDistMax[sfb],qcOutChannel->sfbThresholdLdData[sfb]); + sfbDistMax[sfb] = fMult(FL2FXCONST_DBL(1.0f / 3.0f), + qcOutChannel->sfbThresholdLdData[sfb]) + + fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]) + + fMult(FL2FXCONST_DBL(1.0f / 3.0f), sfbDist[sfb]); + sfbDistMax[sfb] = + fixMax(sfbDistMax[sfb], qcOutChannel->sfbEnergyLdData[sfb] - + FL2FXCONST_DBL(0.15571537944)); + sfbDistMax[sfb] = + fixMin(sfbDistMax[sfb], qcOutChannel->sfbThresholdLdData[sfb]); } } /* loop over all possible scf values for this region */ bCheckScf = 1; - for (scfNew=scf[startSfb]+1; scfNew<=scfHi; scfNew++) { - for (k=0; k<MAX_GROUPED_SFB; k++) - scfTmp[k] = scf[k]; + for (scfNew = scf[startSfb] + 1; scfNew <= scfHi; scfNew++) { + for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k]; /* replace scfs in region by scfNew */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { - if (scfTmp[sfb] != FDK_INT_MIN) - scfTmp[sfb] = scfNew; + for (sfb = startSfb; sfb < stopSfb; sfb++) { + if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew; } /* estimate change in bit demand for new scfs */ - deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb); + deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, + startSfb, stopSfb); - deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines, - startSfb, stopSfb); + deltaSpecPe = FDKaacEnc_calcSpecPeDiff( + psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; @@ -888,13 +872,12 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh bSuccess = 1; /* quantize and calc sum of new distortion */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scfTmp[sfb] != FDK_INT_MIN) { - sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], - quantSpecTmp+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], - scfNew, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpecTmp + sfbOffs[sfb], + sfbOffs[sfb + 1] - sfbOffs[sfb], scfNew, dZoneQuantEnable); if (sfbDistNew[sfb] > sfbDistMax[sfb]) { /* no improvement, skip further dist. calculations */ @@ -908,18 +891,19 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh } } } - if (bCheckScf==0) /* further calculations useless ? */ - break; + if (bCheckScf == 0) /* further calculations useless ? */ + break; /* distortion small enough ? -> use new scalefactors */ if (bSuccess) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) { scf[sfb] = scfNew; sfbDist[sfb] = sfbDistNew[sfb]; - for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++) - quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k]; + for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++) + quantSpec[sfbOffs[sfb] + k] = + quantSpecTmp[sfbOffs[sfb] + k]; } } } @@ -930,52 +914,47 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh /* 2. only if coarser quantization was not successful, try to find a better solution by finer quantization and reducing bits for scalefactor coding */ - if (scfAct==scf[startSfb] && - scfLo < scfAct && - scfMax-scfMin <= MAX_SCF_DELTA) { - + if (scfAct == scf[startSfb] && scfLo < scfAct && + scfMax - scfMin <= MAX_SCF_DELTA) { int bminScfViolation = 0; - for (k=0; k<MAX_GROUPED_SFB; k++) - scfTmp[k] = scf[k]; + for (k = 0; k < MAX_GROUPED_SFB; k++) scfTmp[k] = scf[k]; scfNew = scfLo; /* replace scfs in region by scfNew and check if in all sfb scfNew >= minScf[sfb] */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scfTmp[sfb] != FDK_INT_MIN) { scfTmp[sfb] = scfNew; - if (scfNew < minScf[sfb]) - bminScfViolation = 1; + if (scfNew < minScf[sfb]) bminScfViolation = 1; } } if (!bminScfViolation) { /* estimate change in bit demand for new scfs */ - deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb); + deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, + startSfb, stopSfb); - deltaSpecPe = FDKaacEnc_calcSpecPeDiff(psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines, - startSfb, stopSfb); + deltaSpecPe = FDKaacEnc_calcSpecPeDiff( + psyOutChan, qcOutChannel, scf, scfTmp, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines, startSfb, stopSfb); deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits + deltaSpecPe; } /* new bit demand small enough ? */ if (!bminScfViolation && deltaPeNew < FL2FXCONST_DBL(0.0f)) { - /* quantize and calc sum of new distortion */ distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scfTmp[sfb] != FDK_INT_MIN) { distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; - sfbDistNew[sfb] = FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], - quantSpecTmp+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], - scfNew, - dZoneQuantEnable); + sfbDistNew[sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpecTmp + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], + scfNew, dZoneQuantEnable); if (sfbDistNew[sfb] > qcOutChannel->sfbThresholdLdData[sfb]) { /* no improvement, skip further dist. calculations */ @@ -986,15 +965,15 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh } } /* distortion smaller ? -> use new scalefactors */ - if (distNewSum < fMult(FL2FXCONST_DBL(0.8f),distOldSum)) { + if (distNewSum < fMult(FL2FXCONST_DBL(0.8f), distOldSum)) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) { scf[sfb] = scfNew; sfbDist[sfb] = sfbDistNew[sfb]; - for (k=0; k<sfbOffs[sfb+1]-sfbOffs[sfb]; k++) - quantSpec[sfbOffs[sfb]+k] = quantSpecTmp[sfbOffs[sfb]+k]; + for (k = 0; k < sfbOffs[sfb + 1] - sfbOffs[sfb]; k++) + quantSpec[sfbOffs[sfb] + k] = quantSpecTmp[sfbOffs[sfb] + k]; } } } @@ -1003,43 +982,45 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh /* 3. try to find a better solution (save bits) by only reducing the scalefactor without new quantization */ - if (scfMax-scfMin <= MAX_SCF_DELTA-3) { /* 3 bec. scf is reduced 3 times, - see for loop below */ + if (scfMax - scfMin <= + MAX_SCF_DELTA - 3) { /* 3 bec. scf is reduced 3 times, + see for loop below */ - for (k=0; k<sfbCnt; k++) - scfTmp[k] = scf[k]; + for (k = 0; k < sfbCnt; k++) scfTmp[k] = scf[k]; - for (i=0; i<3; i++) { - scfNew = scfTmp[startSfb]-1; + for (i = 0; i < 3; i++) { + scfNew = scfTmp[startSfb] - 1; /* replace scfs in region by scfNew */ - for (sfb=startSfb; sfb<stopSfb; sfb++) { - if (scfTmp[sfb] != FDK_INT_MIN) - scfTmp[sfb] = scfNew; + for (sfb = startSfb; sfb < stopSfb; sfb++) { + if (scfTmp[sfb] != FDK_INT_MIN) scfTmp[sfb] = scfNew; } /* estimate change in bit demand for new scfs */ - deltaScfBits = FDKaacEnc_countScfBitsDiff(scf,scfTmp,sfbCnt,startSfb,stopSfb); + deltaScfBits = FDKaacEnc_countScfBitsDiff(scf, scfTmp, sfbCnt, + startSfb, stopSfb); deltaPeNew = deltaPe + (FIXP_DBL)deltaScfBits; /* new bit demand small enough ? */ if (deltaPeNew <= FL2FXCONST_DBL(0.0f)) { - bSuccess = 1; distOldSum = distNewSum = FL2FXCONST_DBL(0.0f); - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scfTmp[sfb] != FDK_INT_MIN) { FIXP_DBL sfbEnQ; /* calc the energy and distortion of the quantized spectrum for a smaller scf */ - FDKaacEnc_calcSfbQuantEnergyAndDist(qcOutChannel->mdctSpectrum+sfbOffs[sfb], - quantSpec+sfbOffs[sfb], - sfbOffs[sfb+1]-sfbOffs[sfb], scfNew, - &sfbEnQ, &sfbDistNew[sfb]); + FDKaacEnc_calcSfbQuantEnergyAndDist( + qcOutChannel->mdctSpectrum + sfbOffs[sfb], + quantSpec + sfbOffs[sfb], sfbOffs[sfb + 1] - sfbOffs[sfb], + scfNew, &sfbEnQ, &sfbDistNew[sfb]); distOldSum += CalcInvLdData(sfbDist[sfb]) >> DIST_FAC_SHIFT; distNewSum += CalcInvLdData(sfbDistNew[sfb]) >> DIST_FAC_SHIFT; /* 0.00259488556167 = ld64(1.122f) */ /* -0.00778722686652 = ld64(0.7079f) */ - if ((sfbDistNew[sfb] > (sfbDist[sfb]+FL2FXCONST_DBL(0.00259488556167f))) || (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - FL2FXCONST_DBL(0.00778722686652f)))){ + if ((sfbDistNew[sfb] > + (sfbDist[sfb] + FL2FXCONST_DBL(0.00259488556167f))) || + (sfbEnQ < (qcOutChannel->sfbEnergyLdData[sfb] - + FL2FXCONST_DBL(0.00778722686652f)))) { bSuccess = 0; break; } @@ -1048,7 +1029,7 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh /* distortion smaller ? -> use new scalefactors */ if (distNewSum < distOldSum && bSuccess) { deltaPe = deltaPeNew; - for (sfb=startSfb; sfb<stopSfb; sfb++) { + for (sfb = startSfb; sfb < stopSfb; sfb++) { if (scf[sfb] != FDK_INT_MIN) { scf[sfb] = scfNew; sfbDist[sfb] = sfbDistNew[sfb]; @@ -1060,20 +1041,13 @@ static void FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(PSY_OUT_CHANNEL *psyOutCh } } } while (stopSfb <= sfbCnt); - } -static void -FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, - PSY_OUT_CHANNEL *psyOutChannel, - INT *RESTRICT scf, - INT *RESTRICT globalGain, - FIXP_DBL *RESTRICT sfbFormFactorLdData - ,const INT invQuant, - SHORT *RESTRICT quantSpec, - const INT dZoneQuantEnable - ) -{ +static void FDKaacEnc_EstimateScaleFactorsChannel( + QC_OUT_CHANNEL *qcOutChannel, PSY_OUT_CHANNEL *psyOutChannel, + INT *RESTRICT scf, INT *RESTRICT globalGain, + FIXP_DBL *RESTRICT sfbFormFactorLdData, const INT invQuant, + SHORT *RESTRICT quantSpec, const INT dZoneQuantEnable) { INT i, j, sfb, sfbOffs; INT scfInt; INT maxSf; @@ -1084,46 +1058,45 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, FIXP_DBL thresholdPartLdData; FIXP_DBL scfFract; FIXP_DBL maxSpec; - FIXP_DBL absSpec; INT minScfCalculated[MAX_GROUPED_SFB]; FIXP_DBL sfbDistLdData[MAX_GROUPED_SFB]; - C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024)); + C_ALLOC_SCRATCH_START(quantSpecTmp, SHORT, (1024)) INT minSfMaxQuant[MAX_GROUPED_SFB]; - FIXP_DBL threshConstLdData=FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */ - FIXP_DBL convConst=FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */ - FIXP_DBL c1Const=FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */ - + FIXP_DBL threshConstLdData = + FL2FXCONST_DBL(0.04304511722f); /* log10(6.75)/log10(2.0)/64.0 */ + FIXP_DBL convConst = FL2FXCONST_DBL(0.30102999566f); /* log10(2.0) */ + FIXP_DBL c1Const = + FL2FXCONST_DBL(-0.27083183594f); /* C1 = -69.33295 => C1/2^8 */ - - if (invQuant>0) { - FDKmemclear(quantSpec, (1024)*sizeof(SHORT)); + if (invQuant > 0) { + FDKmemclear(quantSpec, (1024) * sizeof(SHORT)); } /* scfs without energy or with thresh>energy are marked with FDK_INT_MIN */ - for(i=0; i<psyOutChannel->sfbCnt; i++) { + for (i = 0; i < psyOutChannel->sfbCnt; i++) { scf[i] = FDK_INT_MIN; } - for (i=0; i<MAX_GROUPED_SFB; i++) { + for (i = 0; i < MAX_GROUPED_SFB; i++) { minSfMaxQuant[i] = FDK_INT_MIN; } - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { - for(sfb=0; sfb<psyOutChannel->maxSfbPerGroup; sfb++) { - - threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs+sfb]; - energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs+sfb]; - - sfbDistLdData[sfbOffs+sfb] = energyLdData; + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { + for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { + threshLdData = qcOutChannel->sfbThresholdLdData[sfbOffs + sfb]; + energyLdData = qcOutChannel->sfbEnergyLdData[sfbOffs + sfb]; + sfbDistLdData[sfbOffs + sfb] = energyLdData; if (energyLdData > threshLdData) { FIXP_DBL tmp; /* energyPart = (float)log10(sfbFormFactor[sfbOffs+sfb]); */ /* 0.09375f = log(64.0)/log(2.0)/64.0 = scale of sfbFormFactorLdData */ - energyPartLdData = sfbFormFactorLdData[sfbOffs+sfb] + FL2FXCONST_DBL(0.09375f); + energyPartLdData = + sfbFormFactorLdData[sfbOffs + sfb] + FL2FXCONST_DBL(0.09375f); /* influence of allowed distortion */ /* thresholdPart = (float)log10(6.75*thresh+FLT_MIN); */ @@ -1133,165 +1106,166 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, /* scfFloat = 8.8585f * (thresholdPart - energyPart); */ scfFract = thresholdPartLdData - energyPartLdData; /* conversion from log2 to log10 */ - scfFract = fMult(convConst,scfFract); + scfFract = fMult(convConst, scfFract); /* (8.8585f * scfFract)/8 = 8/8 * scfFract + 0.8585 * scfFract/8 */ - scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f),scfFract >> 3); + scfFract = scfFract + fMult(FL2FXCONST_DBL(0.8585f), scfFract >> 3); /* integer scalefactor */ /* scfInt = (int)floor(scfFloat); */ - scfInt = (INT)(scfFract>>((DFRACT_BITS-1)-3-LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */ + scfInt = + (INT)(scfFract >> + ((DFRACT_BITS - 1) - 3 - + LD_DATA_SHIFT)); /* 3 bits => scfFract/8.0; 6 bits => ld64 */ /* maximum of spectrum */ maxSpec = FL2FXCONST_DBL(0.0f); - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ){ - absSpec = fixp_abs(qcOutChannel->mdctSpectrum[j]); - maxSpec = (absSpec > maxSpec) ? absSpec : maxSpec; + /* Unroll by 4, allow dual memory access */ + DWORD_ALIGNED(qcOutChannel->mdctSpectrum); + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j += 4) { + maxSpec = fMax(maxSpec, + fMax(fMax(fAbs(qcOutChannel->mdctSpectrum[j + 0]), + fAbs(qcOutChannel->mdctSpectrum[j + 1])), + fMax(fAbs(qcOutChannel->mdctSpectrum[j + 2]), + fAbs(qcOutChannel->mdctSpectrum[j + 3])))); } - /* lower scf limit to avoid quantized values bigger than MAX_QUANT */ /* C1 = -69.33295f, C2 = 5.77078f = 4/log(2) */ /* minSfMaxQuant[sfbOffs+sfb] = (int)ceil(C1 + C2*log(maxSpec)); */ - /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */ + /* C1/2^8 + 4/log(2.0)*log(maxSpec)/2^8 => C1/2^8 + + * log(maxSpec)/log(2.0)*4/2^8 => C1/2^8 + log(maxSpec)/log(2.0)/64.0 */ - //minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) >> ((DFRACT_BITS-1)-8))) + 1; + // minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + CalcLdData(maxSpec)) + // >> ((DFRACT_BITS-1)-8))) + 1; tmp = CalcLdData(maxSpec); - if (c1Const>FL2FXCONST_DBL(-1.f)-tmp) { - minSfMaxQuant[sfbOffs+sfb] = ((INT) ((c1Const + tmp) >> ((DFRACT_BITS-1)-8))) + 1; + if (c1Const > FL2FXCONST_DBL(-1.f) - tmp) { + minSfMaxQuant[sfbOffs + sfb] = + ((INT)((c1Const + tmp) >> ((DFRACT_BITS - 1) - 8))) + 1; + } else { + minSfMaxQuant[sfbOffs + sfb] = + ((INT)(FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS - 1) - 8))) + 1; } - else { - minSfMaxQuant[sfbOffs+sfb] = ((INT) (FL2FXCONST_DBL(-1.f) >> ((DFRACT_BITS-1)-8))) + 1; - } - - scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs+sfb]); + scfInt = fixMax(scfInt, minSfMaxQuant[sfbOffs + sfb]); /* find better scalefactor with analysis by synthesis */ - if (invQuant>0) { - scfInt = FDKaacEnc_improveScf(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpecTmp+psyOutChannel->sfbOffsets[sfbOffs+sfb], - psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], - threshLdData, scfInt, minSfMaxQuant[sfbOffs+sfb], - &sfbDistLdData[sfbOffs+sfb], &minScfCalculated[sfbOffs+sfb], - dZoneQuantEnable - ); + if (invQuant > 0) { + scfInt = FDKaacEnc_improveScf( + qcOutChannel->mdctSpectrum + + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpecTmp + psyOutChannel->sfbOffsets[sfbOffs + sfb], + psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - + psyOutChannel->sfbOffsets[sfbOffs + sfb], + threshLdData, scfInt, minSfMaxQuant[sfbOffs + sfb], + &sfbDistLdData[sfbOffs + sfb], &minScfCalculated[sfbOffs + sfb], + dZoneQuantEnable); } - scf[sfbOffs+sfb] = scfInt; + scf[sfbOffs + sfb] = scfInt; } } } - - if (invQuant>1) { + if (invQuant > 0) { /* try to decrease scf differences */ FIXP_DBL sfbConstPePart[MAX_GROUPED_SFB]; FIXP_DBL sfbNRelevantLines[MAX_GROUPED_SFB]; - for (i=0; i<psyOutChannel->sfbCnt; i++) + for (i = 0; i < psyOutChannel->sfbCnt; i++) sfbConstPePart[i] = (FIXP_DBL)FDK_INT_MIN; - FDKaacEnc_calcSfbRelevantLines( sfbFormFactorLdData, - qcOutChannel->sfbEnergyLdData, - qcOutChannel->sfbThresholdLdData, - psyOutChannel->sfbOffsets, - psyOutChannel->sfbCnt, - psyOutChannel->sfbPerGroup, - psyOutChannel->maxSfbPerGroup, - sfbNRelevantLines); - - - FDKaacEnc_assimilateSingleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines, minScfCalculated, 1); - - if(invQuant > 1) { - FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); - - FDKaacEnc_assimilateMultipleScf(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); - - - FDKaacEnc_FDKaacEnc_assimilateMultipleScf2(psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, - dZoneQuantEnable, - scf, - minSfMaxQuant, sfbDistLdData, sfbConstPePart, - sfbFormFactorLdData, sfbNRelevantLines); + FDKaacEnc_calcSfbRelevantLines( + sfbFormFactorLdData, qcOutChannel->sfbEnergyLdData, + qcOutChannel->sfbThresholdLdData, psyOutChannel->sfbOffsets, + psyOutChannel->sfbCnt, psyOutChannel->sfbPerGroup, + psyOutChannel->maxSfbPerGroup, sfbNRelevantLines); + + FDKaacEnc_assimilateSingleScf( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, dZoneQuantEnable, + scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, sfbFormFactorLdData, + sfbNRelevantLines, minScfCalculated, 1); + + if (invQuant > 1) { + FDKaacEnc_assimilateMultipleScf( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, + dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines); + + FDKaacEnc_FDKaacEnc_assimilateMultipleScf2( + psyOutChannel, qcOutChannel, quantSpec, quantSpecTmp, + dZoneQuantEnable, scf, minSfMaxQuant, sfbDistLdData, sfbConstPePart, + sfbFormFactorLdData, sfbNRelevantLines); } } - /* get min scalefac */ minSf = FDK_INT_MAX; - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if (scf[sfbOffs+sfb]!=FDK_INT_MIN) - minSf = fixMin(minSf,scf[sfbOffs+sfb]); + if (scf[sfbOffs + sfb] != FDK_INT_MIN) + minSf = fixMin(minSf, scf[sfbOffs + sfb]); } } /* limit scf delta */ - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if ((scf[sfbOffs+sfb] != FDK_INT_MIN) && (minSf+MAX_SCF_DELTA) < scf[sfbOffs+sfb]) { - scf[sfbOffs+sfb] = minSf + MAX_SCF_DELTA; + if ((scf[sfbOffs + sfb] != FDK_INT_MIN) && + (minSf + MAX_SCF_DELTA) < scf[sfbOffs + sfb]) { + scf[sfbOffs + sfb] = minSf + MAX_SCF_DELTA; if (invQuant > 0) { /* changed bands need to be quantized again */ - sfbDistLdData[sfbOffs+sfb] = - FDKaacEnc_calcSfbDist(qcOutChannel->mdctSpectrum+psyOutChannel->sfbOffsets[sfbOffs+sfb], - quantSpec+psyOutChannel->sfbOffsets[sfbOffs+sfb], - psyOutChannel->sfbOffsets[sfbOffs+sfb+1]-psyOutChannel->sfbOffsets[sfbOffs+sfb], - scf[sfbOffs+sfb], - dZoneQuantEnable - ); + sfbDistLdData[sfbOffs + sfb] = FDKaacEnc_calcSfbDist( + qcOutChannel->mdctSpectrum + + psyOutChannel->sfbOffsets[sfbOffs + sfb], + quantSpec + psyOutChannel->sfbOffsets[sfbOffs + sfb], + psyOutChannel->sfbOffsets[sfbOffs + sfb + 1] - + psyOutChannel->sfbOffsets[sfbOffs + sfb], + scf[sfbOffs + sfb], dZoneQuantEnable); } } } } - /* get max scalefac for global gain */ maxSf = FDK_INT_MIN; - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - maxSf = fixMax(maxSf,scf[sfbOffs+sfb]); + maxSf = fixMax(maxSf, scf[sfbOffs + sfb]); } } /* calc loop scalefactors, if spec is not all zero (i.e. maxSf == -99) */ - if( maxSf > FDK_INT_MIN ) { + if (maxSf > FDK_INT_MIN) { *globalGain = maxSf; - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - if( scf[sfbOffs+sfb] == FDK_INT_MIN ) { - scf[sfbOffs+sfb] = 0; + if (scf[sfbOffs + sfb] == FDK_INT_MIN) { + scf[sfbOffs + sfb] = 0; /* set band explicitely to zero */ - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) { + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); } - } - else { - scf[sfbOffs+sfb] = maxSf - scf[sfbOffs+sfb]; + } else { + scf[sfbOffs + sfb] = maxSf - scf[sfbOffs + sfb]; } } } - } - else{ + } else { *globalGain = 0; /* set spectrum explicitely to zero */ - for (sfbOffs=0; sfbOffs<psyOutChannel->sfbCnt; sfbOffs+=psyOutChannel->sfbPerGroup) { + for (sfbOffs = 0; sfbOffs < psyOutChannel->sfbCnt; + sfbOffs += psyOutChannel->sfbPerGroup) { for (sfb = 0; sfb < psyOutChannel->maxSfbPerGroup; sfb++) { - scf[sfbOffs+sfb] = 0; + scf[sfbOffs + sfb] = 0; /* set band explicitely to zero */ - for(j=psyOutChannel->sfbOffsets[sfbOffs+sfb]; j<psyOutChannel->sfbOffsets[sfbOffs+sfb+1]; j++ ) { + for (j = psyOutChannel->sfbOffsets[sfbOffs + sfb]; + j < psyOutChannel->sfbOffsets[sfbOffs + sfb + 1]; j++) { qcOutChannel->mdctSpectrum[j] = FL2FXCONST_DBL(0.0f); } } @@ -1299,32 +1273,20 @@ FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(QC_OUT_CHANNEL *qcOutChannel, } /* free quantSpecTmp from scratch */ - C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024)); - - + C_ALLOC_SCRATCH_END(quantSpecTmp, SHORT, (1024)) } -void -FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], - QC_OUT_CHANNEL* qcOutChannel[], - const int invQuant, - const INT dZoneQuantEnable, - const int nChannels) -{ +void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], + QC_OUT_CHANNEL *qcOutChannel[], + const INT invQuant, + const INT dZoneQuantEnable, + const INT nChannels) { int ch; - for (ch = 0; ch < nChannels; ch++) - { - FDKaacEnc_FDKaacEnc_EstimateScaleFactorsChannel(qcOutChannel[ch], - psyOutChannel[ch], - qcOutChannel[ch]->scf, - &qcOutChannel[ch]->globalGain, - qcOutChannel[ch]->sfbFormFactorLdData - ,invQuant, - qcOutChannel[ch]->quantSpec, - dZoneQuantEnable - ); + for (ch = 0; ch < nChannels; ch++) { + FDKaacEnc_EstimateScaleFactorsChannel( + qcOutChannel[ch], psyOutChannel[ch], qcOutChannel[ch]->scf, + &qcOutChannel[ch]->globalGain, qcOutChannel[ch]->sfbFormFactorLdData, + invQuant, qcOutChannel[ch]->quantSpec, dZoneQuantEnable); } - } - diff --git a/libAACenc/src/sf_estim.h b/libAACenc/src/sf_estim.h index ef8d366..ab2d3c2 100644 --- a/libAACenc/src/sf_estim.h +++ b/libAACenc/src/sf_estim.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,40 +90,35 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M. Werner - contents/description: Scale factor estimation + Author(s): M. Werner -******************************************************************************/ + Description: Scale factor estimation -#ifndef _SF_ESTIM_H -#define _SF_ESTIM_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef SF_ESTIM_H +#define SF_ESTIM_H +#include "common_fix.h" #include "psy_const.h" #include "qc_data.h" #include "interface.h" -#define FORM_FAC_SHIFT 6 - - -void -FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], - PSY_OUT_CHANNEL *psyOutChannel[(2)], - const INT nChannels); - -void -FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], - QC_OUT_CHANNEL* qcOutChannel[], - const int invQuant, - const INT dZoneQuantEnable, - const int nChannels); +#define FORM_FAC_SHIFT 6 +void FDKaacEnc_CalcFormFactor(QC_OUT_CHANNEL *qcOutChannel[(2)], + PSY_OUT_CHANNEL *psyOutChannel[(2)], + const INT nChannels); +void FDKaacEnc_EstimateScaleFactors(PSY_OUT_CHANNEL *psyOutChannel[], + QC_OUT_CHANNEL *qcOutChannel[], + const INT invQuant, + const INT dZoneQuantEnable, + const INT nChannels); #endif diff --git a/libAACenc/src/spreading.cpp b/libAACenc/src/spreading.cpp index 852da1e..0fb43bb 100644 --- a/libAACenc/src/spreading.cpp +++ b/libAACenc/src/spreading.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,36 +90,36 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M.Werner - Initial author: M.Werner - contents/description: Spreading of energy + Description: Spreading of energy -******************************************************************************/ +*******************************************************************************/ #include "spreading.h" -void FDKaacEnc_SpreadingMax(const INT pbCnt, - const FIXP_DBL *RESTRICT maskLowFactor, - const FIXP_DBL *RESTRICT maskHighFactor, - FIXP_DBL *RESTRICT pbSpreadEnergy) -{ - int i; - FIXP_DBL delay; - - /* slope to higher frequencies */ - delay = pbSpreadEnergy[0]; - for (i=1; i<pbCnt; i++) { - delay = fixMax(pbSpreadEnergy[i], fMult(maskHighFactor[i], delay)); - pbSpreadEnergy[i] = delay; - } - - /* slope to lower frequencies */ - delay = pbSpreadEnergy[pbCnt-1]; - for (i=pbCnt-2; i>=0; i--) { - delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i],delay)); - pbSpreadEnergy[i] = delay; - } +void FDKaacEnc_SpreadingMax(const INT pbCnt, + const FIXP_DBL *RESTRICT maskLowFactor, + const FIXP_DBL *RESTRICT maskHighFactor, + FIXP_DBL *RESTRICT pbSpreadEnergy) { + int i; + FIXP_DBL delay; + + /* slope to higher frequencies */ + delay = pbSpreadEnergy[0]; + for (i = 1; i < pbCnt; i++) { + delay = fixMax(pbSpreadEnergy[i], fMult(maskHighFactor[i], delay)); + pbSpreadEnergy[i] = delay; + } + + /* slope to lower frequencies */ + delay = pbSpreadEnergy[pbCnt - 1]; + for (i = pbCnt - 2; i >= 0; i--) { + delay = fixMax(pbSpreadEnergy[i], fMult(maskLowFactor[i], delay)); + pbSpreadEnergy[i] = delay; + } } diff --git a/libAACenc/src/spreading.h b/libAACenc/src/spreading.h index e1b506c..e693031 100644 --- a/libAACenc/src/spreading.h +++ b/libAACenc/src/spreading.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,24 +90,24 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ -/******************************** MPEG Audio Encoder ************************** +/**************************** AAC encoder library ****************************** - Initial author: M.Werner - contents/description: Spreading of energy and weighted tonality + Author(s): M.Werner -******************************************************************************/ + Description: Spreading of energy and weighted tonality -#ifndef _SPREADING_H -#define _SPREADING_H +*******************************************************************************/ -#include "common_fix.h" +#ifndef SPREADING_H +#define SPREADING_H +#include "common_fix.h" -void FDKaacEnc_SpreadingMax(const INT pbCnt, - const FIXP_DBL *RESTRICT maskLowFactor, - const FIXP_DBL *RESTRICT maskHighFactor, - FIXP_DBL *RESTRICT pbSpreadEnergy); +void FDKaacEnc_SpreadingMax(const INT pbCnt, + const FIXP_DBL *RESTRICT maskLowFactor, + const FIXP_DBL *RESTRICT maskHighFactor, + FIXP_DBL *RESTRICT pbSpreadEnergy); -#endif /* #ifndef _SPREADING_H */ +#endif /* #ifndef SPREADING_H */ diff --git a/libAACenc/src/tns_func.h b/libAACenc/src/tns_func.h index 5e5265d..6099bc7 100644 --- a/libAACenc/src/tns_func.h +++ b/libAACenc/src/tns_func.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,67 +90,40 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): Alex Goeschel - Initial author: Alex Goeschel - contents/description: Temporal noise shaping + Description: Temporal noise shaping -******************************************************************************/ +*******************************************************************************/ -#ifndef _TNS_FUNC_H -#define _TNS_FUNC_H +#ifndef TNS_FUNC_H +#define TNS_FUNC_H #include "common_fix.h" #include "psy_configuration.h" -AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitrate, - INT samplerate, - INT channels, - INT blocktype, - INT granuleLength, - INT isLowDelay, - INT ldSbrPresent, - TNS_CONFIG *tnsConfig, - PSY_CONFIGURATION *psyConfig, - INT active, - INT useTnsPeak ); - -INT FDKaacEnc_TnsDetect( - TNS_DATA *tnsData, - const TNS_CONFIG *tC, - TNS_INFO* tnsInfo, - INT sfbCnt, - FIXP_DBL *spectrum, - INT subBlockNumber, - INT blockType - ); - - - -void FDKaacEnc_TnsSync( - TNS_DATA *tnsDataDest, - const TNS_DATA *tnsDataSrc, - TNS_INFO *tnsInfoDest, - TNS_INFO *tnsInfoSrc, - const INT blockTypeDest, - const INT blockTypeSrc, - const TNS_CONFIG *tC - ); - -INT FDKaacEnc_TnsEncode( - TNS_INFO* tnsInfo, - TNS_DATA* tnsData, - const INT numOfSfb, - const TNS_CONFIG *tC, - const INT lowPassLine, - FIXP_DBL* spectrum, - const INT subBlockNumber, - const INT blockType - ); - - - -#endif /* _TNS_FUNC_H */ +AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration( + INT bitrate, INT samplerate, INT channels, INT blocktype, INT granuleLength, + INT isLowDelay, INT ldSbrPresent, TNS_CONFIG *tnsConfig, + PSY_CONFIGURATION *psyConfig, INT active, INT useTnsPeak); + +INT FDKaacEnc_TnsDetect(TNS_DATA *tnsData, const TNS_CONFIG *tC, + TNS_INFO *tnsInfo, INT sfbCnt, const FIXP_DBL *spectrum, + INT subBlockNumber, INT blockType); + +void FDKaacEnc_TnsSync(TNS_DATA *tnsDataDest, const TNS_DATA *tnsDataSrc, + TNS_INFO *tnsInfoDest, TNS_INFO *tnsInfoSrc, + const INT blockTypeDest, const INT blockTypeSrc, + const TNS_CONFIG *tC); + +INT FDKaacEnc_TnsEncode(TNS_INFO *tnsInfo, TNS_DATA *tnsData, + const INT numOfSfb, const TNS_CONFIG *tC, + const INT lowPassLine, FIXP_DBL *spectrum, + const INT subBlockNumber, const INT blockType); + +#endif /* TNS_FUNC_H */ diff --git a/libAACenc/src/tonality.cpp b/libAACenc/src/tonality.cpp index 7246a34..334e0f1 100644 --- a/libAACenc/src/tonality.cpp +++ b/libAACenc/src/tonality.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,74 +90,77 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - author: M. Werner - contents/description: Convert chaos measure to the tonality index + Description: Convert chaos measure to the tonality index -******************************************************************************/ +*******************************************************************************/ #include "tonality.h" + #include "chaosmeasure.h" -static const FIXP_DBL normlog = (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f * FDKlog(2.0)/FDKlog(2.7182818)); */ - -static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT chaosMeasure, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *RESTRICT sfbOffset, - FIXP_DBL *RESTRICT sfbEnergyLD64 ); - - -void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT sfbEnergyLD64, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *sfbOffset, - INT usePns) -{ - INT j; -#if defined(ARCH_PREFER_MULT_32x16) - FIXP_SGL alpha_0 = FL2FXCONST_SGL(0.25f); /* used in smooth ChaosMeasure */ - FIXP_SGL alpha_1 = FL2FXCONST_SGL(1.0f-0.25f); /* used in smooth ChaosMeasure */ -#else - FIXP_DBL alpha_0 = FL2FXCONST_DBL(0.25f); /* used in smooth ChaosMeasure */ - FIXP_DBL alpha_1 = FL2FXCONST_DBL(1.0f-0.25f); /* used in smooth ChaosMeasure */ +#if defined(__arm__) #endif + +static const FIXP_DBL normlog = + (FIXP_DBL)0xd977d949; /*FL2FXCONST_DBL(-0.4342944819f * + FDKlog(2.0)/FDKlog(2.7182818)); */ + +static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT chaosMeasure, + FIXP_SGL *RESTRICT sfbTonality, + INT sfbCnt, const INT *RESTRICT sfbOffset, + FIXP_DBL *RESTRICT sfbEnergyLD64); + +void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT sfbEnergyLD64, + FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt, + const INT *sfbOffset, INT usePns) { + INT j; INT numberOfLines = sfbOffset[sfbCnt]; - if (!usePns) - return; + if (usePns) { + C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024)) + + /* calculate chaos measure */ + FDKaacEnc_CalculateChaosMeasure(spectrum, numberOfLines, + chaosMeasurePerLine); + + /* smooth ChaosMeasure */ + FIXP_DBL left = chaosMeasurePerLine[0]; + FIXP_DBL right; + for (j = 1; j < (numberOfLines - 1); j += 2) { + right = chaosMeasurePerLine[j]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j] = left; /* 0.25 left + 0.75 right */ + + right = chaosMeasurePerLine[j + 1]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j + 1] = left; + } + if (j == (numberOfLines - 1)) { + right = chaosMeasurePerLine[j]; + right = right - (right >> 2); + left = right + (left >> 2); + chaosMeasurePerLine[j] = left; + } - C_ALLOC_SCRATCH_START(chaosMeasurePerLine, FIXP_DBL, (1024)); - /* calculate chaos measure */ - FDKaacEnc_CalculateChaosMeasure(spectrum, - numberOfLines, - chaosMeasurePerLine); + FDKaacEnc_CalcSfbTonality(spectrum, sfbMaxScaleSpec, chaosMeasurePerLine, + sfbTonality, sfbCnt, sfbOffset, sfbEnergyLD64); - /* smooth ChaosMeasure */ - for (j=1;j<numberOfLines;j++) { - FIXP_DBL tmp = fMultDiv2(alpha_1, chaosMeasurePerLine[j]); - chaosMeasurePerLine[j] = fMultAdd(tmp, alpha_0, chaosMeasurePerLine[j-1]); + C_ALLOC_SCRATCH_END(chaosMeasurePerLine, FIXP_DBL, (1024)) } - - FDKaacEnc_CalcSfbTonality(spectrum, - sfbMaxScaleSpec, - chaosMeasurePerLine, - sfbTonality, - sfbCnt, - sfbOffset, - sfbEnergyLD64); - - C_ALLOC_SCRATCH_END(chaosMeasurePerLine, FIXP_DBL, (1024)); } - /***************************************************************************** functionname: CalculateTonalityIndex @@ -158,47 +172,48 @@ void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, output: sfb wise tonality values *****************************************************************************/ -static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT chaosMeasure, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *RESTRICT sfbOffset, - FIXP_DBL *RESTRICT sfbEnergyLD64 ) -{ - INT i, j; - - for (i=0; i<sfbCnt; i++) { - FIXP_DBL chaosMeasureSfbLD64; - INT shiftBits = fixMax(0,sfbMaxScaleSpec[i] - 4); /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */ - - FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0); - - /* calc chaosMeasurePerSfb */ - for (j=(sfbOffset[i+1]-sfbOffset[i])-1; j>=0; j--) { - FIXP_DBL tmp = (*spectrum++)<<shiftBits; - FIXP_DBL lineNrg = fMultDiv2(tmp, tmp); - chaosMeasureSfb = fMultAddDiv2(chaosMeasureSfb, lineNrg, *chaosMeasure++); - } - - /* calc tonalityPerSfb */ - if (chaosMeasureSfb != FL2FXCONST_DBL(0.0)) +static void FDKaacEnc_CalcSfbTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT chaosMeasure, + FIXP_SGL *RESTRICT sfbTonality, + INT sfbCnt, const INT *RESTRICT sfbOffset, + FIXP_DBL *RESTRICT sfbEnergyLD64) { + INT i; + + for (i = 0; i < sfbCnt; i++) { + FIXP_DBL chaosMeasureSfbLD64; + INT shiftBits = + fixMax(0, sfbMaxScaleSpec[i] - + 4); /* max sfbWidth = 96 ; 2^7=128 => 7/2 = 4 (spc*spc) */ + + INT j; + FIXP_DBL chaosMeasureSfb = FL2FXCONST_DBL(0.0); + + /* calc chaosMeasurePerSfb */ + for (j = (sfbOffset[i + 1] - sfbOffset[i]) - 1; j >= 0; j--) { + FIXP_DBL tmp = (*spectrum++) << shiftBits; + FIXP_DBL lineNrg = fMultDiv2(tmp, tmp); + chaosMeasureSfb = fMultAddDiv2(chaosMeasureSfb, lineNrg, *chaosMeasure++); + } + + /* calc tonalityPerSfb */ + if (chaosMeasureSfb != FL2FXCONST_DBL(0.0)) { + /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */ + chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i]; + chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f / 64) - + ((FIXP_DBL)(shiftBits) << (DFRACT_BITS - 6)); + + if (chaosMeasureSfbLD64 > + FL2FXCONST_DBL(-0.0519051)) /* > ld(0.05)+ld(2) */ { - /* add ld(convtone)/64 and 2/64 bec.fMultDiv2 */ - chaosMeasureSfbLD64 = CalcLdData((chaosMeasureSfb)) - sfbEnergyLD64[i]; - chaosMeasureSfbLD64 += FL2FXCONST_DBL(3.0f/64) - ((FIXP_DBL)(shiftBits)<<(DFRACT_BITS-6)); - - if (chaosMeasureSfbLD64 > FL2FXCONST_DBL(-0.0519051) ) /* > ld(0.05)+ld(2) */ - { - if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0) ) - sfbTonality[i] = FX_DBL2FX_SGL(fMultDiv2( chaosMeasureSfbLD64 , normlog ) << 7); - else - sfbTonality[i] = FL2FXCONST_SGL(0.0); - } + if (chaosMeasureSfbLD64 <= FL2FXCONST_DBL(0.0)) + sfbTonality[i] = + FX_DBL2FX_SGL(fMultDiv2(chaosMeasureSfbLD64, normlog) << 7); else - sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; - } - else + sfbTonality[i] = FL2FXCONST_SGL(0.0); + } else sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; - } + } else + sfbTonality[i] = (FIXP_SGL)MAXVAL_SGL; + } } diff --git a/libAACenc/src/tonality.h b/libAACenc/src/tonality.h index fbe78ee..c5cf4c5 100644 --- a/libAACenc/src/tonality.h +++ b/libAACenc/src/tonality.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,30 +90,26 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/******************************** MPEG Audio Encoder ************************** +----------------------------------------------------------------------------- */ - author: M. Lohwasser - contents/description: Calculate tonality index +/**************************** AAC encoder library ****************************** -******************************************************************************/ + Author(s): M. Lohwasser -#ifndef __TONALITY_H -#define __TONALITY_H + Description: Calculate tonality index -#include "common_fix.h" +*******************************************************************************/ +#ifndef TONALITY_H +#define TONALITY_H +#include "common_fix.h" #include "chaosmeasure.h" +void FDKaacEnc_CalculateFullTonality(FIXP_DBL *RESTRICT spectrum, + INT *RESTRICT sfbMaxScaleSpec, + FIXP_DBL *RESTRICT sfbEnergyLD64, + FIXP_SGL *RESTRICT sfbTonality, INT sfbCnt, + const INT *sfbOffset, INT usePns); -void FDKaacEnc_CalculateFullTonality( FIXP_DBL *RESTRICT spectrum, - INT *RESTRICT sfbMaxScaleSpec, - FIXP_DBL *RESTRICT sfbEnergyLD64, - FIXP_SGL *RESTRICT sfbTonality, - INT sfbCnt, - const INT *sfbOffset, - INT usePns); - -#endif +#endif /* TONALITY_H */ diff --git a/libAACenc/src/transform.cpp b/libAACenc/src/transform.cpp index 690b82e..08b1c2f 100644 --- a/libAACenc/src/transform.cpp +++ b/libAACenc/src/transform.cpp @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,9 +90,11 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/***************************************************************************** + Author(s): Tobias Chalupka Description: FDKaacLdEnc_MdctTransform480: The module FDKaacLdEnc_MdctTransform will perform the MDCT. @@ -90,175 +103,192 @@ amm-info@iis.fraunhofer.de can be divided in Windowing, PreModulation, Fft and PostModulation. -******************************************************************************/ +*******************************************************************************/ #include "transform.h" - #include "dct.h" #include "psy_const.h" #include "aacEnc_rom.h" #include "FDK_tools_rom.h" -INT FDKaacEnc_Transform_Real (const INT_PCM * pTimeData, - FIXP_DBL *RESTRICT mdctData, - const INT blockType, - const INT windowShape, - INT *prevWindowShape, - const INT frameLength, - INT *mdctData_e, - INT filterType - ,FIXP_DBL * RESTRICT overlapAddBuffer - ) -{ - const INT_PCM * RESTRICT timeData; - - INT i; - /* tl: transform length - fl: left window slope length - nl: left window slope offset - fr: right window slope length - nr: right window slope offset - See FDK_tools/doc/intern/mdct.tex for more detail. */ - int tl, fl, nl, fr, nr; +#if defined(__arm__) +#endif - const FIXP_WTP * RESTRICT pLeftWindowPart; - const FIXP_WTP * RESTRICT pRightWindowPart; +INT FDKaacEnc_Transform_Real(const INT_PCM *pTimeData, + FIXP_DBL *RESTRICT mdctData, const INT blockType, + const INT windowShape, INT *prevWindowShape, + H_MDCT mdctPers, const INT frameLength, + INT *pMdctData_e, INT filterType) { + const INT_PCM *RESTRICT timeData; - /* - * MDCT scale: - * + 1: fMultDiv2() in windowing. - * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC. - */ - *mdctData_e = 1+1; + UINT numSpec; + UINT numMdctLines; + UINT offset; + int fr; /* fr: right window slope length */ + SHORT mdctData_e[8]; - tl = frameLength; timeData = pTimeData; - switch( blockType ) { + if (blockType == SHORT_WINDOW) { + numSpec = 8; + numMdctLines = frameLength >> 3; + } else { + numSpec = 1; + numMdctLines = frameLength; + } + + offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3) >> 2) : 0; + switch (blockType) { case LONG_WINDOW: - { - int offset = (windowShape == LOL_WINDOW) ? ((frameLength * 3)>>2) : 0; - fl = frameLength - offset; - fr = frameLength - offset; - } - break; case STOP_WINDOW: - fl = frameLength >> 3; - fr = frameLength; + fr = frameLength - offset; break; case START_WINDOW: /* or StopStartSequence */ - fl = frameLength; - fr = frameLength >> 3; - break; case SHORT_WINDOW: - fl = fr = frameLength >> 3; - tl >>= 3; - timeData = pTimeData + 3*fl + (fl/2); + fr = frameLength >> 3; break; default: FDK_ASSERT(0); return -1; - break; } - /* Taken from FDK_tools/src/mdct.cpp Derive NR and NL */ - nr = (tl - fr)>>1; - nl = (tl - fl)>>1; - - pLeftWindowPart = FDKgetWindowSlope(fl, *prevWindowShape); - pRightWindowPart = FDKgetWindowSlope(fr, windowShape); - - /* windowing */ - if (filterType != FB_ELD) - { - /* Left window slope offset */ - for (i=0; i<nl ; i++) - { -#if SAMPLE_BITS == DFRACT_BITS /* SPC_BITS and DFRACT_BITS should be equal. */ - mdctData[(tl/2)+i] = - (FIXP_DBL) timeData[tl-i-1] >> ( 1 ); -#else - mdctData[(tl/2)+i] = - (FIXP_DBL) timeData[tl-i-1] << (DFRACT_BITS - SAMPLE_BITS - 1); -#endif - } - /* Left window slope */ - for (i=0; i<fl/2; i++) - { - FIXP_DBL tmp0; - tmp0 = fMultDiv2((FIXP_PCM)timeData[i+nl], pLeftWindowPart[i].v.im); - mdctData[(tl/2)+i+nl] = fMultSubDiv2(tmp0, (FIXP_PCM)timeData[tl-nl-i-1], pLeftWindowPart[i].v.re); - } + mdct_block(mdctPers, timeData, frameLength, mdctData, numSpec, numMdctLines, + FDKgetWindowSlope(fr, windowShape), fr, mdctData_e); - /* Right window slope offset */ - for(i=0; i<nr; i++) - { -#if SAMPLE_BITS == DFRACT_BITS /* This should be SPC_BITS instead of DFRACT_BITS. */ - mdctData[(tl/2)-1-i] = - (FIXP_DBL) timeData[tl+i] >> (1); -#else - mdctData[(tl/2)-1-i] = - (FIXP_DBL) timeData[tl+i] << (DFRACT_BITS - SAMPLE_BITS - 1); -#endif - } - /* Right window slope */ - for (i=0; i<fr/2; i++) - { - FIXP_DBL tmp1; - tmp1 = fMultDiv2((FIXP_PCM)timeData[tl+nr+i], pRightWindowPart[i].v.re); - mdctData[(tl/2)-nr-i-1] = -fMultAddDiv2(tmp1, (FIXP_PCM)timeData[(tl*2)-nr-i-1], pRightWindowPart[i].v.im); + if (blockType == SHORT_WINDOW) { + if (!(mdctData_e[0] == mdctData_e[1] && mdctData_e[1] == mdctData_e[2] && + mdctData_e[2] == mdctData_e[3] && mdctData_e[3] == mdctData_e[4] && + mdctData_e[4] == mdctData_e[5] && mdctData_e[5] == mdctData_e[6] && + mdctData_e[6] == mdctData_e[7])) { + return -1; } } + *prevWindowShape = windowShape; + *pMdctData_e = mdctData_e[0]; - if (filterType == FB_ELD) - { - const FIXP_WTB *pWindowELD=NULL; - int i, N = frameLength, L = frameLength; + return 0; +} - if (frameLength == 512) { - pWindowELD = ELDAnalysis512; - } else { - pWindowELD = ELDAnalysis480; - } +INT FDKaacEnc_Transform_Real_Eld(const INT_PCM *pTimeData, + FIXP_DBL *RESTRICT mdctData, + const INT blockType, const INT windowShape, + INT *prevWindowShape, const INT frameLength, + INT *mdctData_e, INT filterType, + FIXP_DBL *RESTRICT overlapAddBuffer) { + const INT_PCM *RESTRICT timeData; - for(i=0;i<N/4;i++) - { - FIXP_DBL z0, outval; + INT i; - z0 = (fMult((FIXP_PCM)timeData[L+N*3/4-1-i], pWindowELD[N/2-1-i])<< (WTS0-1)) + (fMult((FIXP_PCM)timeData[L+N*3/4+i], pWindowELD[N/2+i])<< (WTS0-1)); + /* tl: transform length + fl: left window slope length + nl: left window slope offset + fr: right window slope length + nr: right window slope offset */ + const FIXP_WTB *pWindowELD = NULL; + int N = frameLength; + int L = frameLength; - outval = (fMultDiv2((FIXP_PCM)timeData[L+N*3/4-1-i], pWindowELD[N+N/2-1-i]) >> (-WTS1)); - outval += (fMultDiv2((FIXP_PCM)timeData[L+N*3/4+i], pWindowELD[N+N/2+i]) >> (-WTS1) ); - outval += (fMultDiv2(overlapAddBuffer[N/2+i], pWindowELD[2*N+i])>> (-WTS2-1)); + timeData = pTimeData; - overlapAddBuffer[N/2+i] = overlapAddBuffer[i]; + if (blockType != LONG_WINDOW) { + return -1; + } - overlapAddBuffer[i] = z0; - mdctData[i] = overlapAddBuffer[N/2+i] + (fMultDiv2(overlapAddBuffer[N+N/2-1-i], pWindowELD[2*N+N/2+i]) >> (-WTS2-1)); + /* + * MDCT scale: + * + 1: fMultDiv2() in windowing. + * + 1: Because of factor 1/2 in Princen-Bradley compliant windowed TDAC. + */ + *mdctData_e = 1 + 1; - mdctData[N-1-i] = outval; - overlapAddBuffer[N+N/2-1-i] = outval; - } + switch (frameLength) { + case 512: + pWindowELD = ELDAnalysis512; + break; + case 480: + pWindowELD = ELDAnalysis480; + break; + case 256: + pWindowELD = ELDAnalysis256; + *mdctData_e += 1; + break; + case 240: + pWindowELD = ELDAnalysis240; + *mdctData_e += 1; + break; + case 128: + pWindowELD = ELDAnalysis128; + *mdctData_e += 2; + break; + case 120: + pWindowELD = ELDAnalysis120; + *mdctData_e += 2; + break; + default: + FDK_ASSERT(0); + return -1; + } + + for (i = 0; i < N / 4; i++) { + FIXP_DBL z0, outval; + + z0 = (fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N / 2 - 1 - i]) + << (WTS0 - 1)) + + (fMult((FIXP_PCM)timeData[L + N * 3 / 4 + i], pWindowELD[N / 2 + i]) + << (WTS0 - 1)); + + outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N + N / 2 - 1 - i]) >> + (-WTS1)); + outval += (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 + i], + pWindowELD[N + N / 2 + i]) >> + (-WTS1)); + outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >> + (-WTS2 - 1)); + + overlapAddBuffer[N / 2 + i] = overlapAddBuffer[i]; + + overlapAddBuffer[i] = z0; + mdctData[i] = overlapAddBuffer[N / 2 + i] + + (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i], + pWindowELD[2 * N + N / 2 + i]) >> + (-WTS2 - 1)); + + mdctData[N - 1 - i] = outval; + overlapAddBuffer[N + N / 2 - 1 - i] = outval; + } - for(i=N/4;i<N/2;i++) - { - FIXP_DBL z0, outval; + for (i = N / 4; i < N / 2; i++) { + FIXP_DBL z0, outval; - z0 = fMult((FIXP_PCM)timeData[L+N*3/4-1-i], pWindowELD[N/2-1-i]) << (WTS0-1); + z0 = fMult((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N / 2 - 1 - i]) + << (WTS0 - 1); - outval = (fMultDiv2((FIXP_PCM)timeData[L+N*3/4-1-i], pWindowELD[N+N/2-1-i]) >> (-WTS1)) ; - outval += (fMultDiv2(overlapAddBuffer[N/2+i], pWindowELD[2*N+i]) >> (-WTS2-1)); + outval = (fMultDiv2((FIXP_PCM)timeData[L + N * 3 / 4 - 1 - i], + pWindowELD[N + N / 2 - 1 - i]) >> + (-WTS1)); + outval += (fMultDiv2(overlapAddBuffer[N / 2 + i], pWindowELD[2 * N + i]) >> + (-WTS2 - 1)); - overlapAddBuffer[N/2+i] = overlapAddBuffer[i] + (fMult((FIXP_PCM)timeData[L-N/4+i], pWindowELD[N/2+i])<< (WTS0-1) ); + overlapAddBuffer[N / 2 + i] = + overlapAddBuffer[i] + + (fMult((FIXP_PCM)timeData[L - N / 4 + i], pWindowELD[N / 2 + i]) + << (WTS0 - 1)); - overlapAddBuffer[i] = z0; - mdctData[i] = overlapAddBuffer[N/2+i] + (fMultDiv2(overlapAddBuffer[N+N/2-1-i], pWindowELD[2*N+N/2+i]) >> (-WTS2-1)); + overlapAddBuffer[i] = z0; + mdctData[i] = overlapAddBuffer[N / 2 + i] + + (fMultDiv2(overlapAddBuffer[N + N / 2 - 1 - i], + pWindowELD[2 * N + N / 2 + i]) >> + (-WTS2 - 1)); - mdctData[N-1-i] = outval; - overlapAddBuffer[N+N/2-1-i] = outval; - } + mdctData[N - 1 - i] = outval; + overlapAddBuffer[N + N / 2 - 1 - i] = outval; } - - dct_IV(mdctData, tl, mdctData_e); + dct_IV(mdctData, frameLength, mdctData_e); *prevWindowShape = windowShape; return 0; } - diff --git a/libAACenc/src/transform.h b/libAACenc/src/transform.h index 5053174..8f5ff46 100644 --- a/libAACenc/src/transform.h +++ b/libAACenc/src/transform.h @@ -1,74 +1,85 @@ - -/* ----------------------------------------------------------------------------------------------------------- +/* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. +© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +Forschung e.V. All rights reserved. 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. +The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software +that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding +scheme for digital audio. This FDK AAC Codec software is intended to be used on +a wide variety of Android devices. + +AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient +general perceptual audio codecs. AAC-ELD is considered the best-performing +full-bandwidth communications codec by independent studies and is widely +deployed. AAC has been standardized by ISO and IEC as part of the MPEG +specifications. + +Patent licenses for necessary patent claims for the FDK AAC Codec (including +those of Fraunhofer) may be obtained through Via Licensing +(www.vialicensing.com) or through the respective patent owners individually for +the purpose of encoding or decoding bit streams in products that are compliant +with the ISO/IEC MPEG audio standards. Please note that most manufacturers of +Android devices already license these patent claims through Via Licensing or +directly from the patent owners, and therefore FDK AAC Codec software may +already be covered under those patent licenses when it is used for those +licensed purposes only. + +Commercially-licensed AAC software libraries, including floating-point versions +with enhanced sound quality, are also available from Fraunhofer. Users are +encouraged to check the Fraunhofer website for additional applications +information and documentation. 2. COPYRIGHT LICENSE -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: +Redistribution and use in source and binary forms, with or without modification, +are permitted without payment of copyright license fees provided that you +satisfy the following conditions: -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. +You must retain the complete text of this software license in redistributions of +the FDK AAC Codec or your modifications thereto in source code form. -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your +You must retain the complete text of this software license in the documentation +and/or other materials provided with redistributions of the FDK AAC Codec or +your modifications thereto in binary form. You must make available free of +charge copies of the complete source code of the FDK AAC Codec and your modifications thereto to recipients of copies in binary form. -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. +The name of Fraunhofer may not be used to endorse or promote products derived +from this library without prior written permission. -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. +You may not charge copyright license fees for anyone to use, copy or distribute +the FDK AAC Codec software or your modifications thereto. -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." +Your modified versions of the FDK AAC Codec must carry prominent notices stating +that you changed the software and the date of any change. For modified versions +of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" +must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK +AAC Codec Library for Android." 3. NO PATENT LICENSE -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. +NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without +limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. +Fraunhofer provides no warranty of patent non-infringement with respect to this +software. -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. +You may use this FDK AAC Codec software or modifications thereto only for +purposes that are authorized by appropriate patent licenses. 4. DISCLAIMER -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. +This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright +holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, +including but not limited to the implied warranties of merchantability and +fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, +or consequential damages, including but not limited to procurement of substitute +goods or services; loss of use, data, or profits, or business interruption, +however caused and on any theory of liability, whether in contract, strict +liability, or tort (including negligence), arising in any way out of the use of +this software, even if advised of the possibility of such damage. 5. CONTACT INFORMATION @@ -79,18 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** AAC encoder library ****************************** -/******************************** MPEG Audio Encoder ************************** + Author(s): M. Werner - Initial author: M. Werner - contents/description: MDCT Transform + Description: MDCT Transform -******************************************************************************/ +*******************************************************************************/ -#ifndef _TRANSFORM_H -#define _TRANSFORM_H +#ifndef TRANSFORM_H +#define TRANSFORM_H +#include "mdct.h" #include "common_fix.h" #define WTS0 1 @@ -105,19 +118,46 @@ amm-info@iis.fraunhofer.de * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW. * \param windowShape index indicating the window slope type to be used. * Values allowed are either SINE_WINDOW or KBD_WINDOW. - * \param frameLength length of the block. + * \param previndowShape index indicating the window slope type used + * in the last frame. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param frameLength length of the block. Either 1024 or 960. + * \param mdctData_e pointer to an INT where the exponent of the frequency + * domain output data is stored into. + * \param filterType xxx + * \return 0 in case of success, non-zero in case of error (inconsistent + * parameters). + */ +INT FDKaacEnc_Transform_Real(const INT_PCM* pTimeData, + FIXP_DBL* RESTRICT mdctData, const INT blockType, + const INT windowShape, INT* prevWindowShape, + H_MDCT mdctPers, const INT frameLength, + INT* pMdctData_e, INT filterType); + +/** + * \brief: Performe ELD filterbnank transform of time domain data. + * \param timeData pointer to time domain input signal. + * \param mdctData pointer to store frequency domain output data. + * \param blockType index indicating the type of block. Either + * LONG_WINDOW, START_WINDOW, SHORT_WINDOW or STOP_WINDOW. + * \param windowShape index indicating the window slope type to be used. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param previndowShape index indicating the window slope type used + * in the last frame. + * Values allowed are either SINE_WINDOW or KBD_WINDOW. + * \param frameLength length of the block. Either 1024 or 960. * \param mdctData_e pointer to an INT where the exponent of the frequency * domain output data is stored into. - * \return 0 in case of success, non-zero in case of error (inconsistent parameters). + * \param filterType xxx + * \param overlapAddBuffer overlap add buffer for overlap of ELD filterbank + * \return 0 in case of success, non-zero in case of error (inconsistent + * parameters). */ -INT FDKaacEnc_Transform_Real (const INT_PCM *timeData, - FIXP_DBL *RESTRICT mdctData, - const INT blockType, - const INT windowShape, - INT *prevWindowShape, - const INT frameLength, - INT *mdctData_e, - INT filterType - ,FIXP_DBL * RESTRICT overlapAddBuffer - ); -#endif +INT FDKaacEnc_Transform_Real_Eld(const INT_PCM* pTimeData, + FIXP_DBL* RESTRICT mdctData, + const INT blockType, const INT windowShape, + INT* prevWindowShape, const INT frameLength, + INT* mdctData_e, INT filterType, + FIXP_DBL* RESTRICT overlapAddBuffer); + +#endif /* #!defined (TRANSFORM_H) */ |