aboutsummaryrefslogtreecommitdiffstats
path: root/libSBRdec/src/env_extr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRdec/src/env_extr.cpp')
-rw-r--r--libSBRdec/src/env_extr.cpp2005
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;