diff options
Diffstat (limited to 'libSBRdec/src/env_extr.cpp')
-rw-r--r-- | libSBRdec/src/env_extr.cpp | 2005 |
1 files changed, 1166 insertions, 839 deletions
diff --git a/libSBRdec/src/env_extr.cpp b/libSBRdec/src/env_extr.cpp index 4d53a13..e6ae6dc 100644 --- a/libSBRdec/src/env_extr.cpp +++ b/libSBRdec/src/env_extr.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,47 +90,65 @@ Am Wolfsmantel 33 www.iis.fraunhofer.de/amm amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ +----------------------------------------------------------------------------- */ + +/**************************** SBR decoder library ****************************** + + Author(s): + + Description: + +*******************************************************************************/ /*! \file - \brief Envelope extraction - The functions provided by this module are mostly called by applySBR(). After it is - determined that there is valid SBR data, sbrGetHeaderData() might be called if the current - SBR data contains an \ref SBR_HEADER_ELEMENT as opposed to a \ref SBR_STANDARD_ELEMENT. This function - may return various error codes as defined in #SBR_HEADER_STATUS . Most importantly it returns HEADER_RESET when decoder - settings need to be recalculated according to the SBR specifications. In that case applySBR() - will initiatite the required re-configuration. + \brief Envelope extraction + The functions provided by this module are mostly called by applySBR(). After + it is determined that there is valid SBR data, sbrGetHeaderData() might be + called if the current SBR data contains an \ref SBR_HEADER_ELEMENT as opposed + to a \ref SBR_STANDARD_ELEMENT. This function may return various error codes + as defined in #SBR_HEADER_STATUS . Most importantly it returns HEADER_RESET + when decoder settings need to be recalculated according to the SBR + specifications. In that case applySBR() will initiatite the required + re-configuration. The header data is stored in a #SBR_HEADER_DATA structure. - The actual SBR data for the current frame is decoded into SBR_FRAME_DATA stuctures by sbrGetChannelPairElement() - [for stereo streams] and sbrGetSingleChannelElement() [for mono streams]. There is no fractional arithmetic involved. + The actual SBR data for the current frame is decoded into SBR_FRAME_DATA + stuctures by sbrGetChannelPairElement() [for stereo streams] and + sbrGetSingleChannelElement() [for mono streams]. There is no fractional + arithmetic involved. - Once the information is extracted, the data needs to be further prepared before the actual decoding process. - This is done in decodeSbrData(). + Once the information is extracted, the data needs to be further prepared + before the actual decoding process. This is done in decodeSbrData(). \sa Description of buffer management in applySBR(). \ref documentationOverview <h1>About the SBR data format:</h1> - Each frame includes SBR data (side chain information), and can be either the \ref SBR_HEADER_ELEMENT or the \ref SBR_STANDARD_ELEMENT. - Parts of the data can be protected by a CRC checksum. + Each frame includes SBR data (side chain information), and can be either the + \ref SBR_HEADER_ELEMENT or the \ref SBR_STANDARD_ELEMENT. Parts of the data + can be protected by a CRC checksum. \anchor SBR_HEADER_ELEMENT <h2>The SBR_HEADER_ELEMENT</h2> - The SBR_HEADER_ELEMENT can be transmitted with every frame, however, it typically is send every second or so. It contains fundamental - information such as SBR sampling frequency and frequency range as well as control signals that do not require frequent changes. It also - includes the \ref SBR_STANDARD_ELEMENT. + The SBR_HEADER_ELEMENT can be transmitted with every frame, however, it + typically is send every second or so. It contains fundamental information such + as SBR sampling frequency and frequency range as well as control signals that + do not require frequent changes. It also includes the \ref + SBR_STANDARD_ELEMENT. - Depending on the changes between the information in a current SBR_HEADER_ELEMENT and the previous SBR_HEADER_ELEMENT, the SBR decoder might need - to be reset and reconfigured (e.g. new tables need to be calculated). + Depending on the changes between the information in a current + SBR_HEADER_ELEMENT and the previous SBR_HEADER_ELEMENT, the SBR decoder might + need to be reset and reconfigured (e.g. new tables need to be calculated). \anchor SBR_STANDARD_ELEMENT <h2>The SBR_STANDARD_ELEMENT</h2> - This data can be subdivided into "side info" and "raw data", where side info is defined as signals needed to decode the raw data - and some decoder tuning signals. Raw data is referred to as PCM and Huffman coded envelope and noise floor estimates. The side info also - includes information about the time-frequency grid for the current frame. + This data can be subdivided into "side info" and "raw data", where side info + is defined as signals needed to decode the raw data and some decoder tuning + signals. Raw data is referred to as PCM and Huffman coded envelope and noise + floor estimates. The side info also includes information about the + time-frequency grid for the current frame. \sa \ref documentationOverview */ @@ -130,60 +159,115 @@ amm-info@iis.fraunhofer.de #include "sbr_rom.h" #include "huff_dec.h" - #include "psbitdec.h" -#define DRM_PARAMETRIC_STEREO 0 -#define EXTENSION_ID_PS_CODING 2 - - -static int extractFrameInfo (HANDLE_FDK_BITSTREAM hBs, - HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - const UINT nrOfChannels, - const UINT flags - ); - - -static int sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - HANDLE_FDK_BITSTREAM hBs, - const UINT flags); +#define DRM_PARAMETRIC_STEREO 0 +#define EXTENSION_ID_PS_CODING 2 + +static int extractPvcFrameInfo( + HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the + frame-info will be stored */ + HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where + the previous frame-info + will be stored */ + UCHAR pvc_mode_last, /**< PVC mode of last frame */ + const UINT flags); +static int extractFrameInfo(HANDLE_FDK_BITSTREAM hBs, + HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA h_frame_data, + const UINT nrOfChannels, const UINT flags); + +static int sbrGetPvcEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA h_frame_data, + HANDLE_FDK_BITSTREAM hBs, const UINT flags, + const UINT pvcMode); +static int sbrGetEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA h_frame_data, + HANDLE_FDK_BITSTREAM hBs, const UINT flags); + +static void sbrGetDirectionControlData(HANDLE_SBR_FRAME_DATA hFrameData, + HANDLE_FDK_BITSTREAM hBs, + const UINT flags, const int bs_pvc_mode); + +static void sbrGetNoiseFloorData(HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA h_frame_data, + HANDLE_FDK_BITSTREAM hBs); + +static int checkFrameInfo(FRAME_INFO *pFrameInfo, int numberOfTimeSlots, + int overlap, int timeStep); + +/* Mapping to std samplerate table according to 14496-3 (4.6.18.2.6) */ +typedef struct SR_MAPPING { + UINT fsRangeLo; /* If fsRangeLo(n+1)>fs>=fsRangeLo(n), it will be mapped to... + */ + UINT fsMapped; /* fsMapped. */ +} SR_MAPPING; + +static const SR_MAPPING stdSampleRatesMapping[] = { + {0, 8000}, {9391, 11025}, {11502, 12000}, {13856, 16000}, + {18783, 22050}, {23004, 24000}, {27713, 32000}, {37566, 44100}, + {46009, 48000}, {55426, 64000}, {75132, 88200}, {92017, 96000}}; +static const SR_MAPPING stdSampleRatesMappingUsac[] = { + {0, 16000}, {18783, 22050}, {23004, 24000}, {27713, 32000}, + {35777, 40000}, {42000, 44100}, {46009, 48000}, {55426, 64000}, + {75132, 88200}, {92017, 96000}}; + +UINT sbrdec_mapToStdSampleRate(UINT fs, + UINT isUsac) /*!< Output sampling frequency */ +{ + UINT fsMapped = fs, tableSize = 0; + const SR_MAPPING *mappingTable; + int i; -static void sbrGetDirectionControlData (HANDLE_SBR_FRAME_DATA hFrameData, - HANDLE_FDK_BITSTREAM hBs); + if (!isUsac) { + mappingTable = stdSampleRatesMapping; + tableSize = sizeof(stdSampleRatesMapping) / sizeof(SR_MAPPING); + } else { + mappingTable = stdSampleRatesMappingUsac; + tableSize = sizeof(stdSampleRatesMappingUsac) / sizeof(SR_MAPPING); + } -static void sbrGetNoiseFloorData (HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - HANDLE_FDK_BITSTREAM hBs); + for (i = tableSize - 1; i >= 0; i--) { + if (fs >= mappingTable[i].fsRangeLo) { + fsMapped = mappingTable[i].fsMapped; + break; + } + } -static int checkFrameInfo (FRAME_INFO *pFrameInfo, int numberOfTimeSlots, int overlap, int timeStep); + return (fsMapped); +} SBR_ERROR -initHeaderData ( - HANDLE_SBR_HEADER_DATA hHeaderData, - const int sampleRateIn, - const int sampleRateOut, - const int samplesPerFrame, - const UINT flags - ) -{ +initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn, + const int sampleRateOut, const INT downscaleFactor, + const int samplesPerFrame, const UINT flags, + const int setDefaultHdr) { HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; SBR_ERROR sbrError = SBRDEC_OK; int numAnalysisBands; + int sampleRateProc; - if ( sampleRateIn == sampleRateOut ) { - hHeaderData->sbrProcSmplRate = sampleRateOut<<1; + if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { + sampleRateProc = + sbrdec_mapToStdSampleRate(sampleRateOut * downscaleFactor, 0); + } else { + sampleRateProc = sampleRateOut * downscaleFactor; + } + + if (sampleRateIn == sampleRateOut) { + hHeaderData->sbrProcSmplRate = sampleRateProc << 1; numAnalysisBands = 32; } else { - hHeaderData->sbrProcSmplRate = sampleRateOut; - if ( (sampleRateOut>>1) == sampleRateIn) { + hHeaderData->sbrProcSmplRate = sampleRateProc; + if ((sampleRateOut >> 1) == sampleRateIn) { /* 1:2 */ numAnalysisBands = 32; - } else if ( (sampleRateOut>>2) == sampleRateIn ) { + } else if ((sampleRateOut >> 2) == sampleRateIn) { /* 1:4 */ - numAnalysisBands = 32; - } else if ( (sampleRateOut*3)>>3 == (sampleRateIn*8)>>3 ) { + numAnalysisBands = 16; + } else if ((sampleRateOut * 3) >> 3 == (sampleRateIn * 8) >> 3) { /* 3:8, 3/4 core frame length */ numAnalysisBands = 24; } else { @@ -191,74 +275,99 @@ initHeaderData ( goto bail; } } + numAnalysisBands /= downscaleFactor; + + if (setDefaultHdr) { + /* Fill in default values first */ + hHeaderData->syncState = SBR_NOT_INITIALIZED; + hHeaderData->status = 0; + hHeaderData->frameErrorFlag = 0; + + hHeaderData->bs_info.ampResolution = 1; + hHeaderData->bs_info.xover_band = 0; + hHeaderData->bs_info.sbr_preprocessing = 0; + hHeaderData->bs_info.pvc_mode = 0; + + hHeaderData->bs_data.startFreq = 5; + hHeaderData->bs_data.stopFreq = 0; + hHeaderData->bs_data.freqScale = + 0; /* previously 2; for ELD reduced delay bitstreams + /samplerates initializing of the sbr decoder instance fails if + freqScale is set to 2 because no master table can be generated; in + ELD reduced delay bitstreams this value is always 0; gets overwritten + when header is read */ + hHeaderData->bs_data.alterScale = 1; + hHeaderData->bs_data.noise_bands = 2; + hHeaderData->bs_data.limiterBands = 2; + hHeaderData->bs_data.limiterGains = 2; + hHeaderData->bs_data.interpolFreq = 1; + hHeaderData->bs_data.smoothingLength = 1; + + /* Patch some entries */ + if (sampleRateOut * downscaleFactor >= 96000) { + hHeaderData->bs_data.startFreq = + 4; /* having read these frequency values from bit stream before. */ + hHeaderData->bs_data.stopFreq = 3; + } else if (sampleRateOut * downscaleFactor > + 24000) { /* Trigger an error if SBR is going to be processed + without */ + hHeaderData->bs_data.startFreq = + 7; /* having read these frequency values from bit stream before. */ + hHeaderData->bs_data.stopFreq = 3; + } + } - /* Fill in default values first */ - hHeaderData->syncState = SBR_NOT_INITIALIZED; - hHeaderData->status = 0; - hHeaderData->frameErrorFlag = 0; - - hHeaderData->bs_info.ampResolution = 1; - hHeaderData->bs_info.xover_band = 0; - hHeaderData->bs_info.sbr_preprocessing = 0; - - hHeaderData->bs_data.startFreq = 5; - hHeaderData->bs_data.stopFreq = 0; - hHeaderData->bs_data.freqScale = 2; - hHeaderData->bs_data.alterScale = 1; - hHeaderData->bs_data.noise_bands = 2; - hHeaderData->bs_data.limiterBands = 2; - hHeaderData->bs_data.limiterGains = 2; - hHeaderData->bs_data.interpolFreq = 1; - hHeaderData->bs_data.smoothingLength = 1; - - hHeaderData->timeStep = (flags & SBRDEC_ELD_GRID) ? 1 : 2; + if ((sampleRateOut >> 2) == sampleRateIn) { + hHeaderData->timeStep = 4; + } else { + hHeaderData->timeStep = (flags & SBRDEC_ELD_GRID) ? 1 : 2; + } /* Setup pointers to frequency band tables */ - hFreq->freqBandTable[0] = hFreq->freqBandTableLo; + hFreq->freqBandTable[0] = hFreq->freqBandTableLo; hFreq->freqBandTable[1] = hFreq->freqBandTableHi; - /* Patch some entries */ - if (sampleRateOut > 24000) { /* Trigger an error if SBR is going to be processed without */ - hHeaderData->bs_data.startFreq = 7; /* having read these frequency values from bit stream before. */ - hHeaderData->bs_data.stopFreq = 3; - } - - /* One SBR timeslot corresponds to the amount of samples equal to the amount of analysis bands, divided by the timestep. */ - hHeaderData->numberTimeSlots = (samplesPerFrame/numAnalysisBands) >> (hHeaderData->timeStep - 1); + /* One SBR timeslot corresponds to the amount of samples equal to the amount + * of analysis bands, divided by the timestep. */ + hHeaderData->numberTimeSlots = + (samplesPerFrame / numAnalysisBands) >> (hHeaderData->timeStep - 1); if (hHeaderData->numberTimeSlots > (16)) { sbrError = SBRDEC_UNSUPPORTED_CONFIG; } hHeaderData->numberOfAnalysisBands = numAnalysisBands; + if ((sampleRateOut >> 2) == sampleRateIn) { + hHeaderData->numberTimeSlots <<= 1; + } bail: return sbrError; } - /*! \brief Initialize the SBR_PREV_FRAME_DATA struct */ -void -initSbrPrevFrameData (HANDLE_SBR_PREV_FRAME_DATA h_prev_data, /*!< handle to struct SBR_PREV_FRAME_DATA */ - int timeSlots) /*!< Framelength in SBR-timeslots */ +void initSbrPrevFrameData( + HANDLE_SBR_PREV_FRAME_DATA + h_prev_data, /*!< handle to struct SBR_PREV_FRAME_DATA */ + int timeSlots) /*!< Framelength in SBR-timeslots */ { int i; /* Set previous energy and noise levels to 0 for the case that decoding starts in the middle of a bitstream */ - for (i=0; i < MAX_FREQ_COEFFS; i++) + for (i = 0; i < MAX_FREQ_COEFFS; i++) h_prev_data->sfb_nrg_prev[i] = (FIXP_DBL)0; - for (i=0; i < MAX_NOISE_COEFFS; i++) + for (i = 0; i < MAX_NOISE_COEFFS; i++) h_prev_data->prevNoiseLevel[i] = (FIXP_DBL)0; - for (i=0; i < MAX_INVF_BANDS; i++) - h_prev_data->sbr_invf_mode[i] = INVF_OFF; + for (i = 0; i < MAX_INVF_BANDS; i++) h_prev_data->sbr_invf_mode[i] = INVF_OFF; h_prev_data->stopPos = timeSlots; h_prev_data->coupling = COUPLING_OFF; h_prev_data->ampRes = 0; -} + FDKmemclear(&h_prev_data->prevFrameInfo, sizeof(h_prev_data->prevFrameInfo)); +} /*! \brief Read header data from bitstream @@ -266,74 +375,92 @@ initSbrPrevFrameData (HANDLE_SBR_PREV_FRAME_DATA h_prev_data, /*!< handle to str \return error status - 0 if ok */ SBR_HEADER_STATUS -sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_FDK_BITSTREAM hBs, - const UINT flags, - const int fIsSbrData) -{ +sbrGetHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_FDK_BITSTREAM hBs, + const UINT flags, const int fIsSbrData, + const UCHAR configMode) { SBR_HEADER_DATA_BS *pBsData; SBR_HEADER_DATA_BS lastHeader; SBR_HEADER_DATA_BS_INFO lastInfo; - int headerExtra1=0, headerExtra2=0; + int headerExtra1 = 0, headerExtra2 = 0; + + /* Read and discard new header in config change detection mode */ + if (configMode & AC_CM_DET_CFG_CHANGE) { + if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { + /* ampResolution */ + FDKreadBits(hBs, 1); + } + /* startFreq, stopFreq */ + FDKpushFor(hBs, 8); + if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { + /* xover_band */ + FDKreadBits(hBs, 3); + /* reserved bits */ + FDKreadBits(hBs, 2); + } + headerExtra1 = FDKreadBit(hBs); + headerExtra2 = FDKreadBit(hBs); + FDKpushFor(hBs, 5 * headerExtra1 + 6 * headerExtra2); + + return HEADER_OK; + } /* Copy SBR bit stream header to temporary header */ lastHeader = hHeaderData->bs_data; - lastInfo = hHeaderData->bs_info; + lastInfo = hHeaderData->bs_info; /* Read new header from bitstream */ - { + if ((flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) && !fIsSbrData) { + pBsData = &hHeaderData->bs_dflt; + } else { pBsData = &hHeaderData->bs_data; } - { - hHeaderData->bs_info.ampResolution = FDKreadBits (hBs, 1); + if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { + hHeaderData->bs_info.ampResolution = FDKreadBits(hBs, 1); } - pBsData->startFreq = FDKreadBits (hBs, 4); - pBsData->stopFreq = FDKreadBits (hBs, 4); + pBsData->startFreq = FDKreadBits(hBs, 4); + pBsData->stopFreq = FDKreadBits(hBs, 4); - { - hHeaderData->bs_info.xover_band = FDKreadBits (hBs, 3); - FDKreadBits (hBs, 2); + if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { + hHeaderData->bs_info.xover_band = FDKreadBits(hBs, 3); + FDKreadBits(hBs, 2); } - headerExtra1 = FDKreadBits (hBs, 1); - headerExtra2 = FDKreadBits (hBs, 1); + headerExtra1 = FDKreadBits(hBs, 1); + headerExtra2 = FDKreadBits(hBs, 1); /* Handle extra header information */ - if( headerExtra1) - { - pBsData->freqScale = FDKreadBits (hBs, 2); - pBsData->alterScale = FDKreadBits (hBs, 1); - pBsData->noise_bands = FDKreadBits (hBs, 2); - } - else { - pBsData->freqScale = 2; - pBsData->alterScale = 1; + if (headerExtra1) { + pBsData->freqScale = FDKreadBits(hBs, 2); + pBsData->alterScale = FDKreadBits(hBs, 1); + pBsData->noise_bands = FDKreadBits(hBs, 2); + } else { + pBsData->freqScale = 2; + pBsData->alterScale = 1; pBsData->noise_bands = 2; } if (headerExtra2) { - pBsData->limiterBands = FDKreadBits (hBs, 2); - pBsData->limiterGains = FDKreadBits (hBs, 2); - pBsData->interpolFreq = FDKreadBits (hBs, 1); - pBsData->smoothingLength = FDKreadBits (hBs, 1); - } - else { - pBsData->limiterBands = 2; - pBsData->limiterGains = 2; - pBsData->interpolFreq = 1; + pBsData->limiterBands = FDKreadBits(hBs, 2); + pBsData->limiterGains = FDKreadBits(hBs, 2); + pBsData->interpolFreq = FDKreadBits(hBs, 1); + pBsData->smoothingLength = FDKreadBits(hBs, 1); + } else { + pBsData->limiterBands = 2; + pBsData->limiterGains = 2; + pBsData->interpolFreq = 1; pBsData->smoothingLength = 1; } /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */ - if(hHeaderData->syncState < SBR_HEADER || - lastHeader.startFreq != pBsData->startFreq || - lastHeader.stopFreq != pBsData->stopFreq || - lastHeader.freqScale != pBsData->freqScale || - lastHeader.alterScale != pBsData->alterScale || - lastHeader.noise_bands != pBsData->noise_bands || - lastInfo.xover_band != hHeaderData->bs_info.xover_band) { + if (hHeaderData->syncState < SBR_HEADER || + lastHeader.startFreq != pBsData->startFreq || + lastHeader.stopFreq != pBsData->stopFreq || + lastHeader.freqScale != pBsData->freqScale || + lastHeader.alterScale != pBsData->alterScale || + lastHeader.noise_bands != pBsData->noise_bands || + lastInfo.xover_band != hHeaderData->bs_info.xover_band) { return HEADER_RESET; /* New settings */ } @@ -345,27 +472,45 @@ sbrGetHeaderData (HANDLE_SBR_HEADER_DATA hHeaderData, \return error status - 0 if ok */ -int -sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA hFrameData, - HANDLE_FDK_BITSTREAM hBs) -{ +int sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA hFrameData, + HANDLE_FDK_BITSTREAM hBs, const UINT flags) { int i, bitsRead = 0; - int flag = FDKreadBits(hBs,1); + int add_harmonic_flag = FDKreadBits(hBs, 1); bitsRead++; - if(flag){ - for(i=0;i<hHeaderData->freqBandData.nSfb[1];i++){ - hFrameData->addHarmonics[i] = FDKreadBits (hBs, 1 ); - bitsRead++; + if (add_harmonic_flag) { + int nSfb = hHeaderData->freqBandData.nSfb[1]; + for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) { + /* read maximum 32 bits and align them to the MSB */ + int readBits = fMin(32, nSfb); + nSfb -= readBits; + if (readBits > 0) { + hFrameData->addHarmonics[i] = FDKreadBits(hBs, readBits) + << (32 - readBits); + } else { + hFrameData->addHarmonics[i] = 0; + } + + bitsRead += readBits; } + /* bs_pvc_mode = 0 for Rsvd50 */ + if (flags & SBRDEC_SYNTAX_USAC) { + if (hHeaderData->bs_info.pvc_mode) { + int bs_sinusoidal_position = 31; + if (FDKreadBit(hBs) /* bs_sinusoidal_position_flag */) { + bs_sinusoidal_position = FDKreadBits(hBs, 5); + } + hFrameData->sinusoidal_position = bs_sinusoidal_position; + } + } + } else { + for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) + hFrameData->addHarmonics[i] = 0; } - else { - for(i=0; i<MAX_FREQ_COEFFS; i++) - hFrameData->addHarmonics[i] = 0; - } - return(bitsRead); + + return (bitsRead); } /*! @@ -377,16 +522,16 @@ sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData, are unused. The data should be skipped in order to update the number of read bits for the consistency check in applySBR(). */ -static int extractExtendedData( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< handle to SBR header */ - HANDLE_FDK_BITSTREAM hBs /*!< Handle to the bit buffer */ - ,HANDLE_PS_DEC hParametricStereoDec /*!< Parametric Stereo Decoder */ - ) { +static int extractExtendedData( + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< handle to SBR header */ + HANDLE_FDK_BITSTREAM hBs /*!< Handle to the bit buffer */ + , + HANDLE_PS_DEC hParametricStereoDec /*!< Parametric Stereo Decoder */ +) { INT nBitsLeft; int extended_data; int i, frameOk = 1; - extended_data = FDKreadBits(hBs, 1); if (extended_data) { @@ -394,9 +539,7 @@ static int extractExtendedData( int bPsRead = 0; cnt = FDKreadBits(hBs, 4); - if (cnt == (1<<4)-1) - cnt += FDKreadBits(hBs, 8); - + if (cnt == (1 << 4) - 1) cnt += FDKreadBits(hBs, 8); nBitsLeft = 8 * cnt; @@ -412,52 +555,52 @@ static int extractExtendedData( int extension_id = FDKreadBits(hBs, 2); nBitsLeft -= 2; - switch(extension_id) { - - - + switch (extension_id) { case EXTENSION_ID_PS_CODING: - /* Read PS data from bitstream */ - - if (hParametricStereoDec != NULL) { - if(bPsRead && !hParametricStereoDec->bsData[hParametricStereoDec->bsReadSlot].mpeg.bPsHeaderValid) { - cnt = nBitsLeft >> 3; /* number of remaining bytes */ - for (i=0; i<cnt; i++) - FDKreadBits(hBs, 8); - nBitsLeft -= cnt * 8; - } else { - nBitsLeft -= ReadPsData(hParametricStereoDec, hBs, nBitsLeft); - bPsRead = 1; + /* Read PS data from bitstream */ + + if (hParametricStereoDec != NULL) { + if (bPsRead && + !hParametricStereoDec->bsData[hParametricStereoDec->bsReadSlot] + .mpeg.bPsHeaderValid) { + cnt = nBitsLeft >> 3; /* number of remaining bytes */ + for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8); + nBitsLeft -= cnt * 8; + } else { + nBitsLeft -= + (INT)ReadPsData(hParametricStereoDec, hBs, nBitsLeft); + bPsRead = 1; + } } - } - /* parametric stereo detected, could set channelMode accordingly here */ + /* parametric stereo detected, could set channelMode accordingly here + */ /* */ - /* "The usage of this parametric stereo extension to HE-AAC is */ - /* signalled implicitly in the bitstream. Hence, if an sbr_extension() */ - /* with bs_extension_id==EXTENSION_ID_PS is found in the SBR part of */ - /* the bitstream, a decoder supporting the combination of SBR and PS */ - /* shall operate the PS tool to generate a stereo output signal." */ - /* source: ISO/IEC 14496-3:2001/FDAM 2:2004(E) */ - - break; - - - default: - cnt = nBitsLeft >> 3; /* number of remaining bytes */ - for (i=0; i<cnt; i++) - FDKreadBits(hBs, 8); - nBitsLeft -= cnt * 8; - break; + /* "The usage of this parametric stereo extension to HE-AAC is */ + /* signalled implicitly in the bitstream. Hence, if an sbr_extension() + */ + /* with bs_extension_id==EXTENSION_ID_PS is found in the SBR part of + */ + /* the bitstream, a decoder supporting the combination of SBR and PS + */ + /* shall operate the PS tool to generate a stereo output signal." */ + /* source: ISO/IEC 14496-3:2001/FDAM 2:2004(E) */ + + break; + + default: + cnt = nBitsLeft >> 3; /* number of remaining bytes */ + for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8); + nBitsLeft -= cnt * 8; + break; } } if (nBitsLeft < 0) { frameOk = 0; goto bail; - } - else { + } else { /* Read fill bits for byte alignment */ FDKreadBits(hBs, nBitsLeft); } @@ -467,196 +610,208 @@ bail: return (frameOk); } - /*! - \brief Read bitstream elements of one channel - - \return SbrFrameOK: 1=ok, 0=error + \brief Read bitstream elements of a SBR channel element + \return SbrFrameOK */ -int -sbrGetSingleChannelElement (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ - HANDLE_FDK_BITSTREAM hBs, /*!< Handle to struct BIT_BUF */ - HANDLE_PS_DEC hParametricStereoDec, /*!< Handle to PS decoder */ - const UINT flags, - const int overlap - ) -{ - int i; - - - hFrameData->coupling = COUPLING_OFF; - - { +int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA hFrameDataLeft, + HANDLE_SBR_FRAME_DATA hFrameDataRight, + HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev, + UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBs, + HANDLE_PS_DEC hParametricStereoDec, const UINT flags, + const int overlap) { + int i, bs_coupling = COUPLING_OFF; + const int nCh = (hFrameDataRight == NULL) ? 1 : 2; + + if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { /* Reserved bits */ - if (FDKreadBits(hBs, 1)) { /* bs_data_extra */ + if (FDKreadBits(hBs, 1)) { /* bs_data_extra */ FDKreadBits(hBs, 4); - if (flags & SBRDEC_SYNTAX_SCAL) { + if ((flags & SBRDEC_SYNTAX_SCAL) || (nCh == 2)) { FDKreadBits(hBs, 4); } } } - if (flags & SBRDEC_SYNTAX_SCAL) { - FDKreadBits (hBs, 1); /* bs_coupling */ - } - - /* - Grid control - */ - if ( !extractFrameInfo ( hBs, hHeaderData, hFrameData, 1, flags) ) - return 0; - - if ( !checkFrameInfo (&hFrameData->frameInfo, hHeaderData->numberTimeSlots, overlap, hHeaderData->timeStep) ) - return 0; - - - /* - Fetch domain vectors (time or frequency direction for delta-coding) - */ - sbrGetDirectionControlData (hFrameData, hBs); - - for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) { - hFrameData->sbr_invf_mode[i] = - (INVF_MODE) FDKreadBits (hBs, 2); - } - - - - /* raw data */ - if ( !sbrGetEnvelope (hHeaderData, hFrameData, hBs, flags) ) - return 0; - - - sbrGetNoiseFloorData (hHeaderData, hFrameData, hBs); - - sbrGetSyntheticCodedData(hHeaderData, hFrameData, hBs); - - { - /* sbr extended data */ - if (! extractExtendedData( - hHeaderData, - hBs - ,hParametricStereoDec - )) { - return 0; + if (nCh == 2) { + /* Read coupling flag */ + bs_coupling = FDKreadBits(hBs, 1); + if (bs_coupling) { + hFrameDataLeft->coupling = COUPLING_LEVEL; + hFrameDataRight->coupling = COUPLING_BAL; + } else { + hFrameDataLeft->coupling = COUPLING_OFF; + hFrameDataRight->coupling = COUPLING_OFF; } + } else { + if (flags & SBRDEC_SYNTAX_SCAL) { + FDKreadBits(hBs, 1); /* bs_coupling */ + } + hFrameDataLeft->coupling = COUPLING_OFF; } - return 1; -} - - - -/*! - \brief Read bitstream elements of a channel pair - \return SbrFrameOK -*/ -int -sbrGetChannelPairElement (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA hFrameDataLeft, /*!< Dynamic control data for first channel */ - HANDLE_SBR_FRAME_DATA hFrameDataRight,/*!< Dynamic control data for second channel */ - HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ - const UINT flags, - const int overlap ) -{ - int i, bit; - + if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { + if (flags & SBRDEC_USAC_HARMONICSBR) { + hFrameDataLeft->sbrPatchingMode = FDKreadBit(hBs); + if (hFrameDataLeft->sbrPatchingMode == 0) { + hFrameDataLeft->sbrOversamplingFlag = FDKreadBit(hBs); + if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */ + hFrameDataLeft->sbrPitchInBins = FDKreadBits(hBs, 7); + } else { + hFrameDataLeft->sbrPitchInBins = 0; + } + } else { + hFrameDataLeft->sbrOversamplingFlag = 0; + hFrameDataLeft->sbrPitchInBins = 0; + } - /* Reserved bits */ - if (FDKreadBits(hBs, 1)) { /* bs_data_extra */ - FDKreadBits(hBs, 4); - FDKreadBits(hBs, 4); - } + if (nCh == 2) { + if (bs_coupling) { + hFrameDataRight->sbrPatchingMode = hFrameDataLeft->sbrPatchingMode; + hFrameDataRight->sbrOversamplingFlag = + hFrameDataLeft->sbrOversamplingFlag; + hFrameDataRight->sbrPitchInBins = hFrameDataLeft->sbrPitchInBins; + } else { + hFrameDataRight->sbrPatchingMode = FDKreadBit(hBs); + if (hFrameDataRight->sbrPatchingMode == 0) { + hFrameDataRight->sbrOversamplingFlag = FDKreadBit(hBs); + if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */ + hFrameDataRight->sbrPitchInBins = FDKreadBits(hBs, 7); + } else { + hFrameDataRight->sbrPitchInBins = 0; + } + } else { + hFrameDataRight->sbrOversamplingFlag = 0; + hFrameDataRight->sbrPitchInBins = 0; + } + } + } + } else { + if (nCh == 2) { + hFrameDataRight->sbrPatchingMode = 1; + hFrameDataRight->sbrOversamplingFlag = 0; + hFrameDataRight->sbrPitchInBins = 0; + } - /* Read coupling flag */ - bit = FDKreadBits (hBs, 1); + hFrameDataLeft->sbrPatchingMode = 1; + hFrameDataLeft->sbrOversamplingFlag = 0; + hFrameDataLeft->sbrPitchInBins = 0; + } + } else { + if (nCh == 2) { + hFrameDataRight->sbrPatchingMode = 1; + hFrameDataRight->sbrOversamplingFlag = 0; + hFrameDataRight->sbrPitchInBins = 0; + } - if (bit) { - hFrameDataLeft->coupling = COUPLING_LEVEL; - hFrameDataRight->coupling = COUPLING_BAL; - } - else { - hFrameDataLeft->coupling = COUPLING_OFF; - hFrameDataRight->coupling = COUPLING_OFF; + hFrameDataLeft->sbrPatchingMode = 1; + hFrameDataLeft->sbrOversamplingFlag = 0; + hFrameDataLeft->sbrPitchInBins = 0; } - /* - Grid control + sbr_grid(): Grid control */ - if ( !extractFrameInfo (hBs, hHeaderData, hFrameDataLeft, 2, flags) ) - return 0; - - if ( !checkFrameInfo (&hFrameDataLeft->frameInfo, hHeaderData->numberTimeSlots, overlap, hHeaderData->timeStep) ) - return 0; + if (hHeaderData->bs_info.pvc_mode) { + FDK_ASSERT(nCh == 1); /* PVC not possible for CPE */ + if (!extractPvcFrameInfo(hBs, hHeaderData, hFrameDataLeft, + hFrameDataLeftPrev, pvc_mode_last, flags)) + return 0; - if (hFrameDataLeft->coupling) { - FDKmemcpy (&hFrameDataRight->frameInfo, &hFrameDataLeft->frameInfo, sizeof(FRAME_INFO)); - hFrameDataRight->ampResolutionCurrentFrame = hFrameDataLeft->ampResolutionCurrentFrame; - } - else { - if ( !extractFrameInfo (hBs, hHeaderData, hFrameDataRight, 2, flags) ) + if (!checkFrameInfo(&hFrameDataLeft->frameInfo, + hHeaderData->numberTimeSlots, overlap, + hHeaderData->timeStep)) return 0; + } else { + if (!extractFrameInfo(hBs, hHeaderData, hFrameDataLeft, 1, flags)) return 0; - if ( !checkFrameInfo (&hFrameDataRight->frameInfo, hHeaderData->numberTimeSlots, overlap, hHeaderData->timeStep) ) + if (!checkFrameInfo(&hFrameDataLeft->frameInfo, + hHeaderData->numberTimeSlots, overlap, + hHeaderData->timeStep)) return 0; } + if (nCh == 2) { + if (hFrameDataLeft->coupling) { + FDKmemcpy(&hFrameDataRight->frameInfo, &hFrameDataLeft->frameInfo, + sizeof(FRAME_INFO)); + hFrameDataRight->ampResolutionCurrentFrame = + hFrameDataLeft->ampResolutionCurrentFrame; + } else { + if (!extractFrameInfo(hBs, hHeaderData, hFrameDataRight, 2, flags)) + return 0; + + if (!checkFrameInfo(&hFrameDataRight->frameInfo, + hHeaderData->numberTimeSlots, overlap, + hHeaderData->timeStep)) + return 0; + } + } /* - Fetch domain vectors (time or frequency direction for delta-coding) + sbr_dtdf(): Fetch domain vectors (time or frequency direction for + delta-coding) */ - sbrGetDirectionControlData (hFrameDataLeft, hBs); - sbrGetDirectionControlData (hFrameDataRight, hBs); - - for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE) FDKreadBits (hBs, 2); + sbrGetDirectionControlData(hFrameDataLeft, hBs, flags, + hHeaderData->bs_info.pvc_mode); + if (nCh == 2) { + sbrGetDirectionControlData(hFrameDataRight, hBs, flags, 0); } - if (hFrameDataLeft->coupling) { - for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i]; + /* sbr_invf() */ + for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { + hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2); + } + if (nCh == 2) { + if (hFrameDataLeft->coupling) { + for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { + hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i]; + } + } else { + for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { + hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2); + } } + } + if (nCh == 1) { + if (hHeaderData->bs_info.pvc_mode) { + if (!sbrGetPvcEnvelope(hHeaderData, hFrameDataLeft, hBs, flags, + hHeaderData->bs_info.pvc_mode)) + return 0; + } else if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) + return 0; - if ( !sbrGetEnvelope (hHeaderData, hFrameDataLeft, hBs, flags) ) { + sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); + } else if (hFrameDataLeft->coupling) { + if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) { return 0; } - sbrGetNoiseFloorData (hHeaderData, hFrameDataLeft, hBs); + sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); - if ( !sbrGetEnvelope (hHeaderData, hFrameDataRight, hBs, flags) ) { + if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) { return 0; } - } - else { - - for (i=0; i<hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE) FDKreadBits (hBs, 2); - } - + sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); + } else { /* nCh == 2 && no coupling */ + if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) return 0; - if ( !sbrGetEnvelope (hHeaderData, hFrameDataLeft, hBs, flags) ) - return 0; + if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) return 0; - if ( !sbrGetEnvelope (hHeaderData, hFrameDataRight, hBs, flags) ) - return 0; - - sbrGetNoiseFloorData (hHeaderData, hFrameDataLeft, hBs); + sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); + sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); } - sbrGetNoiseFloorData (hHeaderData, hFrameDataRight, hBs); - sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs); - sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs); + sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs, flags); + if (nCh == 2) { + sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs, flags); + } - { - if (! extractExtendedData( - hHeaderData, - hBs - ,NULL - ) ) { + if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { + if (!extractExtendedData(hHeaderData, hBs, hParametricStereoDec)) { return 0; } } @@ -664,38 +819,50 @@ sbrGetChannelPairElement (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static con return 1; } - - - /*! \brief Read direction control data from bitstream */ -void -sbrGetDirectionControlData (HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs) /*!< handle to struct BIT_BUF */ +void sbrGetDirectionControlData( + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ + const UINT flags, const int bs_pvc_mode) + { int i; + int indepFlag = 0; - for (i = 0; i < h_frame_data->frameInfo.nEnvelopes; i++) { - h_frame_data->domain_vec[i] = FDKreadBits (hBs, 1); + if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { + indepFlag = flags & SBRDEC_USAC_INDEP; } - for (i = 0; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) { - h_frame_data->domain_vec_noise[i] = FDKreadBits (hBs, 1); + if (bs_pvc_mode == 0) { + i = 0; + if (indepFlag) { + h_frame_data->domain_vec[i++] = 0; + } + for (; i < h_frame_data->frameInfo.nEnvelopes; i++) { + h_frame_data->domain_vec[i] = FDKreadBits(hBs, 1); + } } -} - + i = 0; + if (indepFlag) { + h_frame_data->domain_vec_noise[i++] = 0; + } + for (; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) { + h_frame_data->domain_vec_noise[i] = FDKreadBits(hBs, 1); + } +} /*! \brief Read noise-floor-level data from bitstream */ -void -sbrGetNoiseFloorData (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs) /*!< handle to struct BIT_BUF */ +void sbrGetNoiseFloorData( + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ + HANDLE_FDK_BITSTREAM hBs) /*!< handle to struct BIT_BUF */ { - int i,j; + int i, j; int delta; COUPLING_MODE coupling; int noNoiseBands = hHeaderData->freqBandData.nNfb; @@ -706,61 +873,157 @@ sbrGetNoiseFloorData (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control d coupling = h_frame_data->coupling; - /* Select huffman codebook depending on coupling mode */ if (coupling == COUPLING_BAL) { hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T; - hcb_noiseF = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; /* "sbr_huffBook_NoiseBalance11F" */ + hcb_noiseF = + (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; /* "sbr_huffBook_NoiseBalance11F" + */ envDataTableCompFactor = 1; - } - else { + } else { hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T; - hcb_noiseF = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; /* "sbr_huffBook_NoiseLevel11F" */ + hcb_noiseF = + (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; /* "sbr_huffBook_NoiseLevel11F" + */ envDataTableCompFactor = 0; } /* Read raw noise-envelope data */ - for (i=0; i<h_frame_data->frameInfo.nNoiseEnvelopes; i++) { - - + for (i = 0; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) { if (h_frame_data->domain_vec_noise[i] == 0) { if (coupling == COUPLING_BAL) { - h_frame_data->sbrNoiseFloorLevel[i*noNoiseBands] = - (FIXP_SGL) (((int)FDKreadBits (hBs, 5)) << envDataTableCompFactor); - } - else { - h_frame_data->sbrNoiseFloorLevel[i*noNoiseBands] = - (FIXP_SGL) (int)FDKreadBits (hBs, 5); + h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] = + (FIXP_SGL)(((int)FDKreadBits(hBs, 5)) << envDataTableCompFactor); + } else { + h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] = + (FIXP_SGL)(int)FDKreadBits(hBs, 5); } for (j = 1; j < noNoiseBands; j++) { delta = DecodeHuffmanCW(hcb_noiseF, hBs); - h_frame_data->sbrNoiseFloorLevel[i*noNoiseBands+j] = (FIXP_SGL) (delta << envDataTableCompFactor); + h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] = + (FIXP_SGL)(delta << envDataTableCompFactor); } - } - else { + } else { for (j = 0; j < noNoiseBands; j++) { delta = DecodeHuffmanCW(hcb_noise, hBs); - h_frame_data->sbrNoiseFloorLevel[i*noNoiseBands+j] = (FIXP_SGL) (delta << envDataTableCompFactor); + h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] = + (FIXP_SGL)(delta << envDataTableCompFactor); } } } } +/* ns = mapNsMode2ns[pvcMode-1][nsMode] */ +static const UCHAR mapNsMode2ns[2][2] = { + {16, 4}, /* pvcMode = 1 */ + {12, 3} /* pvcMode = 2 */ +}; + +static int sbrGetPvcEnvelope( + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ + const UINT flags, const UINT pvcMode) { + int divMode, nsMode; + int indepFlag = flags & SBRDEC_USAC_INDEP; + UCHAR *pvcID = h_frame_data->pvcID; + + divMode = FDKreadBits(hBs, PVC_DIVMODE_BITS); + nsMode = FDKreadBit(hBs); + FDK_ASSERT((pvcMode == 1) || (pvcMode == 2)); + h_frame_data->ns = mapNsMode2ns[pvcMode - 1][nsMode]; + + if (divMode <= 3) { + int i, k = 1, sum_length = 0, reuse_pcvID; + + /* special treatment for first time slot k=0 */ + indepFlag ? (reuse_pcvID = 0) : (reuse_pcvID = FDKreadBit(hBs)); + if (reuse_pcvID) { + pvcID[0] = hHeaderData->pvcIDprev; + } else { + pvcID[0] = FDKreadBits(hBs, PVC_PVCID_BITS); + } + + /* other time slots k>0 */ + for (i = 0; i < divMode; i++) { + int length, numBits = 4; + if (sum_length >= 13) { + numBits = 1; + } else if (sum_length >= 11) { + numBits = 2; + } else if (sum_length >= 7) { + numBits = 3; + } + + length = FDKreadBits(hBs, numBits); + sum_length += length + 1; + if (sum_length >= PVC_NTIMESLOT) { + return 0; /* parse error */ + } + for (; length--; k++) { + pvcID[k] = pvcID[k - 1]; + } + pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); + } + for (; k < 16; k++) { + pvcID[k] = pvcID[k - 1]; + } + } else { /* divMode >= 4 */ + int num_grid_info, fixed_length, grid_info, j, k = 0; + + divMode -= 4; + num_grid_info = 2 << divMode; + fixed_length = 8 >> divMode; + FDK_ASSERT(num_grid_info * fixed_length == PVC_NTIMESLOT); + + /* special treatment for first time slot k=0 */ + indepFlag ? (grid_info = 1) : (grid_info = FDKreadBit(hBs)); + if (grid_info) { + pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); + } else { + pvcID[k++] = hHeaderData->pvcIDprev; + } + j = fixed_length - 1; + for (; j--; k++) { + pvcID[k] = pvcID[k - 1]; + } + num_grid_info--; + + /* other time slots k>0 */ + for (; num_grid_info--;) { + j = fixed_length; + grid_info = FDKreadBit(hBs); + if (grid_info) { + pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); + j--; + } + for (; j--; k++) { + pvcID[k] = pvcID[k - 1]; + } + } + } + + hHeaderData->pvcIDprev = pvcID[PVC_NTIMESLOT - 1]; + + /* usage of PVC excludes inter-TES tool */ + h_frame_data->iTESactive = (UCHAR)0; + + return 1; +} /*! \brief Read envelope data from bitstream */ -static int -sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ - const UINT flags) -{ +static int sbrGetEnvelope( + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ + HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ + const UINT flags) { int i, j; UCHAR no_band[MAX_ENVELOPES]; int delta = 0; @@ -774,7 +1037,7 @@ sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ h_frame_data->nScaleFactors = 0; - if ( (h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1) ) { + if ((h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1)) { if (flags & SBRDEC_ELD_GRID) ampRes = h_frame_data->ampResolutionCurrentFrame; else @@ -785,13 +1048,10 @@ sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ /* Set number of bits for first value depending on amplitude resolution */ - if(ampRes == 1) - { + if (ampRes == 1) { start_bits = 6; start_bits_balance = 5; - } - else - { + } else { start_bits = 7; start_bits_balance = 6; } @@ -800,11 +1060,11 @@ sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ Calculate number of values for each envelope and alltogether */ for (i = 0; i < nEnvelopes; i++) { - no_band[i] = hHeaderData->freqBandData.nSfb[h_frame_data->frameInfo.freqRes[i]]; + no_band[i] = + hHeaderData->freqBandData.nSfb[h_frame_data->frameInfo.freqRes[i]]; h_frame_data->nScaleFactors += no_band[i]; } - if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) - return 0; + if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) return 0; /* Select Huffman codebook depending on coupling mode and amplitude resolution @@ -814,57 +1074,64 @@ sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ if (ampRes == 0) { hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10T; hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10F; - } - else { + } else { hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11T; hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; } - } - else { + } else { envDataTableCompFactor = 0; if (ampRes == 0) { hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10T; hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10F; - } - else { + } else { hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11T; hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; } } + h_frame_data->iTESactive = (UCHAR)0; /* disable inter-TES by default */ /* Now read raw envelope data */ for (j = 0, offset = 0; j < nEnvelopes; j++) { - - if (h_frame_data->domain_vec[j] == 0) { if (coupling == COUPLING_BAL) { h_frame_data->iEnvelope[offset] = - (FIXP_SGL) (( (int)FDKreadBits(hBs, start_bits_balance)) << envDataTableCompFactor); - } - else { + (FIXP_SGL)(((int)FDKreadBits(hBs, start_bits_balance)) + << envDataTableCompFactor); + } else { h_frame_data->iEnvelope[offset] = - (FIXP_SGL) (int)FDKreadBits (hBs, start_bits); + (FIXP_SGL)(int)FDKreadBits(hBs, start_bits); } } for (i = (1 - h_frame_data->domain_vec[j]); i < no_band[j]; i++) { - if (h_frame_data->domain_vec[j] == 0) { delta = DecodeHuffmanCW(hcb_f, hBs); - } - else { + } else { delta = DecodeHuffmanCW(hcb_t, hBs); } - h_frame_data->iEnvelope[offset + i] = (FIXP_SGL) (delta << envDataTableCompFactor); + h_frame_data->iEnvelope[offset + i] = + (FIXP_SGL)(delta << envDataTableCompFactor); + } + if ((flags & SBRDEC_SYNTAX_USAC) && (flags & SBRDEC_USAC_ITES)) { + int bs_temp_shape = FDKreadBit(hBs); + FDK_ASSERT(j < 8); + h_frame_data->iTESactive |= (UCHAR)(bs_temp_shape << j); + if (bs_temp_shape) { + h_frame_data->interTempShapeMode[j] = + FDKread2Bits(hBs); /* bs_inter_temp_shape_mode */ + } else { + h_frame_data->interTempShapeMode[j] = 0; + } } offset += no_band[j]; } #if ENV_EXP_FRACT - /* Convert from int to scaled fract (ENV_EXP_FRACT bits for the fractional part) */ + /* Convert from int to scaled fract (ENV_EXP_FRACT bits for the fractional + * part) */ for (i = 0; i < h_frame_data->nScaleFactors; i++) { h_frame_data->iEnvelope[i] <<= ENV_EXP_FRACT; } @@ -873,61 +1140,53 @@ sbrGetEnvelope (HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ return 1; } - -//static const FRAME_INFO v_frame_info1_8 = { 0, 1, {0, 8}, {1}, -1, 1, {0, 8} }; -static const FRAME_INFO v_frame_info2_8 = { 0, 2, {0, 4, 8}, {1, 1}, -1, 2, {0, 4, 8} }; -static const FRAME_INFO v_frame_info4_8 = { 0, 4, {0, 2, 4, 6, 8}, {1, 1, 1, 1}, -1, 2, {0, 4, 8} }; - /***************************************************************************/ /*! - \brief Generates frame info for FIXFIXonly frame class used for low delay version + \brief Generates frame info for FIXFIXonly frame class used for low delay + version \return nothing ****************************************************************************/ - static void generateFixFixOnly ( FRAME_INFO *hSbrFrameInfo, - int tranPosInternal, - int numberTimeSlots - ) -{ - int nEnv, i, tranIdx; - const int *pTable; +static void generateFixFixOnly(FRAME_INFO *hSbrFrameInfo, int tranPosInternal, + int numberTimeSlots, const UINT flags) { + int nEnv, i, tranIdx; + const int *pTable; - switch (numberTimeSlots) { - case 8: - pTable = FDK_sbrDecoder_envelopeTable_8[tranPosInternal]; - break; - case 15: - pTable = FDK_sbrDecoder_envelopeTable_15[tranPosInternal]; - break; - case 16: - pTable = FDK_sbrDecoder_envelopeTable_16[tranPosInternal]; - break; - default: - FDK_ASSERT(0); - /* in case assertion checks are disabled, force a definite memory fault at first access */ - pTable = NULL; - break; - } + switch (numberTimeSlots) { + case 8: + pTable = FDK_sbrDecoder_envelopeTable_8[tranPosInternal]; + break; + case 15: + pTable = FDK_sbrDecoder_envelopeTable_15[tranPosInternal]; + break; + default: + FDK_ASSERT(0); + /* fall through */ + case 16: + pTable = FDK_sbrDecoder_envelopeTable_16[tranPosInternal]; + break; + } - /* look number of envelopes in table */ - nEnv = pTable[0]; - /* look up envelope distribution in table */ - for (i=1; i<nEnv; i++) - hSbrFrameInfo->borders[i] = pTable[i+2]; - /* open and close frame border */ - hSbrFrameInfo->borders[0] = 0; - hSbrFrameInfo->borders[nEnv] = numberTimeSlots; - hSbrFrameInfo->nEnvelopes = nEnv; - - /* transient idx */ - tranIdx = hSbrFrameInfo->tranEnv = pTable[1]; - - /* add noise floors */ - hSbrFrameInfo->bordersNoise[0] = 0; - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[tranIdx?tranIdx:1]; - hSbrFrameInfo->bordersNoise[2] = numberTimeSlots; - /* nEnv is always > 1, so nNoiseEnvelopes is always 2 (IEC 14496-3 4.6.19.3.2) */ - hSbrFrameInfo->nNoiseEnvelopes = 2; + /* look number of envelopes in table */ + nEnv = pTable[0]; + /* look up envelope distribution in table */ + for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2]; + /* open and close frame border */ + hSbrFrameInfo->borders[0] = 0; + hSbrFrameInfo->borders[nEnv] = numberTimeSlots; + hSbrFrameInfo->nEnvelopes = nEnv; + + /* transient idx */ + tranIdx = hSbrFrameInfo->tranEnv = pTable[1]; + + /* add noise floors */ + hSbrFrameInfo->bordersNoise[0] = 0; + hSbrFrameInfo->bordersNoise[1] = + hSbrFrameInfo->borders[tranIdx ? tranIdx : 1]; + hSbrFrameInfo->bordersNoise[2] = numberTimeSlots; + /* nEnv is always > 1, so nNoiseEnvelopes is always 2 (IEC 14496-3 4.6.19.3.2) + */ + hSbrFrameInfo->nNoiseEnvelopes = 2; } /*! @@ -935,356 +1194,431 @@ static const FRAME_INFO v_frame_info4_8 = { 0, 4, {0, 2, 4, 6, 8}, {1, 1, 1, 1}, \return zero for bitstream error, one for correct. */ -static int -extractLowDelayGrid (HANDLE_FDK_BITSTREAM hBitBuf, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< contains the FRAME_INFO struct to be filled */ - int timeSlots - ) -{ - FRAME_INFO * pFrameInfo = &h_frame_data->frameInfo; +static int extractLowDelayGrid( + HANDLE_FDK_BITSTREAM hBitBuf, /*!< bitbuffer handle */ + HANDLE_SBR_HEADER_DATA hHeaderData, + HANDLE_SBR_FRAME_DATA + h_frame_data, /*!< contains the FRAME_INFO struct to be filled */ + int timeSlots, const UINT flags) { + FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; INT numberTimeSlots = hHeaderData->numberTimeSlots; INT temp = 0, k; - /* FIXFIXonly framing case */ - h_frame_data->frameInfo.frameClass = 0; + /* FIXFIXonly framing case */ + h_frame_data->frameInfo.frameClass = 0; - /* get the transient position from the bitstream */ - switch (timeSlots){ - case 8: - /* 3bit transient position (temp={0;..;7}) */ - temp = FDKreadBits( hBitBuf, 3); - break; + /* get the transient position from the bitstream */ + switch (timeSlots) { + case 8: + /* 3bit transient position (temp={0;..;7}) */ + temp = FDKreadBits(hBitBuf, 3); + break; - case 16: - case 15: - /* 4bit transient position (temp={0;..;15}) */ - temp = FDKreadBits( hBitBuf, 4); - break; + case 16: + case 15: + /* 4bit transient position (temp={0;..;15}) */ + temp = FDKreadBits(hBitBuf, 4); + break; - default: - return 0; - } + default: + return 0; + } - /* calculate borders according to the transient position */ - generateFixFixOnly ( pFrameInfo, - temp, - numberTimeSlots - ); + /* For "case 15" only*/ + if (temp >= timeSlots) { + return 0; + } - /* decode freq res: */ - for (k = 0; k < pFrameInfo->nEnvelopes; k++) { - pFrameInfo->freqRes[k] = (UCHAR) FDKreadBits (hBitBuf, 1); /* f = F [1 bits] */ - } + /* calculate borders according to the transient position */ + generateFixFixOnly(pFrameInfo, temp, numberTimeSlots, flags); + /* decode freq res: */ + for (k = 0; k < pFrameInfo->nEnvelopes; k++) { + pFrameInfo->freqRes[k] = + (UCHAR)FDKreadBits(hBitBuf, 1); /* f = F [1 bits] */ + } return 1; } /*! - \brief Extract the frame information (structure FRAME_INFO) from the bitstream - \return Zero for bitstream error, one for correct. + \brief Extract the PVC frame information (structure FRAME_INFO) from the + bitstream \return Zero for bitstream error, one for correct. */ -int -extractFrameInfo ( HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the frame-info will be stored */ - const UINT nrOfChannels, - const UINT flags - ) -{ - FRAME_INFO * pFrameInfo = &h_frame_data->frameInfo; - int numberTimeSlots = hHeaderData->numberTimeSlots; - int pointer_bits = 0, nEnv = 0, b = 0, border, i, n = 0, - k, p, aL, aR, nL, nR, - temp = 0, staticFreqRes; - UCHAR frameClass; +int extractPvcFrameInfo( + HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the + frame-info will be stored */ + HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where + the previous frame-info + will be stored */ + UCHAR pvc_mode_last, /**< PVC mode of last frame */ + const UINT flags) { + FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; + FRAME_INFO *pPrevFrameInfo = &h_prev_frame_data->prevFrameInfo; + int bs_var_len_hf, bs_noise_position; + bs_noise_position = FDKreadBits(hBs, 4); /* SBR_PVC_NOISEPOSITION_BITS 4 */ + bs_var_len_hf = FDKreadBit(hBs); + pFrameInfo->noisePosition = bs_noise_position; + pFrameInfo->tranEnv = -1; + + /* Init for bs_noise_position == 0 in case a parse error is found below. */ + pFrameInfo->nEnvelopes = 1; + pFrameInfo->nNoiseEnvelopes = 1; + pFrameInfo->freqRes[0] = 0; + + if (bs_var_len_hf) { /* 1 or 3 Bits */ + pFrameInfo->varLength = FDKreadBits(hBs, 2) + 1; + if (pFrameInfo->varLength > 3) { + pFrameInfo->varLength = + 0; /* assume bs_var_len_hf == 0 in case of error */ + return 0; /* reserved value -> parse error */ + } + } else { + pFrameInfo->varLength = 0; + } - if (flags & SBRDEC_ELD_GRID) { - /* CODEC_AACLD (LD+SBR) only uses the normal 0 Grid for non-transient Frames and the LowDelayGrid for transient Frames */ - frameClass = FDKreadBits (hBs, 1); /* frameClass = [1 bit] */ - if ( frameClass == 1 ) { - /* if frameClass == 1, extract LowDelaySbrGrid, otherwise extract normal SBR-Grid for FIXIFX */ - /* extract the AACLD-Sbr-Grid */ - pFrameInfo->frameClass = frameClass; - extractLowDelayGrid (hBs, hHeaderData, h_frame_data, numberTimeSlots); - return 1; - } - } else - { - frameClass = FDKreadBits (hBs, 2); /* frameClass = C [2 bits] */ + if (bs_noise_position) { + pFrameInfo->nEnvelopes = 2; + pFrameInfo->nNoiseEnvelopes = 2; + FDKmemclear(pFrameInfo->freqRes, sizeof(pFrameInfo->freqRes)); } + /* frame border calculation */ + if (hHeaderData->bs_info.pvc_mode > 0) { + /* See "7.5.1.4 HF adjustment of SBR envelope scalefactors" for reference. + */ - switch (frameClass) { - case 0: - temp = FDKreadBits (hBs, 2); /* E [2 bits ] */ - nEnv = (int) (1 << temp); /* E -> e */ + FDK_ASSERT((pFrameInfo->nEnvelopes == 1) || (pFrameInfo->nEnvelopes == 2)); - if ((flags & SBRDEC_ELD_GRID) && (nEnv == 1)) - h_frame_data->ampResolutionCurrentFrame = FDKreadBits( hBs, 1); /* new ELD Syntax 07-11-09 */ + /* left timeborder-offset: use the timeborder of prev SBR frame */ + if (pPrevFrameInfo->nEnvelopes > 0) { + pFrameInfo->borders[0] = + pPrevFrameInfo->borders[pPrevFrameInfo->nEnvelopes] - PVC_NTIMESLOT; + FDK_ASSERT(pFrameInfo->borders[0] <= 3); + } else { + pFrameInfo->borders[0] = 0; + } - staticFreqRes = FDKreadBits (hBs, 1); + /* right timeborder-offset: */ + pFrameInfo->borders[pFrameInfo->nEnvelopes] = 16 + pFrameInfo->varLength; - { - if (nEnv > MAX_ENVELOPES_HEAAC) - return 0; + if (pFrameInfo->nEnvelopes == 2) { + pFrameInfo->borders[1] = pFrameInfo->noisePosition; } - b = nEnv + 1; - switch (nEnv) { - case 1: - switch (numberTimeSlots) { - case 15: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_15, sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_16, sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 2: - switch (numberTimeSlots) { - case 15: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_15, sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_16, sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 4: - switch (numberTimeSlots) { - case 15: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_15, sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_16, sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 8: -#if (MAX_ENVELOPES >= 8) - switch (numberTimeSlots) { - case 15: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_15, sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy (pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_16, sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; -#else - return 0; -#endif - } - /* Apply correct freqRes (High is default) */ - if (!staticFreqRes) { - for (i = 0; i < nEnv ; i++) - pFrameInfo->freqRes[i] = 0; + /* Calculation of PVC time borders t_EPVC */ + if (pvc_mode_last == 0) { + /* there was a legacy SBR frame before this frame => use bs_var_len' for + * first PVC timeslot */ + pFrameInfo->pvcBorders[0] = pFrameInfo->borders[0]; + } else { + pFrameInfo->pvcBorders[0] = 0; } - - break; - case 1: - case 2: - temp = FDKreadBits (hBs, 2); /* A [2 bits] */ - - n = FDKreadBits (hBs, 2); /* n = N [2 bits] */ - - nEnv = n + 1; /* # envelopes */ - b = nEnv + 1; /* # borders */ - - break; - } - - switch (frameClass) { - case 1: - /* Decode borders: */ - pFrameInfo->borders[0] = 0; /* first border */ - border = temp + numberTimeSlots; /* A -> aR */ - i = b-1; /* frame info index for last border */ - pFrameInfo->borders[i] = border; /* last border */ - - for (k = 0; k < n; k++) { - temp = FDKreadBits (hBs, 2);/* R [2 bits] */ - border -= (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[--i] = border; + if (pFrameInfo->nEnvelopes == 2) { + pFrameInfo->pvcBorders[1] = pFrameInfo->borders[1]; } + pFrameInfo->pvcBorders[pFrameInfo->nEnvelopes] = 16; - - /* Decode pointer: */ - pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n+1)); - p = FDKreadBits (hBs, pointer_bits); /* p = P [pointer_bits bits] */ - - if (p > n+1) - return 0; - - pFrameInfo->tranEnv = p ? n + 2 - p : -1; - - - /* Decode freq res: */ - for (k = n; k >= 0; k--) { - pFrameInfo->freqRes[k] = FDKreadBits (hBs, 1); /* f = F [1 bits] */ + /* calculation of SBR noise-floor time-border vector: */ + for (INT i = 0; i <= pFrameInfo->nNoiseEnvelopes; i++) { + pFrameInfo->bordersNoise[i] = pFrameInfo->borders[i]; } + pFrameInfo->tranEnv = -1; /* tranEnv not used */ + } + return 1; +} - /* Calculate noise floor middle border: */ - if (p == 0 || p == 1) - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; - else - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv]; - - break; - - case 2: - /* Decode borders: */ - border = temp; /* A -> aL */ - pFrameInfo->borders[0] = border; /* first border */ +/*! + \brief Extract the frame information (structure FRAME_INFO) from the + bitstream \return Zero for bitstream error, one for correct. +*/ +int extractFrameInfo( + HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ + HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ + HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the + frame-info will be stored */ + const UINT nrOfChannels, const UINT flags) { + FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; + int numberTimeSlots = hHeaderData->numberTimeSlots; + int pointer_bits = 0, nEnv = 0, b = 0, border, i, n = 0, k, p, aL, aR, nL, nR, + temp = 0, staticFreqRes; + UCHAR frameClass; - for (k = 1; k <= n; k++) { - temp = FDKreadBits (hBs, 2);/* R [2 bits] */ - border += (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[k] = border; + if (flags & SBRDEC_ELD_GRID) { + /* CODEC_AACLD (LD+SBR) only uses the normal 0 Grid for non-transient Frames + * and the LowDelayGrid for transient Frames */ + frameClass = FDKreadBits(hBs, 1); /* frameClass = [1 bit] */ + if (frameClass == 1) { + /* if frameClass == 1, extract LowDelaySbrGrid, otherwise extract normal + * SBR-Grid for FIXIFX */ + /* extract the AACLD-Sbr-Grid */ + pFrameInfo->frameClass = frameClass; + int err = 1; + err = extractLowDelayGrid(hBs, hHeaderData, h_frame_data, numberTimeSlots, + flags); + return err; } - pFrameInfo->borders[k] = numberTimeSlots; /* last border */ - - - /* Decode pointer: */ - pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n+1)); - p = FDKreadBits (hBs, pointer_bits); /* p = P [pointer_bits bits] */ - if (p > n+1) - return 0; - - if (p == 0 || p == 1) - pFrameInfo->tranEnv = -1; - else - pFrameInfo->tranEnv = p - 1; - + } else { + frameClass = FDKreadBits(hBs, 2); /* frameClass = C [2 bits] */ + } + switch (frameClass) { + case 0: + temp = FDKreadBits(hBs, 2); /* E [2 bits ] */ + nEnv = (int)(1 << temp); /* E -> e */ + + if ((flags & SBRDEC_ELD_GRID) && (nEnv == 1)) + h_frame_data->ampResolutionCurrentFrame = + FDKreadBits(hBs, 1); /* new ELD Syntax 07-11-09 */ + + staticFreqRes = FDKreadBits(hBs, 1); + + if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { + if (nEnv > MAX_ENVELOPES_USAC) return 0; + } else + + b = nEnv + 1; + switch (nEnv) { + case 1: + switch (numberTimeSlots) { + case 15: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_15, + sizeof(FRAME_INFO)); + break; + case 16: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_16, + sizeof(FRAME_INFO)); + break; + default: + FDK_ASSERT(0); + } + break; + case 2: + switch (numberTimeSlots) { + case 15: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_15, + sizeof(FRAME_INFO)); + break; + case 16: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_16, + sizeof(FRAME_INFO)); + break; + default: + FDK_ASSERT(0); + } + break; + case 4: + switch (numberTimeSlots) { + case 15: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_15, + sizeof(FRAME_INFO)); + break; + case 16: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_16, + sizeof(FRAME_INFO)); + break; + default: + FDK_ASSERT(0); + } + break; + case 8: +#if (MAX_ENVELOPES >= 8) + switch (numberTimeSlots) { + case 15: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_15, + sizeof(FRAME_INFO)); + break; + case 16: + FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_16, + sizeof(FRAME_INFO)); + break; + default: + FDK_ASSERT(0); + } + break; +#else + return 0; +#endif + } + /* Apply correct freqRes (High is default) */ + if (!staticFreqRes) { + for (i = 0; i < nEnv; i++) pFrameInfo->freqRes[i] = 0; + } - /* Decode freq res: */ - for (k = 0; k <= n; k++) { - pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ - } + break; + case 1: + case 2: + temp = FDKreadBits(hBs, 2); /* A [2 bits] */ + n = FDKreadBits(hBs, 2); /* n = N [2 bits] */ + nEnv = n + 1; /* # envelopes */ + b = nEnv + 1; /* # borders */ - /* Calculate noise floor middle border: */ - switch (p) { - case 0: - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[1]; - break; - case 1: - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; - break; - default: - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv]; break; - } + } - break; + switch (frameClass) { + case 1: + /* Decode borders: */ + pFrameInfo->borders[0] = 0; /* first border */ + border = temp + numberTimeSlots; /* A -> aR */ + i = b - 1; /* frame info index for last border */ + pFrameInfo->borders[i] = border; /* last border */ + + for (k = 0; k < n; k++) { + temp = FDKreadBits(hBs, 2); /* R [2 bits] */ + border -= (2 * temp + 2); /* R -> r */ + pFrameInfo->borders[--i] = border; + } - case 3: - /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */ + /* Decode pointer: */ + pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1)); + p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ - aL = FDKreadBits (hBs, 2); /* AL [2 bits], AL -> aL */ + if (p > n + 1) return 0; - aR = FDKreadBits (hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */ + pFrameInfo->tranEnv = p ? n + 2 - p : -1; - nL = FDKreadBits (hBs, 2); /* nL = NL [2 bits] */ + /* Decode freq res: */ + for (k = n; k >= 0; k--) { + pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ + } - nR = FDKreadBits (hBs, 2); /* nR = NR [2 bits] */ + /* Calculate noise floor middle border: */ + if (p == 0 || p == 1) + pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; + else + pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv]; + break; + case 2: + /* Decode borders: */ + border = temp; /* A -> aL */ + pFrameInfo->borders[0] = border; /* first border */ + + for (k = 1; k <= n; k++) { + temp = FDKreadBits(hBs, 2); /* R [2 bits] */ + border += (2 * temp + 2); /* R -> r */ + pFrameInfo->borders[k] = border; + } + pFrameInfo->borders[k] = numberTimeSlots; /* last border */ - /*------------------------------------------------------------------------- - Calculate help variables - --------------------------------------------------------------------------*/ + /* Decode pointer: */ + pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1)); + p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ + if (p > n + 1) return 0; - /* general: */ - nEnv = nL + nR + 1; /* # envelopes */ - if (nEnv > MAX_ENVELOPES) - return 0; - b = nEnv + 1; /* # borders */ + if (p == 0 || p == 1) + pFrameInfo->tranEnv = -1; + else + pFrameInfo->tranEnv = p - 1; + /* Decode freq res: */ + for (k = 0; k <= n; k++) { + pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ + } + /* Calculate noise floor middle border: */ + switch (p) { + case 0: + pFrameInfo->bordersNoise[1] = pFrameInfo->borders[1]; + break; + case 1: + pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; + break; + default: + pFrameInfo->bordersNoise[1] = + pFrameInfo->borders[pFrameInfo->tranEnv]; + break; + } - /*------------------------------------------------------------------------- - Decode envelopes - --------------------------------------------------------------------------*/ + break; + case 3: + /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */ - /* L-borders: */ - border = aL; /* first border */ - pFrameInfo->borders[0] = border; + aL = FDKreadBits(hBs, 2); /* AL [2 bits], AL -> aL */ - for (k = 1; k <= nL; k++) { - temp = FDKreadBits (hBs, 2);/* R [2 bits] */ - border += (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[k] = border; - } + aR = FDKreadBits(hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */ + nL = FDKreadBits(hBs, 2); /* nL = NL [2 bits] */ - /* R-borders: */ - border = aR; /* last border */ - i = nEnv; + nR = FDKreadBits(hBs, 2); /* nR = NR [2 bits] */ - pFrameInfo->borders[i] = border; + /*------------------------------------------------------------------------- + Calculate help variables + --------------------------------------------------------------------------*/ - for (k = 0; k < nR; k++) { - temp = FDKreadBits (hBs, 2);/* R [2 bits] */ - border -= (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[--i] = border; - } + /* general: */ + nEnv = nL + nR + 1; /* # envelopes */ + if (nEnv > MAX_ENVELOPES) return 0; + b = nEnv + 1; /* # borders */ + /*------------------------------------------------------------------------- + Decode envelopes + --------------------------------------------------------------------------*/ - /* decode pointer: */ - pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(nL+nR+1)); - p = FDKreadBits (hBs, pointer_bits); /* p = P [pointer_bits bits] */ + /* L-borders: */ + border = aL; /* first border */ + pFrameInfo->borders[0] = border; - if (p > nL+nR+1) - return 0; + for (k = 1; k <= nL; k++) { + temp = FDKreadBits(hBs, 2); /* R [2 bits] */ + border += (2 * temp + 2); /* R -> r */ + pFrameInfo->borders[k] = border; + } - pFrameInfo->tranEnv = p ? b - p : -1; + /* R-borders: */ + border = aR; /* last border */ + i = nEnv; + pFrameInfo->borders[i] = border; + for (k = 0; k < nR; k++) { + temp = FDKreadBits(hBs, 2); /* R [2 bits] */ + border -= (2 * temp + 2); /* R -> r */ + pFrameInfo->borders[--i] = border; + } - /* decode freq res: */ - for (k = 0; k < nEnv; k++) { - pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ - } + /* decode pointer: */ + pointer_bits = + DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(nL + nR + 1)); + p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ + if (p > nL + nR + 1) return 0; + pFrameInfo->tranEnv = p ? b - p : -1; - /*------------------------------------------------------------------------- - Decode noise floors - --------------------------------------------------------------------------*/ - pFrameInfo->bordersNoise[0] = aL; + /* decode freq res: */ + for (k = 0; k < nEnv; k++) { + pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ + } - if (nEnv == 1) { - /* 1 noise floor envelope: */ - pFrameInfo->bordersNoise[1] = aR; - } - else { - /* 2 noise floor envelopes */ - if (p == 0 || p == 1) - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[nEnv - 1]; - else - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv]; - pFrameInfo->bordersNoise[2] = aR; - } - break; + /*------------------------------------------------------------------------- + Decode noise floors + --------------------------------------------------------------------------*/ + pFrameInfo->bordersNoise[0] = aL; + + if (nEnv == 1) { + /* 1 noise floor envelope: */ + pFrameInfo->bordersNoise[1] = aR; + } else { + /* 2 noise floor envelopes */ + if (p == 0 || p == 1) + pFrameInfo->bordersNoise[1] = pFrameInfo->borders[nEnv - 1]; + else + pFrameInfo->bordersNoise[1] = + pFrameInfo->borders[pFrameInfo->tranEnv]; + pFrameInfo->bordersNoise[2] = aR; + } + break; } - /* Store number of envelopes, noise floor envelopes and frame class */ @@ -1300,25 +1634,24 @@ extractFrameInfo ( HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ if (pFrameInfo->frameClass == 2 || pFrameInfo->frameClass == 1) { /* calculate noise floor first and last borders: */ pFrameInfo->bordersNoise[0] = pFrameInfo->borders[0]; - pFrameInfo->bordersNoise[pFrameInfo->nNoiseEnvelopes] = pFrameInfo->borders[nEnv]; + pFrameInfo->bordersNoise[pFrameInfo->nNoiseEnvelopes] = + pFrameInfo->borders[nEnv]; } - return 1; } - /*! \brief Check if the frameInfo vector has reasonable values. \return Zero for error, one for correct */ -static int -checkFrameInfo (FRAME_INFO * pFrameInfo, /*!< pointer to frameInfo */ - int numberOfTimeSlots, /*!< QMF time slots per frame */ - int overlap, /*!< Amount of overlap QMF time slots */ - int timeStep) /*!< QMF slots to SBR slots step factor */ +static int checkFrameInfo( + FRAME_INFO *pFrameInfo, /*!< pointer to frameInfo */ + int numberOfTimeSlots, /*!< QMF time slots per frame */ + int overlap, /*!< Amount of overlap QMF time slots */ + int timeStep) /*!< QMF slots to SBR slots step factor */ { - int maxPos,i,j; + int maxPos, i, j; int startPos; int stopPos; int tranEnv; @@ -1327,71 +1660,65 @@ checkFrameInfo (FRAME_INFO * pFrameInfo, /*!< pointer to frameInfo */ int nEnvelopes = pFrameInfo->nEnvelopes; int nNoiseEnvelopes = pFrameInfo->nNoiseEnvelopes; - if(nEnvelopes < 1 || nEnvelopes > MAX_ENVELOPES) - return 0; + if (nEnvelopes < 1 || nEnvelopes > MAX_ENVELOPES) return 0; - if(nNoiseEnvelopes > MAX_NOISE_ENVELOPES) - return 0; + if (nNoiseEnvelopes > MAX_NOISE_ENVELOPES) return 0; - startPos = pFrameInfo->borders[0]; - stopPos = pFrameInfo->borders[nEnvelopes]; - tranEnv = pFrameInfo->tranEnv; - startPosNoise = pFrameInfo->bordersNoise[0]; - stopPosNoise = pFrameInfo->bordersNoise[nNoiseEnvelopes]; + startPos = pFrameInfo->borders[0]; + stopPos = pFrameInfo->borders[nEnvelopes]; + tranEnv = pFrameInfo->tranEnv; + startPosNoise = pFrameInfo->bordersNoise[0]; + stopPosNoise = pFrameInfo->bordersNoise[nNoiseEnvelopes]; - if (overlap < 0 || overlap > (6)) { + if (overlap < 0 || overlap > (3 * (4))) { return 0; } - if (timeStep < 1 || timeStep > 2) { + if (timeStep < 1 || timeStep > (4)) { return 0; } - maxPos = numberOfTimeSlots + (overlap/timeStep); - - /* Check that the start and stop positions of the frame are reasonable values. */ - if( (startPos < 0) || (startPos >= stopPos) ) - return 0; - if( startPos > maxPos-numberOfTimeSlots ) /* First env. must start in or directly after the overlap buffer */ + maxPos = numberOfTimeSlots + (overlap / timeStep); + + /* Check that the start and stop positions of the frame are reasonable values. + */ + if ((startPos < 0) || (startPos >= stopPos)) return 0; + if (startPos > maxPos - numberOfTimeSlots) /* First env. must start in or + directly after the overlap + buffer */ return 0; - if( stopPos < numberOfTimeSlots ) /* One complete frame must be ready for output after processing */ - return 0; - if(stopPos > maxPos) + if (stopPos < numberOfTimeSlots) /* One complete frame must be ready for + output after processing */ return 0; + if (stopPos > maxPos) return 0; - /* Check that the start border for every envelope is strictly later in time */ - for(i=0;i<nEnvelopes;i++) { - if(pFrameInfo->borders[i] >= pFrameInfo->borders[i+1]) - return 0; + /* Check that the start border for every envelope is strictly later in time + */ + for (i = 0; i < nEnvelopes; i++) { + if (pFrameInfo->borders[i] >= pFrameInfo->borders[i + 1]) return 0; } /* Check that the envelope to be shortened is actually among the envelopes */ - if(tranEnv>nEnvelopes) - return 0; - + if (tranEnv > nEnvelopes) return 0; /* Check the noise borders */ - if(nEnvelopes==1 && nNoiseEnvelopes>1) - return 0; - - if(startPos != startPosNoise || stopPos != stopPosNoise) - return 0; + if (nEnvelopes == 1 && nNoiseEnvelopes > 1) return 0; + if (startPos != startPosNoise || stopPos != stopPosNoise) return 0; - /* Check that the start border for every noise-envelope is strictly later in time*/ - for(i=0; i<nNoiseEnvelopes; i++) { - if(pFrameInfo->bordersNoise[i] >= pFrameInfo->bordersNoise[i+1]) + /* Check that the start border for every noise-envelope is strictly later in + * time*/ + for (i = 0; i < nNoiseEnvelopes; i++) { + if (pFrameInfo->bordersNoise[i] >= pFrameInfo->bordersNoise[i + 1]) return 0; } /* Check that every noise border is the same as an envelope border*/ - for(i=0; i<nNoiseEnvelopes; i++) { + for (i = 0; i < nNoiseEnvelopes; i++) { startPosNoise = pFrameInfo->bordersNoise[i]; - for(j=0; j<nEnvelopes; j++) { - if(pFrameInfo->borders[j] == startPosNoise) - break; + for (j = 0; j < nEnvelopes; j++) { + if (pFrameInfo->borders[j] == startPosNoise) break; } - if(j==nEnvelopes) - return 0; + if (j == nEnvelopes) return 0; } return 1; |