diff options
Diffstat (limited to 'libSBRenc/src/sbr_encoder.cpp')
-rw-r--r-- | libSBRenc/src/sbr_encoder.cpp | 2868 |
1 files changed, 1501 insertions, 1367 deletions
diff --git a/libSBRenc/src/sbr_encoder.cpp b/libSBRenc/src/sbr_encoder.cpp index 71aab78..df9e996 100644 --- a/libSBRenc/src/sbr_encoder.cpp +++ b/libSBRenc/src/sbr_encoder.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,19 +90,20 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** SBR encoder library ****************************** -/*************************** Fraunhofer IIS FDK Tools *********************** + Author(s): Andreas Ehret, Tobias Chalupka - Author(s): Andreas Ehret, Tobias Chalupka Description: SBR encoder top level processing. -******************************************************************************/ +*******************************************************************************/ #include "sbr_encoder.h" -#include "sbr_ram.h" -#include "sbr_rom.h" +#include "sbrenc_ram.h" +#include "sbrenc_rom.h" #include "sbrenc_freq_sca.h" #include "env_bit.h" #include "cmondata.h" @@ -101,11 +113,9 @@ amm-info@iis.fraunhofer.de #include "ps_main.h" -#define SBRENCODER_LIB_VL0 3 -#define SBRENCODER_LIB_VL1 3 -#define SBRENCODER_LIB_VL2 12 - - +#define SBRENCODER_LIB_VL0 4 +#define SBRENCODER_LIB_VL1 0 +#define SBRENCODER_LIB_VL2 0 /***************************************************************************/ /* @@ -119,34 +129,83 @@ amm-info@iis.fraunhofer.de (core2sbr delay ) ds (read, core and ds area) */ -#define SFB(dwnsmp) (32 << (dwnsmp-1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */ -#define STS(fl) (((fl)==1024)?32:30) /* SBR Time Slots: 32 for core frame length 1024, 30 for core frame length 960 */ - -#define DELAY_QMF_ANA(dwnsmp) ((320<<((dwnsmp)-1)) - (32<<((dwnsmp)-1))) /* Full bandwidth */ -#define DELAY_HYB_ANA (10*64) /* + 0.5 */ /* */ -#define DELAY_HYB_SYN (6*64 - 32) /* */ -#define DELAY_QMF_POSTPROC(dwnsmp) (32*(dwnsmp)) /* QMF postprocessing delay */ -#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp) ) /* Decoder QMF overlap */ -#define DELAY_QMF_SYN (2) /* NO_POLY/2=2.5, rounded down to 2 */ -#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */ +#define SFB(dwnsmp) \ + (32 << (dwnsmp - \ + 1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */ +#define STS(fl) \ + (((fl) == 1024) ? 32 \ + : 30) /* SBR Time Slots: 32 for core frame length 1024, 30 \ + for core frame length 960 */ + +#define DELAY_QMF_ANA(dwnsmp) \ + ((320 << ((dwnsmp)-1)) - (32 << ((dwnsmp)-1))) /* Full bandwidth */ +#define DELAY_HYB_ANA (10 * 64) /* + 0.5 */ /* */ +#define DELAY_HYB_SYN (6 * 64 - 32) /* */ +#define DELAY_QMF_POSTPROC(dwnsmp) \ + (32 * (dwnsmp)) /* QMF postprocessing delay */ +#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp)) /* Decoder QMF overlap */ +#define DELAY_QMF_SYN(dwnsmp) \ + (1 << (dwnsmp - \ + 1)) /* QMF_NO_POLY/2=2.5, rounded down to 2, half for single-rate */ +#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */ /* Delay in QMF paths */ -#define DELAY_SBR(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp)*STS(fl) - 1) + DELAY_QMF_SYN) -#define DELAY_PS(fl,dwnsmp) (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + (SFB(dwnsmp)*STS(fl)-1) + DELAY_HYB_SYN + DELAY_QMF_SYN) -#define DELAY_ELDSBR(fl,dwnsmp) ( ( ((fl)/2)*(dwnsmp) ) - 1 + DELAY_QMF_POSTPROC(dwnsmp) ) - -/* Delay differences for SBR and SBR+PS */ -#define MAX_DS_FILTER_DELAY (5) /* the additional max downsampler filter delay (source fs) */ -#define DELAY_AAC2SBR(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN) - DELAY_SBR((fl),(dwnsmp))) -#define DELAY_ELD2SBR(fl,dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp)) - DELAY_ELDSBR(fl,dwnsmp)) -#define DELAY_AAC2PS(fl,dwnsmp) ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_HYB_SYN + DELAY_QMF_SYN) - DELAY_PS(fl,dwnsmp)) /* 2048 - 463*2 */ - -/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller than the sample delay implied by DELAY_AAC2SBR */ -#define MAX_SAMPLE_DELAY (DELAY_AAC2SBR(1024,2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame length of 1024 and dual-rate sbr */ +#define DELAY_SBR(fl, dwnsmp) \ + (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_QMF_SYN(dwnsmp)) +#define DELAY_PS(fl, dwnsmp) \ + (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + \ + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp)) +#define DELAY_ELDSBR(fl, dwnsmp) \ + ((((fl) / 2) * (dwnsmp)) - 1 + DELAY_QMF_POSTPROC(dwnsmp)) +#define DELAY_ELDv2SBR(fl, dwnsmp) \ + ((((fl) / 2) * (dwnsmp)) - 1 + 80 * (dwnsmp)) /* 80 is the delay caused \ + by the sum of the CLD \ + analysis and the MPSLD \ + synthesis filterbank */ + +/* Delay in core path (core and downsampler not taken into account) */ +#define DELAY_COREPATH_SBR(fl, dwnsmp) \ + ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN(dwnsmp))) +#define DELAY_COREPATH_ELDSBR(fl, dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp))) +#define DELAY_COREPATH_ELDv2SBR(fl, dwnsmp) (128 * (dwnsmp)) /* 4 slots */ +#define DELAY_COREPATH_PS(fl, dwnsmp) \ + ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + \ + /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + \ + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))) /* 2048 - 463*2 */ + +/* Delay differences between SBR- and downsampled path for SBR and SBR+PS */ +#define DELAY_AAC2SBR(fl, dwnsmp) \ + ((DELAY_COREPATH_SBR(fl, dwnsmp)) - DELAY_SBR((fl), (dwnsmp))) +#define DELAY_ELD2SBR(fl, dwnsmp) \ + ((DELAY_COREPATH_ELDSBR(fl, dwnsmp)) - DELAY_ELDSBR(fl, dwnsmp)) +#define DELAY_AAC2PS(fl, dwnsmp) \ + ((DELAY_COREPATH_PS(fl, dwnsmp)) - DELAY_PS(fl, dwnsmp)) /* 2048 - 463*2 */ + +/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller + * than the sample delay implied by DELAY_AAC2SBR */ +#define MAX_DS_FILTER_DELAY \ + (5) /* the additional max downsampler filter delay (source fs) */ +#define MAX_SAMPLE_DELAY \ + (DELAY_AAC2SBR(1024, 2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame \ + length of 1024 and \ + dual-rate sbr */ /***************************************************************************/ - +/*************** Delay parameters for sbrEncoder_Init_delay() **************/ +typedef struct { + int dsDelay; /* the delay of the (time-domain) downsampler itself */ + int delay; /* overall delay / samples */ + int sbrDecDelay; /* SBR decoder's delay */ + int corePathOffset; /* core path offset / samples; added by + sbrEncoder_Init_delay() */ + int sbrPathOffset; /* SBR path offset / samples; added by + sbrEncoder_Init_delay() */ + int bitstrDelay; /* bitstream delay / frames; added by sbrEncoder_Init_delay() + */ + int delayInput2Core; /* delay of the input to the core / samples */ +} DELAY_PARAM; +/***************************************************************************/ #define INVALID_TABLE_IDX -1 @@ -160,44 +219,38 @@ amm-info@iis.fraunhofer.de ****************************************************************************/ #define DISTANCE_CEIL_VALUE 5000000 -static INT -getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ - UINT numChannels,/*! the number of channels for the core coder */ - UINT sampleRate, /*! the sampling rate of the core coder */ - AUDIO_OBJECT_TYPE core, - UINT *pBitRateClosest - ) -{ - int i, bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1, found = 0; - UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; - - #define isForThisCore(i) \ - ( ( sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD ) || \ - ( sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD ) ) - - for (i=0; i < sbrTuningTableSize ; i++) { - if ( isForThisCore(i) ) /* tuning table is for this core codec */ +static INT getSbrTuningTableIndex( + UINT bitrate, /*! the total bitrate in bits/sec */ + UINT numChannels, /*! the number of channels for the core coder */ + UINT sampleRate, /*! the sampling rate of the core coder */ + AUDIO_OBJECT_TYPE core, UINT *pBitRateClosest) { + int i, bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1, + found = 0; + UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; + +#define isForThisCore(i) \ + ((sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD) || \ + (sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD)) + + for (i = 0; i < sbrTuningTableSize; i++) { + if (isForThisCore(i)) /* tuning table is for this core codec */ { - if ( numChannels == sbrTuningTable [i].numChannels - && sampleRate == sbrTuningTable [i].sampleRate ) - { + if (numChannels == sbrTuningTable[i].numChannels && + sampleRate == sbrTuningTable[i].sampleRate) { found = 1; - if ((bitrate >= sbrTuningTable [i].bitrateFrom) && - (bitrate < sbrTuningTable [i].bitrateTo)) { - bitRateClosestLower = bitrate; - bitRateClosestUpper = bitrate; - //FDKprintf("entry %d\n", i); - return i ; + if ((bitrate >= sbrTuningTable[i].bitrateFrom) && + (bitrate < sbrTuningTable[i].bitrateTo)) { + return i; } else { - if ( sbrTuningTable [i].bitrateFrom > bitrate ) { - if (sbrTuningTable [i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = sbrTuningTable [i].bitrateFrom; + if (sbrTuningTable[i].bitrateFrom > bitrate) { + if (sbrTuningTable[i].bitrateFrom < bitRateClosestLower) { + bitRateClosestLower = sbrTuningTable[i].bitrateFrom; bitRateClosestLowerIndex = i; } } - if ( sbrTuningTable [i].bitrateTo <= bitrate ) { - if (sbrTuningTable [i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = sbrTuningTable [i].bitrateTo-1; + if (sbrTuningTable[i].bitrateTo <= bitrate) { + if (sbrTuningTable[i].bitrateTo > bitRateClosestUpper) { + bitRateClosestUpper = sbrTuningTable[i].bitrateTo - 1; bitRateClosestUpperIndex = i; } } @@ -206,20 +259,25 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ } } - if (pBitRateClosest != NULL) - { - /* If there was at least one matching tuning entry found then pick the least distance bit rate */ - if (found) - { - int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE; + if (bitRateClosestUpperIndex >= 0) { + return bitRateClosestUpperIndex; + } + + if (pBitRateClosest != NULL) { + /* If there was at least one matching tuning entry pick the least distance + * bit rate */ + if (found) { + int distanceUpper = DISTANCE_CEIL_VALUE, + distanceLower = DISTANCE_CEIL_VALUE; if (bitRateClosestLowerIndex >= 0) { - distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate; + distanceLower = + sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; } if (bitRateClosestUpperIndex >= 0) { - distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo; + distanceUpper = + bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; } - if ( distanceUpper < distanceLower ) - { + if (distanceUpper < distanceLower) { *pBitRateClosest = bitRateClosestUpper; } else { *pBitRateClosest = bitRateClosestLower; @@ -241,44 +299,47 @@ getSbrTuningTableIndex(UINT bitrate, /*! the total bitrate in bits/sec */ \return Index to the appropriate table ****************************************************************************/ -static INT -getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ - - INT i, paramSets = sizeof (psTuningTable) / sizeof (psTuningTable [0]); - int bitRateClosestLowerIndex=-1, bitRateClosestUpperIndex=-1; - UINT bitRateClosestUpper = 0, bitRateClosestLower=DISTANCE_CEIL_VALUE; - - for (i = 0 ; i < paramSets ; i++) { - if ((bitrate >= psTuningTable [i].bitrateFrom) && - (bitrate < psTuningTable [i].bitrateTo)) { - return i ; +static INT getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest) { + INT i, paramSets = sizeof(psTuningTable) / sizeof(psTuningTable[0]); + int bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1; + UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; + + for (i = 0; i < paramSets; i++) { + if ((bitrate >= psTuningTable[i].bitrateFrom) && + (bitrate < psTuningTable[i].bitrateTo)) { + return i; } else { - if ( psTuningTable [i].bitrateFrom > bitrate ) { - if (psTuningTable [i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = psTuningTable [i].bitrateFrom; + if (psTuningTable[i].bitrateFrom > bitrate) { + if (psTuningTable[i].bitrateFrom < bitRateClosestLower) { + bitRateClosestLower = psTuningTable[i].bitrateFrom; bitRateClosestLowerIndex = i; } } - if ( psTuningTable [i].bitrateTo <= bitrate ) { - if (psTuningTable [i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = psTuningTable [i].bitrateTo-1; + if (psTuningTable[i].bitrateTo <= bitrate) { + if (psTuningTable[i].bitrateTo > bitRateClosestUpper) { + bitRateClosestUpper = psTuningTable[i].bitrateTo - 1; bitRateClosestUpperIndex = i; } } } } - if (pBitRateClosest != NULL) - { - int distanceUpper=DISTANCE_CEIL_VALUE, distanceLower=DISTANCE_CEIL_VALUE; + if (bitRateClosestUpperIndex >= 0) { + return bitRateClosestUpperIndex; + } + + if (pBitRateClosest != NULL) { + int distanceUpper = DISTANCE_CEIL_VALUE, + distanceLower = DISTANCE_CEIL_VALUE; if (bitRateClosestLowerIndex >= 0) { - distanceLower = sbrTuningTable [bitRateClosestLowerIndex].bitrateFrom - bitrate; + distanceLower = + sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; } if (bitRateClosestUpperIndex >= 0) { - distanceUpper = bitrate - sbrTuningTable [bitRateClosestUpperIndex].bitrateTo; + distanceUpper = + bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; } - if ( distanceUpper < distanceLower ) - { + if (distanceUpper < distanceLower) { *pBitRateClosest = bitRateClosestUpper; } else { *pBitRateClosest = bitRateClosestLower; @@ -300,41 +361,29 @@ getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest){ \ingroup SbrEncCfg ****************************************************************************/ -static INT -FDKsbrEnc_GetDownsampledStopFreq ( - const INT sampleRateCore, - const INT startFreq, - INT stopFreq, - const INT downSampleFactor - ) -{ +static INT FDKsbrEnc_GetDownsampledStopFreq(const INT sampleRateCore, + const INT startFreq, INT stopFreq, + const INT downSampleFactor) { INT maxStopFreqRaw = sampleRateCore / 2; INT startBand, stopBand; HANDLE_ERROR_INFO err; - while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) { + while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > + maxStopFreqRaw) { stopFreq--; } - if (FDKsbrEnc_getSbrStopFreqRAW( stopFreq, sampleRateCore) > maxStopFreqRaw) + if (FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) return -1; - err = FDKsbrEnc_FindStartAndStopBand ( - sampleRateCore<<(downSampleFactor-1), - sampleRateCore, - 32<<(downSampleFactor-1), - startFreq, - stopFreq, - &startBand, - &stopBand - ); - if (err) - return -1; + err = FDKsbrEnc_FindStartAndStopBand( + sampleRateCore << (downSampleFactor - 1), sampleRateCore, + 32 << (downSampleFactor - 1), startFreq, stopFreq, &startBand, &stopBand); + if (err) return -1; return stopFreq; } - /***************************************************************************/ /*! @@ -345,22 +394,18 @@ FDKsbrEnc_GetDownsampledStopFreq ( \return a flag indicating success: yes (1) or no (0) ****************************************************************************/ -static UINT -FDKsbrEnc_IsSbrSettingAvail ( - UINT bitrate, /*! the total bitrate in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ - UINT numOutputChannels, /*! the number of channels for the core coder */ - UINT sampleRateInput, /*! the input sample rate [in Hz] */ - UINT sampleRateCore, /*! the core's sampling rate */ - AUDIO_OBJECT_TYPE core - ) -{ +static UINT FDKsbrEnc_IsSbrSettingAvail( + UINT bitrate, /*! the total bitrate in bits/sec */ + UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ + UINT numOutputChannels, /*! the number of channels for the core coder */ + UINT sampleRateInput, /*! the input sample rate [in Hz] */ + UINT sampleRateCore, /*! the core's sampling rate */ + AUDIO_OBJECT_TYPE core) { INT idx = INVALID_TABLE_IDX; - if (sampleRateInput < 16000) - return 0; + if (sampleRateInput < 16000) return 0; - if (bitrate==0) { + if (bitrate == 0) { /* map vbr quality to bitrate */ if (vbrMode < 30) bitrate = 24000; @@ -375,12 +420,12 @@ FDKsbrEnc_IsSbrSettingAvail ( bitrate *= numOutputChannels; } - idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, NULL); + idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, + NULL); return (idx == INVALID_TABLE_IDX ? 0 : 1); } - /***************************************************************************/ /*! @@ -390,46 +435,46 @@ FDKsbrEnc_IsSbrSettingAvail ( \return A flag indicating success: yes (1) or no (0) ****************************************************************************/ -static UINT -FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modified */ - UINT bitRate, /*! the total bitrate in bits/sec */ - UINT numChannels, /*! the core coder number of channels */ - UINT sampleRateCore, /*! the core coder sampling rate in Hz */ - UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */ - UINT transFac, /*! the short block to long block ratio */ - UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ - UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */ - UINT lcsMode, /*! the low complexity stereo mode */ - UINT bParametricStereo, /*!< use parametric stereo */ - AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ +static UINT FDKsbrEnc_AdjustSbrSettings( + const sbrConfigurationPtr config, /*! output, modified */ + UINT bitRate, /*! the total bitrate in bits/sec */ + UINT numChannels, /*! the core coder number of channels */ + UINT sampleRateCore, /*! the core coder sampling rate in Hz */ + UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */ + UINT transFac, /*! the short block to long block ratio */ + UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ + UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ + UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */ + UINT lcsMode, /*! the low complexity stereo mode */ + UINT bParametricStereo, /*!< use parametric stereo */ + AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ { INT idx = INVALID_TABLE_IDX; /* set the core codec settings */ - config->codecSettings.bitRate = bitRate; - config->codecSettings.nChannels = numChannels; - config->codecSettings.sampleFreq = sampleRateCore; - config->codecSettings.transFac = transFac; + config->codecSettings.bitRate = bitRate; + config->codecSettings.nChannels = numChannels; + config->codecSettings.sampleFreq = sampleRateCore; + config->codecSettings.transFac = transFac; config->codecSettings.standardBitrate = standardBitrate; if (bitRate < 28000) { config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL; config->threshold_AmpRes_FF_e = 7; - } - else if (bitRate >= 28000 && bitRate <= 48000) { + } else if (bitRate >= 28000 && bitRate <= 48000) { /* The float threshold is 75 - 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore tonality are scaled by this - 2/3 is because the original implementation divides the tonality values by 3, here it's divided by 2 - 128 compensates the necessary shiftfactor of 7 */ - config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(75.0f*0.524288f/(2.0f/3.0f)/128.0f); + 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore + tonality are scaled by this 2/3 is because the original implementation + divides the tonality values by 3, here it's divided by 2 128 compensates + the necessary shiftfactor of 7 */ + config->threshold_AmpRes_FF_m = + FL2FXCONST_DBL(75.0f * 0.524288f / (2.0f / 3.0f) / 128.0f); config->threshold_AmpRes_FF_e = 7; - } - else if (bitRate > 48000) { + } else if (bitRate > 48000) { config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0); config->threshold_AmpRes_FF_e = 0; } - if (bitRate==0) { + if (bitRate == 0) { /* map vbr quality to bitrate */ if (vbrMode < 30) bitRate = 24000; @@ -443,31 +488,29 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif bitRate = 48000; bitRate *= numChannels; /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ - if (numChannels==1) { - if (sampleRateSbr==44100 || sampleRateSbr==48000) { - if (vbrMode<40) bitRate = 32000; + if (numChannels == 1) { + if (sampleRateSbr == 44100 || sampleRateSbr == 48000) { + if (vbrMode < 40) bitRate = 32000; } } } - idx = getSbrTuningTableIndex(bitRate,numChannels,sampleRateCore, core, NULL); + idx = + getSbrTuningTableIndex(bitRate, numChannels, sampleRateCore, core, NULL); if (idx != INVALID_TABLE_IDX) { - config->startFreq = sbrTuningTable[idx].startFreq ; - config->stopFreq = sbrTuningTable[idx].stopFreq ; + config->startFreq = sbrTuningTable[idx].startFreq; + config->stopFreq = sbrTuningTable[idx].stopFreq; if (useSpeechConfig) { - config->startFreq = sbrTuningTable[idx].startFreqSpeech; - config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; + config->startFreq = sbrTuningTable[idx].startFreqSpeech; + config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; } /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */ if (1 == config->downSampleFactor) { INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq( - sampleRateCore, - config->startFreq, - config->stopFreq, - config->downSampleFactor - ); + sampleRateCore, config->startFreq, config->stopFreq, + config->downSampleFactor); if (dsStopFreq < 0) { return 0; } @@ -475,52 +518,68 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif config->stopFreq = dsStopFreq; } - config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands ; - if (core == AOT_ER_AAC_ELD) - config->init_amp_res_FF = SBR_AMP_RES_1_5; - config->noiseFloorOffset= sbrTuningTable[idx].noiseFloorOffset; + config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands; + if (core == AOT_ER_AAC_ELD) config->init_amp_res_FF = SBR_AMP_RES_1_5; + config->noiseFloorOffset = sbrTuningTable[idx].noiseFloorOffset; - config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel ; - config->stereoMode = sbrTuningTable[idx].stereoMode ; - config->freqScale = sbrTuningTable[idx].freqScale ; + config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel; + config->stereoMode = sbrTuningTable[idx].stereoMode; + config->freqScale = sbrTuningTable[idx].freqScale; if (numChannels == 1) { /* stereo case */ switch (core) { case AOT_AAC_LC: - if (bitRate <= (useSpeechConfig?24000U:20000U)) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ + if (bitRate <= (useSpeechConfig ? 24000U : 20000U)) { + config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency + resolution for + non-split frames */ + config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency + resolution for split + frames */ } break; case AOT_ER_AAC_ELD: if (bitRate < 36000) - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ + config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency + resolution for split + frames */ if (bitRate < 26000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */ + config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency + resolution for + non-split frames */ + config->fResTransIsLow = + 1; /* for transient frames, set low frequency resolution */ } break; default: break; } - } - else { + } else { /* stereo case */ switch (core) { case AOT_AAC_LC: if (bitRate <= 28000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ + config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency + resolution for + non-split frames */ + config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency + resolution for split + frames */ } break; case AOT_ER_AAC_ELD: if (bitRate < 72000) { - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency resolution for split frames */ + config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency + resolution for split + frames */ } if (bitRate < 52000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency resolution for non-split frames */ - config->fResTransIsLow = 1; /* for transient frames, set low frequency resolution */ + config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency + resolution for + non-split frames */ + config->fResTransIsLow = + 1; /* for transient frames, set low frequency resolution */ } break; default: @@ -535,24 +594,22 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif } } - /* adjust usage of parametric coding dependent on bitrate and speech config flag */ - if (useSpeechConfig) - config->parametricCoding = 0; + /* adjust usage of parametric coding dependent on bitrate and speech config + * flag */ + if (useSpeechConfig) config->parametricCoding = 0; if (core == AOT_ER_AAC_ELD) { - if (bitRate < 28000) - config->init_amp_res_FF = SBR_AMP_RES_3_0; + if (bitRate < 28000) config->init_amp_res_FF = SBR_AMP_RES_3_0; config->SendHeaderDataTime = -1; } if (numChannels == 1) { if (bitRate < 16000) { - config->parametricCoding = 0; + config->parametricCoding = 0; } - } - else { + } else { if (bitRate < 20000) { - config->parametricCoding = 0; + config->parametricCoding = 0; } } @@ -561,17 +618,16 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif /* PS settings */ config->bParametricStereo = bParametricStereo; - return 1 ; - } - else { - return 0 ; + return 1; + } else { + return 0; } } /***************************************************************************** functionname: FDKsbrEnc_InitializeSbrDefaults - description: initializes the SBR confifuration + description: initializes the SBR configuration returns: error status input: - core codec type, - factor of SBR to core frame length, @@ -579,76 +635,73 @@ FDKsbrEnc_AdjustSbrSettings (const sbrConfigurationPtr config, /*! output, modif output: initialized SBR configuration *****************************************************************************/ -static UINT -FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, - INT downSampleFactor, - UINT codecGranuleLen - ,const INT isLowDelay - ) -{ - if ( (downSampleFactor < 1 || downSampleFactor > 2) || - (codecGranuleLen*downSampleFactor > QMF_CHANNELS*QMF_MAX_TIME_SLOTS) ) - return(0); /* error */ - - config->SendHeaderDataTime = 1000; - config->useWaveCoding = 0; - config->crcSbr = 0; - config->dynBwSupported = 1; - if (isLowDelay) - config->tran_thr = 6000; - else - config->tran_thr = 13000; - - config->parametricCoding = 1; - - config->sbrFrameSize = codecGranuleLen * downSampleFactor; - config->downSampleFactor = downSampleFactor; - - /* sbr default parameters */ - config->sbr_data_extra = 0; - config->amp_res = SBR_AMP_RES_3_0 ; - config->tran_fc = 0 ; - config->tran_det_mode = 1 ; - config->spread = 1 ; - config->stat = 0 ; - config->e = 1 ; - config->deltaTAcrossFrames = 1 ; - config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f) ; - config->dF_edge_incr = FL2FXCONST_DBL(0.3f) ; - - config->sbr_invf_mode = INVF_SWITCHED; - config->sbr_xpos_mode = XPOS_LC; - config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT; - config->sbr_xpos_level = 0; - config->useSaPan = 0; - config->dynBwEnabled = 0; - - - /* the following parameters are overwritten by the FDKsbrEnc_AdjustSbrSettings() function since - they are included in the tuning table */ - config->stereoMode = SBR_SWITCH_LRC; - config->ana_max_level = 6; - config->noiseFloorOffset = 0; - config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ - config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ - config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */ - config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */ - config->fResTransIsLow = 0; /* for transient frames, set variable frequency resolution according to freqResTable */ - - /* header_extra_1 */ - config->freqScale = SBR_FREQ_SCALE_DEFAULT; - config->alterScale = SBR_ALTER_SCALE_DEFAULT; - config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT; - - /* header_extra_2 */ - config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT; - config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT; - config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; - config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT; +static UINT FDKsbrEnc_InitializeSbrDefaults(sbrConfigurationPtr config, + INT downSampleFactor, + UINT codecGranuleLen, + const INT isLowDelay) { + if ((downSampleFactor < 1 || downSampleFactor > 2) || + (codecGranuleLen * downSampleFactor > 64 * 32)) + return (0); /* error */ + + config->SendHeaderDataTime = 1000; + config->useWaveCoding = 0; + config->crcSbr = 0; + config->dynBwSupported = 1; + if (isLowDelay) + config->tran_thr = 6000; + else + config->tran_thr = 13000; + + config->parametricCoding = 1; + + config->sbrFrameSize = codecGranuleLen * downSampleFactor; + config->downSampleFactor = downSampleFactor; + + /* sbr default parameters */ + config->sbr_data_extra = 0; + config->amp_res = SBR_AMP_RES_3_0; + config->tran_fc = 0; + config->tran_det_mode = 1; + config->spread = 1; + config->stat = 0; + config->e = 1; + config->deltaTAcrossFrames = 1; + config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f); + config->dF_edge_incr = FL2FXCONST_DBL(0.3f); + + config->sbr_invf_mode = INVF_SWITCHED; + config->sbr_xpos_mode = XPOS_LC; + config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT; + config->sbr_xpos_level = 0; + config->useSaPan = 0; + config->dynBwEnabled = 0; + + /* the following parameters are overwritten by the + FDKsbrEnc_AdjustSbrSettings() function since they are included in the + tuning table */ + config->stereoMode = SBR_SWITCH_LRC; + config->ana_max_level = 6; + config->noiseFloorOffset = 0; + config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ + config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ + config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */ + config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */ + config->fResTransIsLow = 0; /* for transient frames, set variable frequency + resolution according to freqResTable */ - return 1; -} + /* header_extra_1 */ + config->freqScale = SBR_FREQ_SCALE_DEFAULT; + config->alterScale = SBR_ALTER_SCALE_DEFAULT; + config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT; + /* header_extra_2 */ + config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT; + config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT; + config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; + config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT; + + return 1; +} /***************************************************************************** @@ -659,19 +712,14 @@ FDKsbrEnc_InitializeSbrDefaults (sbrConfigurationPtr config, output: released handle *****************************************************************************/ -static void -deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut) -{ +static void deleteEnvChannel(HANDLE_ENV_CHANNEL hEnvCut) { if (hEnvCut) { - FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr); - FDKsbrEnc_deleteExtractSbrEnvelope (&hEnvCut->sbrExtractEnvelope); + FDKsbrEnc_deleteExtractSbrEnvelope(&hEnvCut->sbrExtractEnvelope); } - } - /***************************************************************************** functionname: sbrEncoder_ChannelClose @@ -681,12 +729,9 @@ deleteEnvChannel (HANDLE_ENV_CHANNEL hEnvCut) output: *****************************************************************************/ -static void -sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) -{ - if (hSbrChannel != NULL) - { - deleteEnvChannel (&hSbrChannel->hEnvChannel); +static void sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) { + if (hSbrChannel != NULL) { + deleteEnvChannel(&hSbrChannel->hEnvChannel); } } @@ -699,67 +744,60 @@ sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) output: *****************************************************************************/ -static void -sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) -{ +static void sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) { HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement; - if (hSbrElement!=NULL) { + if (hSbrElement != NULL) { if (hSbrElement->sbrConfigData.v_k_master) FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master); if (hSbrElement->sbrConfigData.freqBandTable[LO]) - FreeRam_Sbr_freqBandTableLO(&hSbrElement->sbrConfigData.freqBandTable[LO]); + FreeRam_Sbr_freqBandTableLO( + &hSbrElement->sbrConfigData.freqBandTable[LO]); if (hSbrElement->sbrConfigData.freqBandTable[HI]) - FreeRam_Sbr_freqBandTableHI(&hSbrElement->sbrConfigData.freqBandTable[HI]); + FreeRam_Sbr_freqBandTableHI( + &hSbrElement->sbrConfigData.freqBandTable[HI]); FreeRam_SbrElement(phSbrElement); } - return ; - + return; } - -void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder) -{ +void sbrEncoder_Close(HANDLE_SBR_ENCODER *phSbrEncoder) { HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder; - if (hSbrEncoder != NULL) - { + if (hSbrEncoder != NULL) { int el, ch; - for (el=0; el<(8); el++) - { - if (hSbrEncoder->sbrElement[el]!=NULL) { + for (el = 0; el < (8); el++) { + if (hSbrEncoder->sbrElement[el] != NULL) { sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]); } } /* Close sbr Channels */ - for (ch=0; ch<(8); ch++) - { + for (ch = 0; ch < (8); ch++) { if (hSbrEncoder->pSbrChannel[ch]) { sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]); FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]); } if (hSbrEncoder->QmfAnalysis[ch].FilterStates) - FreeRam_Sbr_QmfStatesAnalysis((FIXP_QAS**)&hSbrEncoder->QmfAnalysis[ch].FilterStates); - - + FreeRam_Sbr_QmfStatesAnalysis( + (FIXP_QAS **)&hSbrEncoder->QmfAnalysis[ch].FilterStates); } if (hSbrEncoder->hParametricStereo) PSEnc_Destroy(&hSbrEncoder->hParametricStereo); if (hSbrEncoder->qmfSynthesisPS.FilterStates) - FreeRam_PsQmfStatesSynthesis((FIXP_DBL**)&hSbrEncoder->qmfSynthesisPS.FilterStates); + FreeRam_PsQmfStatesSynthesis( + (FIXP_DBL **)&hSbrEncoder->qmfSynthesisPS.FilterStates); /* Release Overlay */ - FreeRam_SbrDynamic_RAM((FIXP_DBL**)&hSbrEncoder->pSBRdynamic_RAM); - + if (hSbrEncoder->pSBRdynamic_RAM) + FreeRam_SbrDynamic_RAM((FIXP_DBL **)&hSbrEncoder->pSBRdynamic_RAM); FreeRam_SbrEncoder(phSbrEncoder); } - } /***************************************************************************** @@ -771,67 +809,44 @@ void sbrEncoder_Close (HANDLE_SBR_ENCODER *phSbrEncoder) output: error info *****************************************************************************/ -static INT updateFreqBandTable( - HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - const INT downSampleFactor - ) -{ +static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData, + HANDLE_SBR_HEADER_DATA sbrHeaderData, + const INT downSampleFactor) { INT k0, k2; - if( FDKsbrEnc_FindStartAndStopBand ( - sbrConfigData->sampleFreq, - sbrConfigData->sampleFreq >> (downSampleFactor-1), - sbrConfigData->noQmfBands, - sbrHeaderData->sbr_start_frequency, - sbrHeaderData->sbr_stop_frequency, - &k0, - &k2 - ) - ) - return(1); - - - if( FDKsbrEnc_UpdateFreqScale( - sbrConfigData->v_k_master, - &sbrConfigData->num_Master, - k0, - k2, - sbrHeaderData->freqScale, - sbrHeaderData->alterScale - ) - ) - return(1); - - - sbrHeaderData->sbr_xover_band=0; - - - if( FDKsbrEnc_UpdateHiRes( - sbrConfigData->freqBandTable[HI], - &sbrConfigData->nSfb[HI], - sbrConfigData->v_k_master, - sbrConfigData->num_Master, - &sbrHeaderData->sbr_xover_band - ) - ) - return(1); + if (FDKsbrEnc_FindStartAndStopBand( + sbrConfigData->sampleFreq, + sbrConfigData->sampleFreq >> (downSampleFactor - 1), + sbrConfigData->noQmfBands, sbrHeaderData->sbr_start_frequency, + sbrHeaderData->sbr_stop_frequency, &k0, &k2)) + return (1); + if (FDKsbrEnc_UpdateFreqScale( + sbrConfigData->v_k_master, &sbrConfigData->num_Master, k0, k2, + sbrHeaderData->freqScale, sbrHeaderData->alterScale)) + return (1); - FDKsbrEnc_UpdateLoRes( - sbrConfigData->freqBandTable[LO], - &sbrConfigData->nSfb[LO], - sbrConfigData->freqBandTable[HI], - sbrConfigData->nSfb[HI] - ); + sbrHeaderData->sbr_xover_band = 0; + if (FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI], + &sbrConfigData->nSfb[HI], sbrConfigData->v_k_master, + sbrConfigData->num_Master, + &sbrHeaderData->sbr_xover_band)) + return (1); - sbrConfigData->xOverFreq = (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / sbrConfigData->noQmfBands+1)>>1; + FDKsbrEnc_UpdateLoRes( + sbrConfigData->freqBandTable[LO], &sbrConfigData->nSfb[LO], + sbrConfigData->freqBandTable[HI], sbrConfigData->nSfb[HI]); + + sbrConfigData->xOverFreq = + (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / + sbrConfigData->noQmfBands + + 1) >> + 1; return (0); } - /***************************************************************************** functionname: resetEnvChannel @@ -841,27 +856,26 @@ static INT updateFreqBandTable( output: hEnv *****************************************************************************/ -static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv) -{ - /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function FDKsbrEnc_extractSbrEnvelope !!!*/ - hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = sbrHeaderData->sbr_noise_bands; - - - if(FDKsbrEnc_ResetTonCorrParamExtr(&hEnv->TonCorr, - sbrConfigData->xposCtrlSwitch, - sbrConfigData->freqBandTable[HI][0], - sbrConfigData->v_k_master, - sbrConfigData->num_Master, - sbrConfigData->sampleFreq, - sbrConfigData->freqBandTable, - sbrConfigData->nSfb, - sbrConfigData->noQmfBands)) - return(1); - - hEnv->sbrCodeNoiseFloor.nSfb[LO] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - hEnv->sbrCodeNoiseFloor.nSfb[HI] = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; +static INT resetEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, + HANDLE_SBR_HEADER_DATA sbrHeaderData, + HANDLE_ENV_CHANNEL hEnv) { + /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function + * FDKsbrEnc_extractSbrEnvelope !!!*/ + hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = + sbrHeaderData->sbr_noise_bands; + + if (FDKsbrEnc_ResetTonCorrParamExtr( + &hEnv->TonCorr, sbrConfigData->xposCtrlSwitch, + sbrConfigData->freqBandTable[HI][0], sbrConfigData->v_k_master, + sbrConfigData->num_Master, sbrConfigData->sampleFreq, + sbrConfigData->freqBandTable, sbrConfigData->nSfb, + sbrConfigData->noQmfBands)) + return (1); + + hEnv->sbrCodeNoiseFloor.nSfb[LO] = + hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; + hEnv->sbrCodeNoiseFloor.nSfb[HI] = + hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO]; hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI]; @@ -874,16 +888,17 @@ static INT resetEnvChannel (HANDLE_SBR_CONFIG_DATA sbrConfigData, return (0); } -/* ****************************** FDKsbrEnc_SbrGetXOverFreq ******************************/ +/* ****************************** FDKsbrEnc_SbrGetXOverFreq + * ******************************/ /** * @fn * @brief calculates the closest possible crossover frequency * @return the crossover frequency SBR accepts * */ -static INT -FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */ - INT xoverFreq) /*!< from core coder suggested crossover frequency */ +static INT FDKsbrEnc_SbrGetXOverFreq( + HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */ + INT xoverFreq) /*!< from core coder suggested crossover frequency */ { INT band; INT lastDiff, newDiff; @@ -892,13 +907,15 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master; /* Check if there is a matching cutoff frequency in the master table */ - cutoffSb = (4*xoverFreq * hEnv->sbrConfigData.noQmfBands / hEnv->sbrConfigData.sampleFreq + 1)>>1; + cutoffSb = (4 * xoverFreq * hEnv->sbrConfigData.noQmfBands / + hEnv->sbrConfigData.sampleFreq + + 1) >> + 1; lastDiff = cutoffSb; for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) { - newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb); - if(newDiff >= lastDiff) { + if (newDiff >= lastDiff) { band--; break; } @@ -906,7 +923,10 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en lastDiff = newDiff; } - return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq/hEnv->sbrConfigData.noQmfBands+1)>>1); + return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq / + hEnv->sbrConfigData.noQmfBands + + 1) >> + 1); } /***************************************************************************** @@ -918,32 +938,27 @@ FDKsbrEnc_SbrGetXOverFreq(HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR en output: *****************************************************************************/ -INT -FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, - int iElement, - INT_PCM *samples, /*!< time samples, always interleaved */ - UINT timeInStride, /*!< time buffer channel interleaving stride */ - UINT *sbrDataBits, /*!< Size of SBR payload */ - UCHAR *sbrData, /*!< SBR payload */ - int clearOutput /*!< Do not consider any input signal */ - ) -{ +INT FDKsbrEnc_EnvEncodeFrame( + HANDLE_SBR_ENCODER hEnvEncoder, int iElement, + INT_PCM *samples, /*!< time samples, always deinterleaved */ + UINT samplesBufSize, /*!< time buffer channel stride */ + UINT *sbrDataBits, /*!< Size of SBR payload */ + UCHAR *sbrData, /*!< SBR payload */ + int clearOutput /*!< Do not consider any input signal */ +) { HANDLE_SBR_ELEMENT hSbrElement = NULL; - FDK_CRCINFO crcInfo; - INT crcReg; - INT ch; - INT band; - INT cutoffSb; - INT newXOver; - - if (hEnvEncoder == NULL) - return -1; + FDK_CRCINFO crcInfo; + INT crcReg; + INT ch; + INT band; + INT cutoffSb; + INT newXOver; - hSbrElement = hEnvEncoder->sbrElement[iElement]; + if (hEnvEncoder == NULL) return -1; - if (hSbrElement == NULL) - return -1; + hSbrElement = hEnvEncoder->sbrElement[iElement]; + if (hSbrElement == NULL) return -1; /* header bitstream handling */ HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData; @@ -951,33 +966,33 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, INT psHeaderActive = 0; sbrBitstreamData->HeaderActive = 0; - /* Anticipate PS header because of internal PS bitstream delay in order to be in sync with SBR header. */ - if ( sbrBitstreamData->CountSendHeaderData==(sbrBitstreamData->NrSendHeaderData-1) ) - { - psHeaderActive = 1; + /* Anticipate PS header because of internal PS bitstream delay in order to be + * in sync with SBR header. */ + if (sbrBitstreamData->CountSendHeaderData == + (sbrBitstreamData->NrSendHeaderData - 1)) { + psHeaderActive = 1; } /* Signal SBR header to be written into bitstream */ - if ( sbrBitstreamData->CountSendHeaderData==0 ) - { - sbrBitstreamData->HeaderActive = 1; + if (sbrBitstreamData->CountSendHeaderData == 0) { + sbrBitstreamData->HeaderActive = 1; } /* Increment header interval counter */ if (sbrBitstreamData->NrSendHeaderData == 0) { sbrBitstreamData->CountSendHeaderData = 1; - } - else { + } else { if (sbrBitstreamData->CountSendHeaderData >= 0) { sbrBitstreamData->CountSendHeaderData++; - sbrBitstreamData->CountSendHeaderData %= sbrBitstreamData->NrSendHeaderData; + sbrBitstreamData->CountSendHeaderData %= + sbrBitstreamData->NrSendHeaderData; } } - if (hSbrElement->CmonData.dynBwEnabled ) { + if (hSbrElement->CmonData.dynBwEnabled) { INT i; - for ( i = 4; i > 0; i-- ) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i-1]; + for (i = 4; i > 0; i--) + hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i - 1]; hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc; if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2]) @@ -986,41 +1001,38 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, newXOver = hSbrElement->dynXOverFreqDelay[1]; /* has the crossover frequency changed? */ - if ( hSbrElement->sbrConfigData.dynXOverFreq != newXOver ) { - + if (hSbrElement->sbrConfigData.dynXOverFreq != newXOver) { /* get corresponding master band */ - cutoffSb = ((4* newXOver * hSbrElement->sbrConfigData.noQmfBands - / hSbrElement->sbrConfigData.sampleFreq)+1)>>1; + cutoffSb = ((4 * newXOver * hSbrElement->sbrConfigData.noQmfBands / + hSbrElement->sbrConfigData.sampleFreq) + + 1) >> + 1; - for ( band = 0; band < hSbrElement->sbrConfigData.num_Master; band++ ) { - if ( cutoffSb == hSbrElement->sbrConfigData.v_k_master[band] ) - break; + for (band = 0; band < hSbrElement->sbrConfigData.num_Master; band++) { + if (cutoffSb == hSbrElement->sbrConfigData.v_k_master[band]) break; } - FDK_ASSERT( band < hSbrElement->sbrConfigData.num_Master ); + FDK_ASSERT(band < hSbrElement->sbrConfigData.num_Master); hSbrElement->sbrConfigData.dynXOverFreq = newXOver; hSbrElement->sbrHeaderData.sbr_xover_band = band; - hSbrElement->sbrBitstreamData.HeaderActive=1; + hSbrElement->sbrBitstreamData.HeaderActive = 1; psHeaderActive = 1; /* ps header is one frame delayed */ /* update vk_master table */ - if(updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - hEnvEncoder->downSampleFactor - )) - return(1); - + if (updateFreqBandTable(&hSbrElement->sbrConfigData, + &hSbrElement->sbrHeaderData, + hEnvEncoder->downSampleFactor)) + return (1); /* reset SBR channels */ INT nEnvCh = hSbrElement->sbrConfigData.nChannels; - for ( ch = 0; ch < nEnvCh; ch++ ) { - if(resetEnvChannel (&hSbrElement->sbrConfigData, + for (ch = 0; ch < nEnvCh; ch++) { + if (resetEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, &hSbrElement->sbrChannel[ch]->hEnvChannel)) - return(1); - + return (1); } } } @@ -1028,11 +1040,11 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, /* allocate space for dummy header and crc */ - crcReg = FDKsbrEnc_InitSbrBitstream(&hSbrElement->CmonData, - hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay], - MAX_PAYLOAD_SIZE*sizeof(UCHAR), - &crcInfo, - hSbrElement->sbrConfigData.sbrSyntaxFlags); + crcReg = FDKsbrEnc_InitSbrBitstream( + &hSbrElement->CmonData, + hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay], + MAX_PAYLOAD_SIZE * sizeof(UCHAR), &crcInfo, + hSbrElement->sbrConfigData.sbrSyntaxFlags); /* Temporal Envelope Data */ SBR_FRAME_TEMP_DATA _fData; @@ -1047,61 +1059,47 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA)); FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA)); - for(i=0; i<MAX_NUM_NOISE_VALUES; i++) - fData->res[i] = FREQ_RES_HIGH; + for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) fData->res[i] = FREQ_RES_HIGH; } - - if (!clearOutput) - { + if (!clearOutput) { /* * Transform audio data into QMF domain */ - for(ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) - { + for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel; HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope; - if(hSbrElement->elInfo.fParametricStereo == 0) - { + if (hSbrElement->elInfo.fParametricStereo == 0) { QMF_SCALE_FACTOR tmpScale; FIXP_DBL **pQmfReal, **pQmfImag; - C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) - + C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, 64 * 2) /* Obtain pointers to QMF buffers. */ pQmfReal = sbrExtrEnv->rBuffer; pQmfImag = sbrExtrEnv->iBuffer; - qmfAnalysisFiltering( hSbrElement->hQmfAnalysis[ch], - pQmfReal, - pQmfImag, - &tmpScale, - samples + hSbrElement->elInfo.ChannelIndex[ch], - timeInStride, - qmfWorkBuffer ); + qmfAnalysisFiltering( + hSbrElement->hQmfAnalysis[ch], pQmfReal, pQmfImag, &tmpScale, + samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, 0, + 1, qmfWorkBuffer); h_envChan->qmfScale = tmpScale.lb_scale + 7; - - C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, QMF_CHANNELS*2) + C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, 64 * 2) } /* fParametricStereo == 0 */ - /* Parametric Stereo processing */ - if (hSbrElement->elInfo.fParametricStereo) - { + if (hSbrElement->elInfo.fParametricStereo) { INT error = noError; - /* Limit Parametric Stereo to one instance */ FDK_ASSERT(ch == 0); - - if(error == noError){ + if (error == noError) { /* parametric stereo processing: - input: o left and right time domain samples @@ -1111,28 +1109,22 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, o ps parameter extraction o downmix + hybrid synthesis - output: - o downmixed qmf data is written to sbrExtrEnv->rBuffer and sbrExtrEnv->iBuffer + o downmixed qmf data is written to sbrExtrEnv->rBuffer and + sbrExtrEnv->iBuffer */ SCHAR qmfScale; - INT_PCM* pSamples[2] = {samples + hSbrElement->elInfo.ChannelIndex[0],samples + hSbrElement->elInfo.ChannelIndex[1]}; - error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( hEnvEncoder->hParametricStereo, - pSamples, - timeInStride, - hSbrElement->hQmfAnalysis, - sbrExtrEnv->rBuffer, - sbrExtrEnv->iBuffer, - samples + hSbrElement->elInfo.ChannelIndex[ch], - &hEnvEncoder->qmfSynthesisPS, - &qmfScale, - psHeaderActive ); - if (noError != error) - { - error = handBack(error); - } + INT_PCM *pSamples[2] = { + samples + hSbrElement->elInfo.ChannelIndex[0] * samplesBufSize, + samples + hSbrElement->elInfo.ChannelIndex[1] * samplesBufSize}; + error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( + hEnvEncoder->hParametricStereo, pSamples, samplesBufSize, + hSbrElement->hQmfAnalysis, sbrExtrEnv->rBuffer, + sbrExtrEnv->iBuffer, + samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, + &hEnvEncoder->qmfSynthesisPS, &qmfScale, psHeaderActive); h_envChan->qmfScale = (int)qmfScale; } - } /* if (hEnvEncoder->hParametricStereo) */ /* @@ -1140,80 +1132,146 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, Extract Envelope relevant things from QMF data */ - FDKsbrEnc_extractSbrEnvelope1( - &hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrBitstreamData, - h_envChan, - &hSbrElement->CmonData, - &eData[ch], - fData - ); + FDKsbrEnc_extractSbrEnvelope1(&hSbrElement->sbrConfigData, + &hSbrElement->sbrHeaderData, + &hSbrElement->sbrBitstreamData, h_envChan, + &hSbrElement->CmonData, &eData[ch], fData); } /* hEnvEncoder->sbrConfigData.nChannels */ - } + } /* - Process Envelope relevant things and calculate envelope data and write payload + Process Envelope relevant things and calculate envelope data and write + payload */ FDKsbrEnc_extractSbrEnvelope2( - &hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo : NULL, - &hSbrElement->sbrBitstreamData, - &hSbrElement->sbrChannel[0]->hEnvChannel, - &hSbrElement->sbrChannel[1]->hEnvChannel, - &hSbrElement->CmonData, - eData, - fData, - clearOutput - ); + &hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, + (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo + : NULL, + &hSbrElement->sbrBitstreamData, &hSbrElement->sbrChannel[0]->hEnvChannel, + (hSbrElement->sbrConfigData.stereoMode != SBR_MONO) + ? &hSbrElement->sbrChannel[1]->hEnvChannel + : NULL, + &hSbrElement->CmonData, eData, fData, clearOutput); + + hSbrElement->sbrBitstreamData.rightBorderFIX = 0; /* format payload, calculate crc */ - FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, hSbrElement->sbrConfigData.sbrSyntaxFlags); + FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, + hSbrElement->sbrConfigData.sbrSyntaxFlags); /* save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE */ - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf); + hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = + FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf); - if(hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > (MAX_PAYLOAD_SIZE<<3)) - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay]=0; + if (hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > + (MAX_PAYLOAD_SIZE << 3)) + hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = 0; /* While filling the Delay lines, sbrData is NULL */ if (sbrData) { *sbrDataBits = hSbrElement->payloadDelayLineSize[0]; - FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], (hSbrElement->payloadDelayLineSize[0]+7)>>3); - + FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], + (hSbrElement->payloadDelayLineSize[0] + 7) >> 3); + } + /* delay header active flag */ + if (hSbrElement->sbrBitstreamData.HeaderActive == 1) { + hSbrElement->sbrBitstreamData.HeaderActiveDelay = + 1 + hEnvEncoder->nBitstrDelay; + } else { + if (hSbrElement->sbrBitstreamData.HeaderActiveDelay > 0) { + hSbrElement->sbrBitstreamData.HeaderActiveDelay--; + } } + return (0); +} -/*******************************/ +/***************************************************************************** - if (hEnvEncoder->fTimeDomainDownsampling) - { - int ch; - int nChannels = hSbrElement->sbrConfigData.nChannels; + functionname: FDKsbrEnc_Downsample + description: performs downsampling and delay compensation of the core path + returns: + input: + output: - for (ch=0; ch < nChannels; ch++) - { - INT nOutSamples; - - FDKaacEnc_Downsample(&hSbrElement->sbrChannel[ch]->downSampler, - samples + hSbrElement->elInfo.ChannelIndex[ch] + hEnvEncoder->bufferOffset, - hSbrElement->sbrConfigData.frameSize, - timeInStride, - samples + hSbrElement->elInfo.ChannelIndex[ch], - &nOutSamples, - hEnvEncoder->nChannels); +*****************************************************************************/ +INT FDKsbrEnc_Downsample( + HANDLE_SBR_ENCODER hSbrEncoder, + INT_PCM *samples, /*!< time samples, always deinterleaved */ + UINT samplesBufSize, /*!< time buffer size per channel */ + UINT numChannels, /*!< number of channels */ + UINT *sbrDataBits, /*!< Size of SBR payload */ + UCHAR *sbrData, /*!< SBR payload */ + int clearOutput /*!< Do not consider any input signal */ +) { + HANDLE_SBR_ELEMENT hSbrElement = NULL; + INT nOutSamples; + int el; + if (hSbrEncoder->downSampleFactor > 1) { + /* Do downsampling */ + + /* Loop over elements (LFE is handled later) */ + for (el = 0; el < hSbrEncoder->noElements; el++) { + hSbrElement = hSbrEncoder->sbrElement[el]; + if (hSbrEncoder->sbrElement[el] != NULL) { + if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { + int ch; + int nChannels = hSbrElement->sbrConfigData.nChannels; + + for (ch = 0; ch < nChannels; ch++) { + FDKaacEnc_Downsample( + &hSbrElement->sbrChannel[ch]->downSampler, + samples + + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize + + hSbrEncoder->bufferOffset / numChannels, + hSbrElement->sbrConfigData.frameSize, + samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, + &nOutSamples); + } + } + } } - } /* downsample */ + /* Handle LFE (if existing) */ + if (hSbrEncoder->lfeChIdx != -1) { /* lfe downsampler */ + FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, + samples + hSbrEncoder->lfeChIdx * samplesBufSize + + hSbrEncoder->bufferOffset / numChannels, + hSbrEncoder->frameSize, + samples + hSbrEncoder->lfeChIdx * samplesBufSize, + &nOutSamples); + } + } else { + /* No downsampling. Still, some buffer shifting for correct delay */ + int samples2Copy = hSbrEncoder->frameSize; + if (hSbrEncoder->bufferOffset / (int)numChannels < samples2Copy) { + for (int c = 0; c < (int)numChannels; c++) { + /* Do memmove while taking care of overlapping memory areas. (memcpy + does not necessarily take care) Distinguish between oeverlapping and + non overlapping version due to reasons of complexity. */ + FDKmemmove(samples + c * samplesBufSize, + samples + c * samplesBufSize + + hSbrEncoder->bufferOffset / numChannels, + samples2Copy * sizeof(INT_PCM)); + } + } else { + for (int c = 0; c < (int)numChannels; c++) { + /* Simple memcpy since the memory areas are not overlapping */ + FDKmemcpy(samples + c * samplesBufSize, + samples + c * samplesBufSize + + hSbrEncoder->bufferOffset / numChannels, + samples2Copy * sizeof(INT_PCM)); + } + } + } - return (0); + return 0; } /***************************************************************************** @@ -1226,27 +1284,17 @@ FDKsbrEnc_EnvEncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, *****************************************************************************/ -static INT -createEnvChannel (HANDLE_ENV_CHANNEL hEnv, - INT channel - ,UCHAR* dynamic_RAM - ) -{ - FDKmemclear(hEnv,sizeof (struct ENV_CHANNEL)); +static INT createEnvChannel(HANDLE_ENV_CHANNEL hEnv, INT channel, + UCHAR *dynamic_RAM) { + FDKmemclear(hEnv, sizeof(struct ENV_CHANNEL)); - if ( FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, - channel) ) - { - return(1); + if (FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, channel)) { + return (1); } - if ( FDKsbrEnc_CreateExtractSbrEnvelope (&hEnv->sbrExtractEnvelope, - channel - ,/*chan*/0 - ,dynamic_RAM - ) ) - { - return(1); + if (FDKsbrEnc_CreateExtractSbrEnvelope(&hEnv->sbrExtractEnvelope, channel, + /*chan*/ 0, dynamic_RAM)) { + return (1); } return 0; @@ -1261,21 +1309,16 @@ createEnvChannel (HANDLE_ENV_CHANNEL hEnv, output: *****************************************************************************/ -static INT -initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv, - sbrConfigurationPtr params, - ULONG statesInitFlag - ,INT chanInEl - ,UCHAR* dynamic_RAM - ) -{ - int frameShift, tran_off=0; +static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, + HANDLE_SBR_HEADER_DATA sbrHeaderData, + HANDLE_ENV_CHANNEL hEnv, sbrConfigurationPtr params, + ULONG statesInitFlag, INT chanInEl, + UCHAR *dynamic_RAM) { + int frameShift, tran_off = 0; INT e; INT tran_fc; INT timeSlots, timeStep, startIndex; - INT noiseBands[2] = { 3, 3 }; + INT noiseBands[2] = {3, 3}; e = 1 << params->e; @@ -1283,11 +1326,12 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0]; hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1]; - hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow; + hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow; hEnv->fLevelProtect = 0; - hEnv->encEnvData.ldGrid = (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; + hEnv->encEnvData.ldGrid = + (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode; @@ -1298,19 +1342,16 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, */ sbrConfigData->switchTransposers = TRUE; hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT; - } - else { + } else { sbrConfigData->switchTransposers = FALSE; } hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl; - /* extended data */ - if(params->parametricCoding) { + if (params->parametricCoding) { hEnv->encEnvData.extended_data = 1; - } - else { + } else { hEnv->encEnvData.extended_data = 0; } @@ -1319,40 +1360,37 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands; switch (params->sbrFrameSize) { - case 2304: - timeSlots = 18; - break; - case 2048: - case 1024: - case 512: - timeSlots = 16; - break; - case 1920: - case 960: - case 480: - timeSlots = 15; - break; - case 1152: - timeSlots = 9; - break; - default: - return (1); /* Illegal frame size */ + case 2304: + timeSlots = 18; + break; + case 2048: + case 1024: + case 512: + timeSlots = 16; + break; + case 1920: + case 960: + case 480: + timeSlots = 15; + break; + case 1152: + timeSlots = 9; + break; + default: + return (1); /* Illegal frame size */ } timeStep = sbrConfigData->noQmfSlots / timeSlots; - if ( FDKsbrEnc_InitTonCorrParamExtr(params->sbrFrameSize, - &hEnv->TonCorr, - sbrConfigData, - timeSlots, - params->sbr_xpos_ctrl, - params->ana_max_level, - sbrHeaderData->sbr_noise_bands, - params->noiseFloorOffset, - params->useSpeechConfig) ) - return(1); + if (FDKsbrEnc_InitTonCorrParamExtr( + params->sbrFrameSize, &hEnv->TonCorr, sbrConfigData, timeSlots, + params->sbr_xpos_ctrl, params->ana_max_level, + sbrHeaderData->sbr_noise_bands, params->noiseFloorOffset, + params->useSpeechConfig)) + return (1); - hEnv->encEnvData.noOfnoisebands = hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; + hEnv->encEnvData.noOfnoisebands = + hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; noiseBands[0] = hEnv->encEnvData.noOfnoisebands; noiseBands[1] = hEnv->encEnvData.noOfnoisebands; @@ -1362,106 +1400,90 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) { hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL; hEnv->TonCorr.switchInverseFilt = TRUE; - } - else { + } else { hEnv->TonCorr.switchInverseFilt = FALSE; } - - tran_fc = params->tran_fc; + tran_fc = params->tran_fc; if (tran_fc == 0) { - tran_fc = fixMin (5000, FDKsbrEnc_getSbrStartFreqRAW (sbrHeaderData->sbr_start_frequency,params->codecSettings.sampleFreq)); + tran_fc = fixMin( + 5000, FDKsbrEnc_getSbrStartFreqRAW(sbrHeaderData->sbr_start_frequency, + params->codecSettings.sampleFreq)); } - tran_fc = (tran_fc*4*sbrConfigData->noQmfBands/sbrConfigData->sampleFreq + 1)>>1; + tran_fc = + (tran_fc * 4 * sbrConfigData->noQmfBands / sbrConfigData->sampleFreq + + 1) >> + 1; if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { frameShift = LD_PRETRAN_OFF; - tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD*timeStep; - } else - { + tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD * timeStep; + } else { frameShift = 0; switch (timeSlots) { /* The factor of 2 is by definition. */ - case NUMBER_TIME_SLOTS_2048: tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; break; - case NUMBER_TIME_SLOTS_1920: tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; break; - default: return 1; + case NUMBER_TIME_SLOTS_2048: + tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; + break; + case NUMBER_TIME_SLOTS_1920: + tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; + break; + default: + return 1; } } - if ( FDKsbrEnc_InitExtractSbrEnvelope (&hEnv->sbrExtractEnvelope, - sbrConfigData->noQmfSlots, - sbrConfigData->noQmfBands, startIndex, - timeSlots, timeStep, tran_off, - statesInitFlag - ,chanInEl - ,dynamic_RAM - ,sbrConfigData->sbrSyntaxFlags - ) ) - return(1); - - if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeEnvelope, - sbrConfigData->nSfb, - params->deltaTAcrossFrames, - params->dF_edge_1stEnv, - params->dF_edge_incr)) - return(1); - - if(FDKsbrEnc_InitSbrCodeEnvelope (&hEnv->sbrCodeNoiseFloor, - noiseBands, - params->deltaTAcrossFrames, - 0,0)) - return(1); + if (FDKsbrEnc_InitExtractSbrEnvelope( + &hEnv->sbrExtractEnvelope, sbrConfigData->noQmfSlots, + sbrConfigData->noQmfBands, startIndex, timeSlots, timeStep, tran_off, + statesInitFlag, chanInEl, dynamic_RAM, sbrConfigData->sbrSyntaxFlags)) + return (1); + + if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeEnvelope, sbrConfigData->nSfb, + params->deltaTAcrossFrames, + params->dF_edge_1stEnv, + params->dF_edge_incr)) + return (1); + + if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeNoiseFloor, noiseBands, + params->deltaTAcrossFrames, 0, 0)) + return (1); sbrConfigData->initAmpResFF = params->init_amp_res_FF; - if(FDKsbrEnc_InitSbrHuffmanTables (&hEnv->encEnvData, - &hEnv->sbrCodeEnvelope, - &hEnv->sbrCodeNoiseFloor, - sbrHeaderData->sbr_amp_res)) - return(1); - - FDKsbrEnc_initFrameInfoGenerator (&hEnv->SbrEnvFrame, - params->spread, - e, - params->stat, - timeSlots, - hEnv->encEnvData.freq_res_fixfix, - hEnv->encEnvData.fResTransIsLow, - hEnv->encEnvData.ldGrid - ); - - if(sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope, + &hEnv->sbrCodeNoiseFloor, + sbrHeaderData->sbr_amp_res)) + return (1); + + FDKsbrEnc_initFrameInfoGenerator( + &hEnv->SbrEnvFrame, params->spread, e, params->stat, timeSlots, + hEnv->encEnvData.freq_res_fixfix, hEnv->encEnvData.fResTransIsLow, + hEnv->encEnvData.ldGrid); + + if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + { - INT bandwidth_qmf_slot = (sbrConfigData->sampleFreq>>1) / (sbrConfigData->noQmfBands); - if(FDKsbrEnc_InitSbrFastTransientDetector( - &hEnv->sbrFastTransientDetector, - sbrConfigData->noQmfSlots, - bandwidth_qmf_slot, - sbrConfigData->noQmfBands, - sbrConfigData->freqBandTable[0][0] - )) - return(1); + INT bandwidth_qmf_slot = + (sbrConfigData->sampleFreq >> 1) / (sbrConfigData->noQmfBands); + if (FDKsbrEnc_InitSbrFastTransientDetector( + &hEnv->sbrFastTransientDetector, sbrConfigData->noQmfSlots, + bandwidth_qmf_slot, sbrConfigData->noQmfBands, + sbrConfigData->freqBandTable[0][0])) + return (1); } /* The transient detector has to be initialized also if the fast transient detector was active, because the values from the transient detector structure are used. */ - if(FDKsbrEnc_InitSbrTransientDetector (&hEnv->sbrTransientDetector, - sbrConfigData->sbrSyntaxFlags, - sbrConfigData->frameSize, - sbrConfigData->sampleFreq, - params, - tran_fc, - sbrConfigData->noQmfSlots, - sbrConfigData->noQmfBands, - hEnv->sbrExtractEnvelope.YBufferWriteOffset, - hEnv->sbrExtractEnvelope.YBufferSzShift, - frameShift, - tran_off - )) - return(1); - + if (FDKsbrEnc_InitSbrTransientDetector( + &hEnv->sbrTransientDetector, sbrConfigData->sbrSyntaxFlags, + sbrConfigData->frameSize, sbrConfigData->sampleFreq, params, tran_fc, + sbrConfigData->noQmfSlots, sbrConfigData->noQmfBands, + hEnv->sbrExtractEnvelope.YBufferWriteOffset, + hEnv->sbrExtractEnvelope.YBufferSzShift, frameShift, tran_off)) + return (1); sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl; @@ -1471,83 +1493,80 @@ initEnvChannel ( HANDLE_SBR_CONFIG_DATA sbrConfigData, return (0); } -INT sbrEncoder_Open( - HANDLE_SBR_ENCODER *phSbrEncoder, - INT nElements, - INT nChannels, - INT supportPS - ) -{ +INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements, + INT nChannels, INT supportPS) { INT i; INT errorStatus = 1; HANDLE_SBR_ENCODER hSbrEncoder = NULL; - if (phSbrEncoder==NULL - ) - { + if (phSbrEncoder == NULL) { goto bail; } hSbrEncoder = GetRam_SbrEncoder(); - if (hSbrEncoder==NULL) { + if (hSbrEncoder == NULL) { goto bail; } FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER)); - hSbrEncoder->pSBRdynamic_RAM = (UCHAR*)GetRam_SbrDynamic_RAM(); - hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; + if (NULL == + (hSbrEncoder->pSBRdynamic_RAM = (UCHAR *)GetRam_SbrDynamic_RAM())) { + goto bail; + } + hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; - for (i=0; i<nElements; i++) { + /* Create SBR elements */ + for (i = 0; i < nElements; i++) { hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i); - if (hSbrEncoder->sbrElement[i]==NULL) { - goto bail; + if (hSbrEncoder->sbrElement[i] == NULL) { + goto bail; } FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT)); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = GetRam_Sbr_freqBandTableLO(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = GetRam_Sbr_freqBandTableHI(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = GetRam_Sbr_v_k_master(i); - if ( (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO]==NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI]==NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master==NULL) ) - { - goto bail; + hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = + GetRam_Sbr_freqBandTableLO(i); + hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = + GetRam_Sbr_freqBandTableHI(i); + hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = + GetRam_Sbr_v_k_master(i); + if ((hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] == NULL) || + (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] == NULL) || + (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master == NULL)) { + goto bail; } } - for (i=0; i<nChannels; i++) { + /* Create SBR channels */ + for (i = 0; i < nChannels; i++) { hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i); - if (hSbrEncoder->pSbrChannel[i]==NULL) { - goto bail; + if (hSbrEncoder->pSbrChannel[i] == NULL) { + goto bail; } - if ( createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, - i - ,hSbrEncoder->dynamicRam - ) ) - { - goto bail; + if (createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, i, + hSbrEncoder->dynamicRam)) { + goto bail; } - } - for (i=0; i<fixMax(nChannels,(supportPS)?2:0); i++) { + /* Create QMF States */ + for (i = 0; i < fixMax(nChannels, (supportPS) ? 2 : 0); i++) { hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i); - if (hSbrEncoder->QmfAnalysis[i].FilterStates==NULL) { - goto bail; + if (hSbrEncoder->QmfAnalysis[i].FilterStates == NULL) { + goto bail; } } + /* Create Parametric Stereo handle */ if (supportPS) { - if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) - { + if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) { goto bail; } hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis(); - if (hSbrEncoder->qmfSynthesisPS.FilterStates==NULL) { + if (hSbrEncoder->qmfSynthesisPS.FilterStates == NULL) { goto bail; } - } /* supportPS */ + } /* supportPS */ *phSbrEncoder = hSbrEncoder; @@ -1560,56 +1579,74 @@ bail: return errorStatus; } -static -INT FDKsbrEnc_Reallocate( - HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], - const INT noElements) -{ +static INT FDKsbrEnc_Reallocate(HANDLE_SBR_ENCODER hSbrEncoder, + SBR_ELEMENT_INFO elInfo[(8)], + const INT noElements) { INT totalCh = 0; INT totalQmf = 0; INT coreEl; - INT el=-1; + INT el = -1; hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */ - for (coreEl=0; coreEl<noElements; coreEl++) - { + for (coreEl = 0; coreEl < noElements; coreEl++) { /* SBR only handles SCE and CPE's */ if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { el++; } else { if (elInfo[coreEl].elType == ID_LFE) { - hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0]; + hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0]; } continue; } - SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl]; - HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el]; + SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl]; + HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el]; int ch; - for ( ch = 0; ch < pelInfo->nChannelsInEl; ch++ ) { + for (ch = 0; ch < pelInfo->nChannelsInEl; ch++) { hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh]; totalCh++; } /* analysis QMF */ - for ( ch = 0; ch < ((pelInfo->fParametricStereo)?2:pelInfo->nChannelsInEl); ch++ ) { + for (ch = 0; + ch < ((pelInfo->fParametricStereo) ? 2 : pelInfo->nChannelsInEl); + ch++) { hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch]; hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++]; } /* Copy Element info */ - hSbrElement->elInfo.elType = pelInfo->elType; - hSbrElement->elInfo.instanceTag = pelInfo->instanceTag; - hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl; + hSbrElement->elInfo.elType = pelInfo->elType; + hSbrElement->elInfo.instanceTag = pelInfo->instanceTag; + hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl; hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo; + hSbrElement->elInfo.fDualMono = pelInfo->fDualMono; } /* coreEl */ return 0; } +/***************************************************************************** + + functionname: FDKsbrEnc_bsBufInit + description: initializes bitstream buffer + returns: initialized bitstream buffer in env encoder + input: + output: hEnv + +*****************************************************************************/ +static INT FDKsbrEnc_bsBufInit(HANDLE_SBR_ELEMENT hSbrElement, + int nBitstrDelay) { + UCHAR *bitstreamBuffer; + + /* initialize the bitstream buffer */ + bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay]; + FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, + MAX_PAYLOAD_SIZE * sizeof(UCHAR), 0, BS_WRITER); + return (0); +} /***************************************************************************** @@ -1620,113 +1657,109 @@ INT FDKsbrEnc_Reallocate( output: hEnv *****************************************************************************/ -static -INT FDKsbrEnc_EnvInit ( - HANDLE_SBR_ELEMENT hSbrElement, - sbrConfigurationPtr params, - INT *coreBandWith, - AUDIO_OBJECT_TYPE aot, - int nBitstrDelay, - int nElement, - const int headerPeriod, - ULONG statesInitFlag, - int fTimeDomainDownsampling - ,UCHAR *dynamic_RAM - ) -{ - UCHAR *bitstreamBuffer; +static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement, + sbrConfigurationPtr params, INT *coreBandWith, + AUDIO_OBJECT_TYPE aot, int nElement, + const int headerPeriod, ULONG statesInitFlag, + const SBRENC_DS_TYPE downsamplingMethod, + UCHAR *dynamic_RAM) { int ch, i; - if ((params->codecSettings.nChannels < 1) || (params->codecSettings.nChannels > MAX_NUM_CHANNELS)){ - return(1); + if ((params->codecSettings.nChannels < 1) || + (params->codecSettings.nChannels > MAX_NUM_CHANNELS)) { + return (1); } - /* initialize the encoder handle and structs*/ - bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay]; - /* init and set syntax flags */ hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; switch (aot) { - case AOT_ER_AAC_ELD: - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; - break; - default: - break; + case AOT_ER_AAC_ELD: + hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; + break; + default: + break; } if (params->crcSbr) { hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; } - hSbrElement->sbrConfigData.noQmfBands = QMF_CHANNELS>>(2-params->downSampleFactor); - switch (hSbrElement->sbrConfigData.noQmfBands) - { - case 64: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6; - break; - case 32: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>5; - break; - default: hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize>>6; - return(2); + hSbrElement->sbrConfigData.noQmfBands = 64 >> (2 - params->downSampleFactor); + switch (hSbrElement->sbrConfigData.noQmfBands) { + case 64: + hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; + break; + case 32: + hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 5; + break; + default: + hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; + return (2); } - FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, MAX_PAYLOAD_SIZE*sizeof(UCHAR), 0, BS_WRITER); - /* now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData, */ hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels; - if(params->codecSettings.nChannels == 2) - hSbrElement->sbrConfigData.stereoMode = params->stereoMode; - else - hSbrElement->sbrConfigData.stereoMode = SBR_MONO; + if (params->codecSettings.nChannels == 2) { + if ((hSbrElement->elInfo.elType == ID_CPE) && + ((hSbrElement->elInfo.fDualMono == 1))) { + hSbrElement->sbrConfigData.stereoMode = SBR_LEFT_RIGHT; + } else { + hSbrElement->sbrConfigData.stereoMode = params->stereoMode; + } + } else { + hSbrElement->sbrConfigData.stereoMode = SBR_MONO; + } - hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; + hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; - hSbrElement->sbrConfigData.sampleFreq = params->downSampleFactor * params->codecSettings.sampleFreq; + hSbrElement->sbrConfigData.sampleFreq = + params->downSampleFactor * params->codecSettings.sampleFreq; hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; - if (params->SendHeaderDataTime > 0 ) { - - if (headerPeriod==-1) { - - hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)(params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq - / (1000 * hSbrElement->sbrConfigData.frameSize)); - hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData,1); - } - else { + if (params->SendHeaderDataTime > 0) { + if (headerPeriod == -1) { + hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)( + params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq / + (1000 * hSbrElement->sbrConfigData.frameSize)); + hSbrElement->sbrBitstreamData.NrSendHeaderData = + fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData, 1); + } else { /* assure header period at least once per second */ - hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin(fixMax(headerPeriod,1),(hSbrElement->sbrConfigData.sampleFreq/hSbrElement->sbrConfigData.frameSize)); + hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin( + fixMax(headerPeriod, 1), (hSbrElement->sbrConfigData.sampleFreq / + hSbrElement->sbrConfigData.frameSize)); } - } - else { - hSbrElement->sbrBitstreamData.NrSendHeaderData = 0; + } else { + hSbrElement->sbrBitstreamData.NrSendHeaderData = 0; } hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra; hSbrElement->sbrBitstreamData.HeaderActive = 0; + hSbrElement->sbrBitstreamData.rightBorderFIX = 0; hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq; - hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq; + hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq; hSbrElement->sbrHeaderData.sbr_xover_band = 0; hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0; /* data_extra */ - if (params->sbr_xpos_ctrl!= SBR_XPOS_CTRL_DEFAULT) - hSbrElement->sbrHeaderData.sbr_data_extra = 1; + if (params->sbr_xpos_ctrl != SBR_XPOS_CTRL_DEFAULT) + hSbrElement->sbrHeaderData.sbr_data_extra = 1; hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res; /* header_extra_1 */ - hSbrElement->sbrHeaderData.freqScale = params->freqScale; + hSbrElement->sbrHeaderData.freqScale = params->freqScale; hSbrElement->sbrHeaderData.alterScale = params->alterScale; hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands; hSbrElement->sbrHeaderData.header_extra_1 = 0; if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) || (params->alterScale != SBR_ALTER_SCALE_DEFAULT) || - (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) - { - hSbrElement->sbrHeaderData.header_extra_1 = 1; + (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) { + hSbrElement->sbrHeaderData.header_extra_1 = 1; } /* header_extra_2 */ @@ -1734,95 +1767,92 @@ INT FDKsbrEnc_EnvInit ( hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains; if ((hSbrElement->sbrConfigData.sampleFreq > 48000) && - (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) - { + (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) { hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE; } hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq; - hSbrElement->sbrHeaderData.sbr_smoothing_length = params->sbr_smoothing_length; + hSbrElement->sbrHeaderData.sbr_smoothing_length = + params->sbr_smoothing_length; hSbrElement->sbrHeaderData.header_extra_2 = 0; if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) || (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) || (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) || - (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) - { - hSbrElement->sbrHeaderData.header_extra_2 = 1; + (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) { + hSbrElement->sbrHeaderData.header_extra_2 = 1; } - /* other switches */ - hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; - hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; - hSbrElement->sbrConfigData.thresholdAmpResFF_m = params->threshold_AmpRes_FF_m; - hSbrElement->sbrConfigData.thresholdAmpResFF_e = params->threshold_AmpRes_FF_e; + /* other switches */ + hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; + hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; + hSbrElement->sbrConfigData.thresholdAmpResFF_m = + params->threshold_AmpRes_FF_m; + hSbrElement->sbrConfigData.thresholdAmpResFF_e = + params->threshold_AmpRes_FF_e; /* init freq band table */ - if(updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - params->downSampleFactor - )) - { - return(1); + if (updateFreqBandTable(&hSbrElement->sbrConfigData, + &hSbrElement->sbrHeaderData, + params->downSampleFactor)) { + return (1); } /* now create envelope ext and QMF for each available channel */ - for ( ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++ ) { - - if ( initEnvChannel(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrChannel[ch]->hEnvChannel, - params, - statesInitFlag - ,ch - ,dynamic_RAM - ) ) - { - return(1); - } - + for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { + if (initEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, + &hSbrElement->sbrChannel[ch]->hEnvChannel, params, + statesInitFlag, ch, dynamic_RAM)) { + return (1); + } } /* nChannels */ /* reset and intialize analysis qmf */ - for ( ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo)?2:hSbrElement->sbrConfigData.nChannels); ch++ ) - { + for (ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo) + ? 2 + : hSbrElement->sbrConfigData.nChannels); + ch++) { int err; - UINT qmfFlags = (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? QMF_FLAG_CLDFB : 0; + UINT qmfFlags = + (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) + ? QMF_FLAG_CLDFB + : 0; if (statesInitFlag) qmfFlags &= ~QMF_FLAG_KEEP_STATES; else - qmfFlags |= QMF_FLAG_KEEP_STATES; - - err = qmfInitAnalysisFilterBank( hSbrElement->hQmfAnalysis[ch], - (FIXP_QAS*)hSbrElement->hQmfAnalysis[ch]->FilterStates, - hSbrElement->sbrConfigData.noQmfSlots, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, - qmfFlags ); - if (0!=err) { + qmfFlags |= QMF_FLAG_KEEP_STATES; + + err = qmfInitAnalysisFilterBank( + hSbrElement->hQmfAnalysis[ch], + (FIXP_QAS *)hSbrElement->hQmfAnalysis[ch]->FilterStates, + hSbrElement->sbrConfigData.noQmfSlots, + hSbrElement->sbrConfigData.noQmfBands, + hSbrElement->sbrConfigData.noQmfBands, + hSbrElement->sbrConfigData.noQmfBands, qmfFlags); + if (0 != err) { return err; } } /* */ hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq; - hSbrElement->CmonData.dynBwEnabled = (params->dynBwSupported && params->dynBwEnabled); - hSbrElement->CmonData.dynXOverFreqEnc = FDKsbrEnc_SbrGetXOverFreq( hSbrElement, hSbrElement->CmonData.xOverFreq); - for ( i = 0; i < 5; i++ ) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc; - hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels; + hSbrElement->CmonData.dynBwEnabled = + (params->dynBwSupported && params->dynBwEnabled); + hSbrElement->CmonData.dynXOverFreqEnc = + FDKsbrEnc_SbrGetXOverFreq(hSbrElement, hSbrElement->CmonData.xOverFreq); + for (i = 0; i < 5; i++) + hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc; + hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels; hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq; /* Update Bandwith to be passed to the core encoder */ *coreBandWith = hSbrElement->CmonData.xOverFreq; - return(0); - } + return (0); +} -INT sbrEncoder_GetInBufferSize(int noChannels) -{ +INT sbrEncoder_GetInBufferSize(int noChannels) { INT temp; temp = (2048); @@ -1835,53 +1865,42 @@ INT sbrEncoder_GetInBufferSize(int noChannels) /* * Encode Dummy SBR payload frames to fill the delay lines. */ -static -INT FDKsbrEnc_DelayCompensation ( - HANDLE_SBR_ENCODER hEnvEnc, - INT_PCM *timeBuffer - ) -{ - int n, el; - - for (n=hEnvEnc->nBitstrDelay; n>0; n--) - { - for (el=0; el<hEnvEnc->noElements; el++) - { - if (FDKsbrEnc_EnvEncodeFrame( - hEnvEnc, - el, - timeBuffer + hEnvEnc->downsampledOffset, - hEnvEnc->sbrElement[el]->sbrConfigData.nChannels, - NULL, - NULL, - 1 - )) - return -1; - } - sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer); +static INT FDKsbrEnc_DelayCompensation(HANDLE_SBR_ENCODER hEnvEnc, + INT_PCM *timeBuffer, + UINT timeBufferBufSize) { + int n, el; + + for (n = hEnvEnc->nBitstrDelay; n > 0; n--) { + for (el = 0; el < hEnvEnc->noElements; el++) { + if (FDKsbrEnc_EnvEncodeFrame( + hEnvEnc, el, + timeBuffer + hEnvEnc->downsampledOffset / hEnvEnc->nChannels, + timeBufferBufSize, NULL, NULL, 1)) + return -1; } - return 0; + sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer, timeBufferBufSize); + } + return 0; } -UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) -{ - UINT newBitRate; +UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, + UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) { + UINT newBitRate = bitRate; INT index; FDK_ASSERT(numChannels > 0 && numChannels <= 2); if (aot == AOT_PS) { - if (numChannels == 2) { + if (numChannels == 1) { index = getPsTuningTableIndex(bitRate, &newBitRate); if (index == INVALID_TABLE_IDX) { bitRate = newBitRate; } - /* Set numChannels to 1 because for PS we need a SBR SCE (mono) element. */ - numChannels = 1; } else { return 0; } } - index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, &newBitRate); + index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, + &newBitRate); if (index != INVALID_TABLE_IDX) { newBitRate = bitRate; } @@ -1889,523 +1908,640 @@ UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, UINT coreSampleRate return newBitRate; } -UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) -{ - UINT isPossible=(AOT_PS==aot)?0:1; +UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) { + UINT isPossible = (AOT_PS == aot) ? 0 : 1; return isPossible; } -INT sbrEncoder_Init( - HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], - int noElements, - INT_PCM *inputBuffer, - INT *coreBandwidth, - INT *inputBufferOffset, - INT *numChannels, - INT *coreSampleRate, - UINT *downSampleFactor, - INT *frameLength, - AUDIO_OBJECT_TYPE aot, - int *delay, - int transformFactor, - const int headerPeriod, - ULONG statesInitFlag - ) -{ - HANDLE_ERROR_INFO errorInfo = noError; - sbrConfiguration sbrConfig[(8)]; - INT error = 0; - INT lowestBandwidth; - /* Save input parameters */ - INT inputSampleRate = *coreSampleRate; - int coreFrameLength = *frameLength; - int inputBandWidth = *coreBandwidth; - int inputChannels = *numChannels; - - int downsampledOffset = 0; - int sbrOffset = 0; - int downsamplerDelay = 0; - int timeDomainDownsample = 0; - int nBitstrDelay = 0; - int highestSbrStartFreq, highestSbrStopFreq; - int lowDelay = 0; - int usePs = 0; - - /* check whether SBR setting is available for the current encoder configuration (bitrate, samplerate) */ - if (!sbrEncoder_IsSingleRatePossible(aot)) { - *downSampleFactor = 2; +/*****************************************************************************/ +/* */ +/*functionname: sbrEncoder_Init_delay */ +/*description: Determine Delay balancing and new encoder delay */ +/* */ +/*returns: - error status */ +/*input: - frame length of the core (i.e. e.g. AAC) */ +/* - number of channels */ +/* - downsample factor (1 for downsampled, 2 for dual-rate SBR) */ +/* - low delay presence */ +/* - ps presence */ +/* - downsampling method: QMF-, time domain or no downsampling */ +/* - various delay values (see DELAY_PARAM struct description) */ +/* */ +/*Example: Delay balancing for a HE-AACv1 encoder (time-domain downsampling) */ +/*========================================================================== */ +/* */ +/* +--------+ +--------+ +--------+ +--------+ +--------+ */ +/* |core | |ds 2:1 | |AAC | |QMF | |QMF | */ +/* +-+path +------------+ +-+core +-+analysis+-+overlap +-+ */ +/* | |offset | | | | | |32 bands| | | | */ +/* | +--------+ +--------+ +--------+ +--------+ +--------+ | */ +/* | core path +-------++ */ +/* | |QMF | */ +/*->+ +synth. +-> */ +/* | |64 bands| */ +/* | +-------++ */ +/* | +--------+ +--------+ +--------+ +--------+ | */ +/* | |SBR path| |QMF | |subband | |bs delay| | */ +/* +-+offset +-+analysis+-+sample +-+(full +-----------------------+ */ +/* | | |64 bands| |buffer | | frames)| */ +/* +--------+ +--------+ +--------+ +--------+ */ +/* SBR path */ +/* */ +/*****************************************************************************/ +static INT sbrEncoder_Init_delay( + const int coreFrameLength, /* input */ + const int numChannels, /* input */ + const int downSampleFactor, /* input */ + const int lowDelay, /* input */ + const int usePs, /* input */ + const int is212, /* input */ + const SBRENC_DS_TYPE downsamplingMethod, /* input */ + DELAY_PARAM *hDelayParam /* input/output */ +) { + int delayCorePath = 0; /* delay in core path */ + int delaySbrPath = 0; /* delay difference in QMF aka SBR path */ + int delayInput2Core = 0; /* delay from the input to the core */ + int delaySbrDec = 0; /* delay of the decoder's SBR module */ + + int delayCore = hDelayParam->delay; /* delay of the core */ + + /* Added delay by the SBR delay initialization */ + int corePathOffset = 0; /* core path */ + int sbrPathOffset = 0; /* sbr path */ + int bitstreamDelay = 0; /* sbr path, framewise */ + + int flCore = coreFrameLength; /* core frame length */ + + int returnValue = 0; /* return value - 0 means: no error */ + + /* 1) Calculate actual delay for core and SBR path */ + if (is212) { + delayCorePath = DELAY_COREPATH_ELDv2SBR(flCore, downSampleFactor); + delaySbrPath = DELAY_ELDv2SBR(flCore, downSampleFactor); + delaySbrDec = ((flCore) / 2) * (downSampleFactor); + } else if (lowDelay) { + delayCorePath = DELAY_COREPATH_ELDSBR(flCore, downSampleFactor); + delaySbrPath = DELAY_ELDSBR(flCore, downSampleFactor); + delaySbrDec = DELAY_QMF_POSTPROC(downSampleFactor); + } else if (usePs) { + delayCorePath = DELAY_COREPATH_PS(flCore, downSampleFactor); + delaySbrPath = DELAY_PS(flCore, downSampleFactor); + delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); + } else { + delayCorePath = DELAY_COREPATH_SBR(flCore, downSampleFactor); + delaySbrPath = DELAY_SBR(flCore, downSampleFactor); + delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); + } + delayCorePath += delayCore * downSampleFactor; + delayCorePath += + (downsamplingMethod == SBRENC_DS_TIME) ? hDelayParam->dsDelay : 0; + + /* 2) Manage coupling of paths */ + if (downsamplingMethod == SBRENC_DS_QMF && delayCorePath > delaySbrPath) { + /* In case of QMF downsampling, both paths are coupled, i.e. the SBR path + offset would be added to both the SBR path and to the core path + as well, thus making it impossible to achieve delay balancing. + To overcome that problem, a framewise delay is added to the SBR path + first, until the overall delay of the core path is shorter than + the delay of the SBR path. When this is achieved, the missing delay + difference can be added as downsampled offset to the core path. + */ + while (delayCorePath > delaySbrPath) { + /* Add one frame delay to SBR path */ + delaySbrPath += flCore * downSampleFactor; + bitstreamDelay += 1; } + } + /* 3) Calculate necessary additional delay to balance the paths */ + if (delayCorePath > delaySbrPath) { + /* Delay QMF input */ + while (delayCorePath > delaySbrPath + (int)flCore * (int)downSampleFactor) { + /* Do bitstream frame-wise delay balancing if there are + more than SBR framelength samples delay difference */ + delaySbrPath += flCore * downSampleFactor; + bitstreamDelay += 1; + } + /* Multiply input offset by input channels */ + corePathOffset = 0; + sbrPathOffset = (delayCorePath - delaySbrPath) * numChannels; + } else { + /* Delay AAC data */ + /* Multiply downsampled offset by AAC core channels. Divide by 2 because of + half samplerate of downsampled data. */ + corePathOffset = ((delaySbrPath - delayCorePath) * numChannels) >> + (downSampleFactor - 1); + sbrPathOffset = 0; + } + /* 4) Calculate delay from input to core */ + if (usePs) { + delayInput2Core = + (DELAY_QMF_ANA(downSampleFactor) + DELAY_QMF_DS + DELAY_HYB_SYN) + + (downSampleFactor * corePathOffset) + 1; + } else if (downsamplingMethod == SBRENC_DS_TIME) { + delayInput2Core = corePathOffset + hDelayParam->dsDelay; + } else { + delayInput2Core = corePathOffset; + } - if ( aot==AOT_PS ) { - usePs = 1; - } - if ( aot==AOT_ER_AAC_ELD ) { - lowDelay = 1; - } - else if ( aot==AOT_ER_AAC_LD ) { - error = 1; - goto bail; - } + /* 6) Set output parameters */ + hDelayParam->delay = FDKmax(delayCorePath, delaySbrPath); /* overall delay */ + hDelayParam->sbrDecDelay = delaySbrDec; /* SBR decoder delay */ + hDelayParam->delayInput2Core = delayInput2Core; /* delay input - core */ + hDelayParam->bitstrDelay = bitstreamDelay; /* bitstream delay, in frames */ + hDelayParam->corePathOffset = corePathOffset; /* offset added to core path */ + hDelayParam->sbrPathOffset = sbrPathOffset; /* offset added to SBR path */ - /* Parametric Stereo */ - if ( usePs ) { - if ( *numChannels == 2 && noElements == 1) { - /* Override Element type in case of Parametric stereo */ - elInfo[0].elType = ID_SCE; - elInfo[0].fParametricStereo = 1; - elInfo[0].nChannelsInEl = 1; - /* core encoder gets downmixed mono signal */ - *numChannels = 1; - } else { - error = 1; - goto bail; - } - } /* usePs */ + return returnValue; +} - /* set the core's sample rate */ - switch (*downSampleFactor) { +/***************************************************************************** + + functionname: sbrEncoder_Init + description: initializes the SBR encoder + returns: error status + +*****************************************************************************/ +INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder, + SBR_ELEMENT_INFO elInfo[(8)], int noElements, + INT_PCM *inputBuffer, UINT inputBufferBufSize, + INT *coreBandwidth, INT *inputBufferOffset, + INT *numChannels, const UINT syntaxFlags, + INT *coreSampleRate, UINT *downSampleFactor, + INT *frameLength, AUDIO_OBJECT_TYPE aot, int *delay, + int transformFactor, const int headerPeriod, + ULONG statesInitFlag) { + HANDLE_ERROR_INFO errorInfo = noError; + sbrConfiguration sbrConfig[(8)]; + INT error = 0; + INT lowestBandwidth; + /* Save input parameters */ + INT inputSampleRate = *coreSampleRate; + int coreFrameLength = *frameLength; + int inputBandWidth = *coreBandwidth; + int inputChannels = *numChannels; + + SBRENC_DS_TYPE downsamplingMethod = SBRENC_DS_NONE; + int highestSbrStartFreq, highestSbrStopFreq; + int lowDelay = 0; + int usePs = 0; + int is212 = 0; + + DELAY_PARAM delayParam; + + /* check whether SBR setting is available for the current encoder + * configuration (bitrate, samplerate) */ + if (!sbrEncoder_IsSingleRatePossible(aot)) { + *downSampleFactor = 2; + } + + if (aot == AOT_PS) { + usePs = 1; + } + if (aot == AOT_ER_AAC_ELD) { + lowDelay = 1; + } else if (aot == AOT_ER_AAC_LD) { + error = 1; + goto bail; + } + + /* Parametric Stereo */ + if (usePs) { + if (*numChannels == 2 && noElements == 1) { + /* Override Element type in case of Parametric stereo */ + elInfo[0].elType = ID_SCE; + elInfo[0].fParametricStereo = 1; + elInfo[0].nChannelsInEl = 1; + /* core encoder gets downmixed mono signal */ + *numChannels = 1; + } else { + error = 1; + goto bail; + } + } /* usePs */ + + /* set the core's sample rate */ + switch (*downSampleFactor) { case 1: *coreSampleRate = inputSampleRate; + downsamplingMethod = SBRENC_DS_NONE; break; case 2: - *coreSampleRate = inputSampleRate>>1; + *coreSampleRate = inputSampleRate >> 1; + downsamplingMethod = usePs ? SBRENC_DS_QMF : SBRENC_DS_TIME; break; default: - *coreSampleRate = inputSampleRate>>1; + *coreSampleRate = inputSampleRate >> 1; return 0; /* return error */ - } + } - /* check whether SBR setting is available for the current encoder configuration (bitrate, coreSampleRate) */ - { - int delayDiff = 0; - int el, coreEl; - - /* Check if every element config is feasible */ - for (coreEl=0; coreEl<noElements; coreEl++) - { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) { - continue; - } - /* check if desired configuration is available */ - if ( !FDKsbrEnc_IsSbrSettingAvail (elInfo[coreEl].bitRate, 0, elInfo[coreEl].nChannelsInEl, inputSampleRate, *coreSampleRate, aot) ) - { - error = 1; - goto bail; - } - } + /* check whether SBR setting is available for the current encoder + * configuration (bitrate, coreSampleRate) */ + { + int el, coreEl; - /* Determine Delay balancing and new encoder delay */ - if (lowDelay) { - { - delayDiff = (*delay * *downSampleFactor) + DELAY_ELD2SBR(coreFrameLength,*downSampleFactor); - *delay = DELAY_ELDSBR(coreFrameLength,*downSampleFactor); - } - } - else if (usePs) { - delayDiff = (*delay * *downSampleFactor) + DELAY_AAC2PS(coreFrameLength,*downSampleFactor); - *delay = DELAY_PS(coreFrameLength,*downSampleFactor); - } - else { - delayDiff = DELAY_AAC2SBR(coreFrameLength,*downSampleFactor); - delayDiff += (*delay * *downSampleFactor); - *delay = DELAY_SBR(coreFrameLength,*downSampleFactor); + /* Check if every element config is feasible */ + for (coreEl = 0; coreEl < noElements; coreEl++) { + /* SBR only handles SCE and CPE's */ + if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) { + continue; } - - if (!usePs) { - timeDomainDownsample = *downSampleFactor-1; /* activate time domain downsampler when downSampleFactor is != 1 */ + /* check if desired configuration is available */ + if (!FDKsbrEnc_IsSbrSettingAvail(elInfo[coreEl].bitRate, 0, + elInfo[coreEl].nChannelsInEl, + inputSampleRate, *coreSampleRate, aot)) { + error = 1; + goto bail; } + } - - /* Take care about downsampled data bound to the SBR path */ - if (!timeDomainDownsample && delayDiff > 0) { - /* - * We must tweak the balancing into a situation where the downsampled path - * is the one to be delayed, because delaying the QMF domain input, also delays - * the downsampled audio, counteracting to the purpose of delay balancing. - */ - while ( delayDiff > 0 ) - { - /* Encoder delay increases */ - { - *delay += coreFrameLength * *downSampleFactor; - /* Add one frame delay to SBR path */ - delayDiff -= coreFrameLength * *downSampleFactor; - } - nBitstrDelay += 1; - } - } else - { - *delay += fixp_abs(delayDiff); + hSbrEncoder->nChannels = *numChannels; + hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor; + hSbrEncoder->downsamplingMethod = downsamplingMethod; + hSbrEncoder->downSampleFactor = *downSampleFactor; + hSbrEncoder->estimateBitrate = 0; + hSbrEncoder->inputDataDelay = 0; + is212 = ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS)) ? 1 : 0; + + /* Open SBR elements */ + el = -1; + highestSbrStartFreq = highestSbrStopFreq = 0; + lowestBandwidth = 99999; + + /* Loop through each core encoder element and get a matching SBR element + * config */ + for (coreEl = 0; coreEl < noElements; coreEl++) { + /* SBR only handles SCE and CPE's */ + if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { + el++; + } else { + continue; } - if (delayDiff < 0) { - /* Delay AAC data */ - delayDiff = -delayDiff; - /* Multiply downsampled offset by AAC core channels. Divide by 2 because of half samplerate of downsampled data. */ - FDK_ASSERT(*downSampleFactor>0 && *downSampleFactor<=2); - downsampledOffset = (delayDiff*(*numChannels))>>(*downSampleFactor-1); - sbrOffset = 0; + /* Set parametric Stereo Flag. */ + if (usePs) { + elInfo[coreEl].fParametricStereo = 1; } else { - /* Delay SBR input */ - if ( delayDiff > (int)coreFrameLength * (int)*downSampleFactor ) - { - /* Do bitstream frame-wise delay balancing if we have more than SBR framelength samples delay difference */ - delayDiff -= coreFrameLength * *downSampleFactor; - nBitstrDelay = 1; - } - /* Multiply input offset by input channels */ - sbrOffset = delayDiff*(*numChannels); - downsampledOffset = 0; + elInfo[coreEl].fParametricStereo = 0; } - hSbrEncoder->nBitstrDelay = nBitstrDelay; - hSbrEncoder->nChannels = *numChannels; - hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor; - hSbrEncoder->fTimeDomainDownsampling = timeDomainDownsample; - hSbrEncoder->downSampleFactor = *downSampleFactor; - hSbrEncoder->estimateBitrate = 0; - hSbrEncoder->inputDataDelay = 0; - - - /* Open SBR elements */ - el = -1; - highestSbrStartFreq = highestSbrStopFreq = 0; - lowestBandwidth = 99999; - - /* Loop through each core encoder element and get a matching SBR element config */ - for (coreEl=0; coreEl<noElements; coreEl++) - { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { - el++; - } else { - continue; - } - /* Set parametric Stereo Flag. */ - if (usePs) { - elInfo[coreEl].fParametricStereo = 1; - } else { - elInfo[coreEl].fParametricStereo = 0; - } - - /* - * Init sbrConfig structure - */ - if ( ! FDKsbrEnc_InitializeSbrDefaults ( &sbrConfig[el], - *downSampleFactor, - coreFrameLength, - IS_LOWDELAY(aot) - ) ) - { - error = 1; - goto bail; - } - - /* - * Modify sbrConfig structure according to Element parameters - */ - if ( ! FDKsbrEnc_AdjustSbrSettings (&sbrConfig[el], - elInfo[coreEl].bitRate, - elInfo[coreEl].nChannelsInEl, - *coreSampleRate, - inputSampleRate, - transformFactor, - 24000, - 0, - 0, /* useSpeechConfig */ - 0, /* lcsMode */ - usePs, /* bParametricStereo */ - aot) ) - { - error = 1; - goto bail; - } - - /* Find common frequency border for all SBR elements */ - highestSbrStartFreq = fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); - highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); - - } /* first element loop */ - - /* Set element count (can be less than core encoder element count) */ - hSbrEncoder->noElements = el+1; + /* + * Init sbrConfig structure + */ + if (!FDKsbrEnc_InitializeSbrDefaults(&sbrConfig[el], *downSampleFactor, + coreFrameLength, IS_LOWDELAY(aot))) { + error = 1; + goto bail; + } - FDKsbrEnc_Reallocate(hSbrEncoder, - elInfo, - noElements); + /* + * Modify sbrConfig structure according to Element parameters + */ + if (!FDKsbrEnc_AdjustSbrSettings( + &sbrConfig[el], elInfo[coreEl].bitRate, + elInfo[coreEl].nChannelsInEl, *coreSampleRate, inputSampleRate, + transformFactor, 24000, 0, 0, /* useSpeechConfig */ + 0, /* lcsMode */ + usePs, /* bParametricStereo */ + aot)) { + error = 1; + goto bail; + } - for (el=0; el<hSbrEncoder->noElements; el++) { + /* Find common frequency border for all SBR elements */ + highestSbrStartFreq = + fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); + highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); - int bandwidth = *coreBandwidth; + } /* first element loop */ - /* Use lowest common bandwidth */ - sbrConfig[el].startFreq = highestSbrStartFreq; - sbrConfig[el].stopFreq = highestSbrStopFreq; + /* Set element count (can be less than core encoder element count) */ + hSbrEncoder->noElements = el + 1; - /* initialize SBR element, and get core bandwidth */ - error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], - &sbrConfig[el], - &bandwidth, - aot, - nBitstrDelay, - el, - headerPeriod, - statesInitFlag, - hSbrEncoder->fTimeDomainDownsampling - ,hSbrEncoder->dynamicRam - ); + FDKsbrEnc_Reallocate(hSbrEncoder, elInfo, noElements); - if (error != 0) { - error = 2; - goto bail; - } + for (el = 0; el < hSbrEncoder->noElements; el++) { + int bandwidth = *coreBandwidth; - /* Get lowest core encoder bandwidth to be returned later. */ - lowestBandwidth = fixMin(lowestBandwidth, bandwidth); + /* Use lowest common bandwidth */ + sbrConfig[el].startFreq = highestSbrStartFreq; + sbrConfig[el].stopFreq = highestSbrStopFreq; - } /* second element loop */ + /* initialize SBR element, and get core bandwidth */ + error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], &sbrConfig[el], + &bandwidth, aot, el, headerPeriod, + statesInitFlag, hSbrEncoder->downsamplingMethod, + hSbrEncoder->dynamicRam); - /* Initialize a downsampler for each channel in each SBR element */ - if (hSbrEncoder->fTimeDomainDownsampling) - { - for (el=0; el<hSbrEncoder->noElements; el++) - { - HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el]; - INT Wc, ch; + if (error != 0) { + error = 2; + goto bail; + } - /* Calculated required normalized cutoff frequency (Wc = 1.0 -> lowestBandwidth = inputSampleRate/2) */ - Wc = (2*lowestBandwidth)*1000 / inputSampleRate; + /* Get lowest core encoder bandwidth to be returned later. */ + lowestBandwidth = fixMin(lowestBandwidth, bandwidth); - for (ch=0; ch<hSbrEl->elInfo.nChannelsInEl; ch++) - { - FDKaacEnc_InitDownsampler (&hSbrEl->sbrChannel[ch]->downSampler, Wc, *downSampleFactor); - FDK_ASSERT (hSbrEl->sbrChannel[ch]->downSampler.delay <=MAX_DS_FILTER_DELAY); - } + } /* second element loop */ - downsamplerDelay = hSbrEl->sbrChannel[0]->downSampler.delay; - } /* third element loop */ + /* Initialize a downsampler for each channel in each SBR element */ + if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { + for (el = 0; el < hSbrEncoder->noElements; el++) { + HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el]; + INT Wc, ch; - /* lfe */ - FDKaacEnc_InitDownsampler (&hSbrEncoder->lfeDownSampler, 0, *downSampleFactor); + Wc = 500; /* Cutoff frequency with full bandwidth */ - /* Add the resampler additional delay to get the final delay and buffer offset values. */ - if (sbrOffset > 0 || downsampledOffset <= ((downsamplerDelay * (*numChannels))>>(*downSampleFactor-1))) { - sbrOffset += (downsamplerDelay - downsampledOffset) * (*numChannels) ; - *delay += downsamplerDelay - downsampledOffset; - downsampledOffset = 0; - } else { - downsampledOffset -= (downsamplerDelay * (*numChannels))>>(*downSampleFactor-1); - sbrOffset = 0; + for (ch = 0; ch < hSbrEl->elInfo.nChannelsInEl; ch++) { + FDKaacEnc_InitDownsampler(&hSbrEl->sbrChannel[ch]->downSampler, Wc, + *downSampleFactor); + FDK_ASSERT(hSbrEl->sbrChannel[ch]->downSampler.delay <= + MAX_DS_FILTER_DELAY); } + } /* third element loop */ - hSbrEncoder->inputDataDelay = downsamplerDelay; - } + /* lfe */ + FDKaacEnc_InitDownsampler(&hSbrEncoder->lfeDownSampler, 0, + *downSampleFactor); + } - /* Assign core encoder Bandwidth */ - *coreBandwidth = lowestBandwidth; + /* Get delay information */ + delayParam.dsDelay = + hSbrEncoder->sbrElement[0]->sbrChannel[0]->downSampler.delay; + delayParam.delay = *delay; - /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */ - hSbrEncoder->estimateBitrate += 2500 * (*numChannels); + error = sbrEncoder_Init_delay(coreFrameLength, *numChannels, + *downSampleFactor, lowDelay, usePs, is212, + downsamplingMethod, &delayParam); - /* initialize parametric stereo */ - if (usePs) - { - PSENC_CONFIG psEncConfig; - FDK_ASSERT(hSbrEncoder->noElements == 1); - INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); + if (error != 0) { + error = 3; + goto bail; + } - psEncConfig.frameSize = coreFrameLength; //sbrConfig.sbrFrameSize; - psEncConfig.qmfFilterMode = 0; - psEncConfig.sbrPsDelay = 0; + hSbrEncoder->nBitstrDelay = delayParam.bitstrDelay; + hSbrEncoder->sbrDecDelay = delayParam.sbrDecDelay; + hSbrEncoder->inputDataDelay = delayParam.delayInput2Core; - /* tuning parameters */ - if (psTuningTableIdx != INVALID_TABLE_IDX) { - psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands; - psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes; - psEncConfig.iidQuantErrorThreshold = (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold; + /* Assign core encoder Bandwidth */ + *coreBandwidth = lowestBandwidth; - /* calculation is not quite linear, increased number of envelopes causes more bits */ - /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope configuration */ - hSbrEncoder->estimateBitrate += ( (((*coreSampleRate) * 5 * psEncConfig.nStereoBands * psEncConfig.maxEnvelopes) / hSbrEncoder->frameSize)); + /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */ + hSbrEncoder->estimateBitrate += 2500 * (*numChannels); - } else { - error = ERROR(CDI, "Invalid ps tuning table index."); - goto bail; - } - - qmfInitSynthesisFilterBank(&hSbrEncoder->qmfSynthesisPS, - (FIXP_DBL*)hSbrEncoder->qmfSynthesisPS.FilterStates, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands>>1, - (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES); - - if(errorInfo == noError){ - /* update delay */ - psEncConfig.sbrPsDelay = FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0]->sbrChannel[0]->hEnvChannel.sbrExtractEnvelope); - - if(noError != (errorInfo = PSEnc_Init( hSbrEncoder->hParametricStereo, - &psEncConfig, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands - ,hSbrEncoder->dynamicRam - ))) - { - errorInfo = handBack(errorInfo); - } - } + /* Initialize bitstream buffer for each element */ + for (el = 0; el < hSbrEncoder->noElements; el++) { + FDKsbrEnc_bsBufInit(hSbrEncoder->sbrElement[el], delayParam.bitstrDelay); + } - /* QMF analysis + Hybrid analysis + Hybrid synthesis + QMF synthesis + downsampled input buffer delay */ - hSbrEncoder->inputDataDelay = (64*10/2) + (6*64) + (0) + (64*10/2-64+1) + ((*downSampleFactor)*downsampledOffset); - } + /* initialize parametric stereo */ + if (usePs) { + PSENC_CONFIG psEncConfig; + FDK_ASSERT(hSbrEncoder->noElements == 1); + INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); + + psEncConfig.frameSize = coreFrameLength; // sbrConfig.sbrFrameSize; + psEncConfig.qmfFilterMode = 0; + psEncConfig.sbrPsDelay = 0; + + /* tuning parameters */ + if (psTuningTableIdx != INVALID_TABLE_IDX) { + psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands; + psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes; + psEncConfig.iidQuantErrorThreshold = + (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold; + + /* calculation is not quite linear, increased number of envelopes causes + * more bits */ + /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope + * configuration */ + hSbrEncoder->estimateBitrate += + ((((*coreSampleRate) * 5 * psEncConfig.nStereoBands * + psEncConfig.maxEnvelopes) / + hSbrEncoder->frameSize)); - hSbrEncoder->downsampledOffset = downsampledOffset; - { - hSbrEncoder->downmixSize = coreFrameLength*(*numChannels); + } else { + error = ERROR(CDI, "Invalid ps tuning table index."); + goto bail; } - hSbrEncoder->bufferOffset = sbrOffset; - /* Delay Compensation: fill bitstream delay buffer with zero input signal */ - if ( hSbrEncoder->nBitstrDelay > 0 ) - { - error = FDKsbrEnc_DelayCompensation (hSbrEncoder, inputBuffer); - if (error != 0) - goto bail; + qmfInitSynthesisFilterBank( + &hSbrEncoder->qmfSynthesisPS, + (FIXP_DBL *)hSbrEncoder->qmfSynthesisPS.FilterStates, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, + (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES); + + if (errorInfo == noError) { + /* update delay */ + psEncConfig.sbrPsDelay = + FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0] + ->sbrChannel[0] + ->hEnvChannel.sbrExtractEnvelope); + + errorInfo = + PSEnc_Init(hSbrEncoder->hParametricStereo, &psEncConfig, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, + hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands, + hSbrEncoder->dynamicRam); } + } - /* Set Output frame length */ - *frameLength = coreFrameLength * *downSampleFactor; - /* Input buffer offset */ - *inputBufferOffset = fixMax(sbrOffset, downsampledOffset); + hSbrEncoder->downsampledOffset = delayParam.corePathOffset; + hSbrEncoder->bufferOffset = delayParam.sbrPathOffset; + *delay = delayParam.delay; + { hSbrEncoder->downmixSize = coreFrameLength * (*numChannels); } + /* Delay Compensation: fill bitstream delay buffer with zero input signal */ + if (hSbrEncoder->nBitstrDelay > 0) { + error = FDKsbrEnc_DelayCompensation(hSbrEncoder, inputBuffer, + inputBufferBufSize); + if (error != 0) goto bail; } - return error; + /* Set Output frame length */ + *frameLength = coreFrameLength * *downSampleFactor; + /* Input buffer offset */ + *inputBufferOffset = + fixMax(delayParam.sbrPathOffset, delayParam.corePathOffset); + } + + return error; bail: - /* Restore input settings */ - *coreSampleRate = inputSampleRate; - *frameLength = coreFrameLength; - *numChannels = inputChannels; - *coreBandwidth = inputBandWidth; - - return error; - } - - -INT -sbrEncoder_EncodeFrame( HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *samples, - UINT timeInStride, - UINT sbrDataBits[(8)], - UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE] - ) -{ + /* Restore input settings */ + *coreSampleRate = inputSampleRate; + *frameLength = coreFrameLength; + *numChannels = inputChannels; + *coreBandwidth = inputBandWidth; + + return error; +} + +INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hSbrEncoder, INT_PCM *samples, + UINT samplesBufSize, UINT sbrDataBits[(8)], + UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]) { INT error; int el; - for (el=0; el<hSbrEncoder->noElements; el++) - { - if (hSbrEncoder->sbrElement[el] != NULL) - { + for (el = 0; el < hSbrEncoder->noElements; el++) { + if (hSbrEncoder->sbrElement[el] != NULL) { error = FDKsbrEnc_EnvEncodeFrame( - hSbrEncoder, - el, - samples + hSbrEncoder->downsampledOffset, - timeInStride, - &sbrDataBits[el], - sbrData[el], - 0 - ); - if (error) - return error; + hSbrEncoder, el, + samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, + samplesBufSize, &sbrDataBits[el], sbrData[el], 0); + if (error) return error; } } - if ( ( hSbrEncoder->lfeChIdx!=-1) && (hSbrEncoder->downSampleFactor > 1) ) - { /* lfe downsampler */ - INT nOutSamples; + error = FDKsbrEnc_Downsample( + hSbrEncoder, + samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, + samplesBufSize, hSbrEncoder->nChannels, &sbrDataBits[el], sbrData[el], 0); + if (error) return error; - FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, - samples + hSbrEncoder->downsampledOffset + hSbrEncoder->bufferOffset + hSbrEncoder->lfeChIdx, - hSbrEncoder->frameSize, - timeInStride, - samples + hSbrEncoder->downsampledOffset + hSbrEncoder->lfeChIdx, - &nOutSamples, - hSbrEncoder->nChannels); + return 0; +} +INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hSbrEncoder, + INT_PCM *timeBuffer, UINT timeBufferBufSize) { + if (hSbrEncoder->downsampledOffset > 0) { + int c; + int nd = hSbrEncoder->downmixSize / hSbrEncoder->nChannels; - } + for (c = 0; c < hSbrEncoder->nChannels; c++) { + /* Move delayed downsampled data */ + FDKmemcpy(timeBuffer + timeBufferBufSize * c, + timeBuffer + timeBufferBufSize * c + nd, + sizeof(INT_PCM) * + (hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels)); + } + } else { + int c; + for (c = 0; c < hSbrEncoder->nChannels; c++) { + /* Move delayed input data */ + FDKmemcpy( + timeBuffer + timeBufferBufSize * c, + timeBuffer + timeBufferBufSize * c + hSbrEncoder->frameSize, + sizeof(INT_PCM) * hSbrEncoder->bufferOffset / hSbrEncoder->nChannels); + } + } + if (hSbrEncoder->nBitstrDelay > 0) { + int el; + + for (el = 0; el < hSbrEncoder->noElements; el++) { + FDKmemmove( + hSbrEncoder->sbrElement[el]->payloadDelayLine[0], + hSbrEncoder->sbrElement[el]->payloadDelayLine[1], + sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay * MAX_PAYLOAD_SIZE)); + + FDKmemmove(&hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0], + &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1], + sizeof(UINT) * (hSbrEncoder->nBitstrDelay)); + } + } return 0; } +INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder) { + INT error = -1; + if (hSbrEncoder) { + int el; + for (el = 0; el < hSbrEncoder->noElements; el++) { + if ((hSbrEncoder->noElements == 1) && + (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { + hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = + hSbrEncoder->sbrElement[el]->sbrBitstreamData.NrSendHeaderData - 1; + } else { + hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = 0; + } + } + error = 0; + } + return error; +} -INT sbrEncoder_UpdateBuffers( - HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *timeBuffer - ) - { - if ( hSbrEncoder->downsampledOffset > 0 ) { - /* Move delayed downsampled data */ - FDKmemcpy ( timeBuffer, - timeBuffer + hSbrEncoder->downmixSize, - sizeof(INT_PCM) * (hSbrEncoder->downsampledOffset) ); - } else { - /* Move delayed input data */ - FDKmemcpy ( timeBuffer, - timeBuffer + hSbrEncoder->nChannels * hSbrEncoder->frameSize, - sizeof(INT_PCM) * hSbrEncoder->bufferOffset ); +INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder) { + INT sbrHeader = 1; + if (hSbrEncoder) { + int el; + for (el = 0; el < hSbrEncoder->noElements; el++) { + sbrHeader &= + (hSbrEncoder->sbrElement[el]->sbrBitstreamData.HeaderActiveDelay == 1) + ? 1 + : 0; } - if ( hSbrEncoder->nBitstrDelay > 0 ) - { - int el; + } + return sbrHeader; +} - for (el=0; el<hSbrEncoder->noElements; el++) - { - FDKmemmove ( hSbrEncoder->sbrElement[el]->payloadDelayLine[0], - hSbrEncoder->sbrElement[el]->payloadDelayLine[1], - sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay*MAX_PAYLOAD_SIZE) ); +INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder) { + INT delay = -1; - FDKmemmove( &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0], - &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1], - sizeof(UINT) * (hSbrEncoder->nBitstrDelay) ); - } + if (hSbrEncoder) { + if ((hSbrEncoder->noElements == 1) && + (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { + delay = hSbrEncoder->nBitstrDelay + 1; + } else { + delay = hSbrEncoder->nBitstrDelay; } - return 0; - } + } + return delay; +} +INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder) { + INT delay = -1; + if (hSbrEncoder) { + delay = hSbrEncoder->nBitstrDelay; + } + return delay; +} -INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) -{ +INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder) { + INT error = -1; + if (hSbrEncoder) { + int el; + for (el = 0; el < hSbrEncoder->noElements; el++) { + hSbrEncoder->sbrElement[el]->sbrBitstreamData.rightBorderFIX = 1; + } + error = 0; + } + return error; +} + +INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) { INT estimateBitrate = 0; - if(hSbrEncoder) { + if (hSbrEncoder) { estimateBitrate += hSbrEncoder->estimateBitrate; } return estimateBitrate; } -INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) -{ +INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) { INT delay = -1; - if(hSbrEncoder) { + if (hSbrEncoder) { delay = hSbrEncoder->inputDataDelay; } return delay; } +INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder) { + INT delay = -1; -INT sbrEncoder_GetLibInfo( LIB_INFO *info ) -{ + if (hSbrEncoder) { + delay = hSbrEncoder->sbrDecDelay; + } + return delay; +} + +INT sbrEncoder_GetLibInfo(LIB_INFO *info) { int i; if (info == NULL) { @@ -2421,7 +2557,8 @@ INT sbrEncoder_GetLibInfo( LIB_INFO *info ) info += i; info->module_id = FDK_SBRENC; - info->version = LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); + info->version = + LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); LIB_VERSION_STRING(info); #ifdef __ANDROID__ info->build_date = ""; @@ -2433,10 +2570,7 @@ INT sbrEncoder_GetLibInfo( LIB_INFO *info ) info->title = "SBR Encoder"; /* Set flags */ - info->flags = 0 - | CAPF_SBR_HQ - | CAPF_SBR_PS_MPEG - ; + info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_PS_MPEG; /* End of flags */ return 0; |