| /* ----------------------------------------------------------------------------- |
| Software License for The Fraunhofer FDK AAC Codec Library for Android |
| |
| © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten |
| Forschung e.V. All rights reserved. |
| |
| 1. INTRODUCTION |
| The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software |
| that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding |
| scheme for digital audio. This FDK AAC Codec software is intended to be used on |
| a wide variety of Android devices. |
| |
| AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient |
| general perceptual audio codecs. AAC-ELD is considered the best-performing |
| full-bandwidth communications codec by independent studies and is widely |
| deployed. AAC has been standardized by ISO and IEC as part of the MPEG |
| specifications. |
| |
| Patent licenses for necessary patent claims for the FDK AAC Codec (including |
| those of Fraunhofer) may be obtained through Via Licensing |
| (www.vialicensing.com) or through the respective patent owners individually for |
| the purpose of encoding or decoding bit streams in products that are compliant |
| with the ISO/IEC MPEG audio standards. Please note that most manufacturers of |
| Android devices already license these patent claims through Via Licensing or |
| directly from the patent owners, and therefore FDK AAC Codec software may |
| already be covered under those patent licenses when it is used for those |
| licensed purposes only. |
| |
| Commercially-licensed AAC software libraries, including floating-point versions |
| with enhanced sound quality, are also available from Fraunhofer. Users are |
| encouraged to check the Fraunhofer website for additional applications |
| information and documentation. |
| |
| 2. COPYRIGHT LICENSE |
| |
| Redistribution and use in source and binary forms, with or without modification, |
| are permitted without payment of copyright license fees provided that you |
| satisfy the following conditions: |
| |
| You must retain the complete text of this software license in redistributions of |
| the FDK AAC Codec or your modifications thereto in source code form. |
| |
| You must retain the complete text of this software license in the documentation |
| and/or other materials provided with redistributions of the FDK AAC Codec or |
| your modifications thereto in binary form. You must make available free of |
| charge copies of the complete source code of the FDK AAC Codec and your |
| modifications thereto to recipients of copies in binary form. |
| |
| The name of Fraunhofer may not be used to endorse or promote products derived |
| from this library without prior written permission. |
| |
| You may not charge copyright license fees for anyone to use, copy or distribute |
| the FDK AAC Codec software or your modifications thereto. |
| |
| Your modified versions of the FDK AAC Codec must carry prominent notices stating |
| that you changed the software and the date of any change. For modified versions |
| of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" |
| must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK |
| AAC Codec Library for Android." |
| |
| 3. NO PATENT LICENSE |
| |
| NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without |
| limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. |
| Fraunhofer provides no warranty of patent non-infringement with respect to this |
| software. |
| |
| You may use this FDK AAC Codec software or modifications thereto only for |
| purposes that are authorized by appropriate patent licenses. |
| |
| 4. DISCLAIMER |
| |
| This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright |
| holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, |
| including but not limited to the implied warranties of merchantability and |
| fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, |
| or consequential damages, including but not limited to procurement of substitute |
| goods or services; loss of use, data, or profits, or business interruption, |
| however caused and on any theory of liability, whether in contract, strict |
| liability, or tort (including negligence), arising in any way out of the use of |
| this software, even if advised of the possibility of such damage. |
| |
| 5. CONTACT INFORMATION |
| |
| Fraunhofer Institute for Integrated Circuits IIS |
| Attention: Audio and Multimedia Departments - FDK AAC LL |
| Am Wolfsmantel 33 |
| 91058 Erlangen, Germany |
| |
| www.iis.fraunhofer.de/amm |
| amm-info@iis.fraunhofer.de |
| ----------------------------------------------------------------------------- */ |
| |
| /**************************** 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. |
| |
| 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. |
| |
| 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. |
| |
| \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. |
| |
| 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. |
| |
| \sa \ref documentationOverview |
| */ |
| |
| #include "env_extr.h" |
| |
| #include "sbr_ram.h" |
| #include "sbr_rom.h" |
| #include "huff_dec.h" |
| |
| #include "psbitdec.h" |
| |
| #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; |
| |
| if (!isUsac) { |
| mappingTable = stdSampleRatesMapping; |
| tableSize = sizeof(stdSampleRatesMapping) / sizeof(SR_MAPPING); |
| } else { |
| mappingTable = stdSampleRatesMappingUsac; |
| tableSize = sizeof(stdSampleRatesMappingUsac) / sizeof(SR_MAPPING); |
| } |
| |
| for (i = tableSize - 1; i >= 0; i--) { |
| if (fs >= mappingTable[i].fsRangeLo) { |
| fsMapped = mappingTable[i].fsMapped; |
| break; |
| } |
| } |
| |
| return (fsMapped); |
| } |
| |
| SBR_ERROR |
| 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 (!(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 = sampleRateProc; |
| if ((sampleRateOut >> 1) == sampleRateIn) { |
| /* 1:2 */ |
| numAnalysisBands = 32; |
| } else if ((sampleRateOut >> 2) == sampleRateIn) { |
| /* 1:4 */ |
| numAnalysisBands = 16; |
| } else if ((sampleRateOut * 3) >> 3 == (sampleRateIn * 8) >> 3) { |
| /* 3:8, 3/4 core frame length */ |
| numAnalysisBands = 24; |
| } else { |
| sbrError = SBRDEC_UNSUPPORTED_CONFIG; |
| 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; |
| } |
| } |
| |
| 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[1] = hFreq->freqBandTableHi; |
| |
| /* 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 */ |
| { |
| 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++) |
| h_prev_data->sfb_nrg_prev[i] = (FIXP_DBL)0; |
| 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; |
| |
| 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 |
| |
| \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, |
| const UCHAR configMode) { |
| SBR_HEADER_DATA_BS *pBsData; |
| SBR_HEADER_DATA_BS lastHeader; |
| SBR_HEADER_DATA_BS_INFO lastInfo; |
| 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; |
| |
| /* Read new header from bitstream */ |
| if ((flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) && !fIsSbrData) { |
| pBsData = &hHeaderData->bs_dflt; |
| } else { |
| pBsData = &hHeaderData->bs_data; |
| } |
| |
| 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); |
| |
| 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); |
| |
| /* 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; |
| 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->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) { |
| return HEADER_RESET; /* New settings */ |
| } |
| |
| return HEADER_OK; |
| } |
| |
| /*! |
| \brief Get missing harmonics parameters (only used for AAC+SBR) |
| |
| \return error status - 0 if ok |
| */ |
| int sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData, |
| HANDLE_SBR_FRAME_DATA hFrameData, |
| HANDLE_FDK_BITSTREAM hBs, const UINT flags) { |
| int i, bitsRead = 0; |
| |
| int add_harmonic_flag = 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; |
| } |
| |
| return (bitsRead); |
| } |
| |
| /*! |
| \brief Reads extension data from the bitstream |
| |
| The bitstream format allows up to 4 kinds of extended data element. |
| Extended data may contain several elements, each identified by a 2-bit-ID. |
| So far, no extended data elements are defined hence the first 2 parameters |
| 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 */ |
| ) { |
| INT nBitsLeft; |
| int extended_data; |
| int i, frameOk = 1; |
| |
| extended_data = FDKreadBits(hBs, 1); |
| |
| if (extended_data) { |
| int cnt; |
| int bPsRead = 0; |
| |
| cnt = FDKreadBits(hBs, 4); |
| if (cnt == (1 << 4) - 1) cnt += FDKreadBits(hBs, 8); |
| |
| nBitsLeft = 8 * cnt; |
| |
| /* sanity check for cnt */ |
| if (nBitsLeft > (INT)FDKgetValidBits(hBs)) { |
| /* limit nBitsLeft */ |
| nBitsLeft = (INT)FDKgetValidBits(hBs); |
| /* set frame error */ |
| frameOk = 0; |
| } |
| |
| while (nBitsLeft > 7) { |
| int extension_id = FDKreadBits(hBs, 2); |
| nBitsLeft -= 2; |
| |
| 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 -= |
| (INT)ReadPsData(hParametricStereoDec, hBs, nBitsLeft); |
| bPsRead = 1; |
| } |
| } |
| |
| /* 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; |
| } |
| } |
| |
| if (nBitsLeft < 0) { |
| frameOk = 0; |
| goto bail; |
| } else { |
| /* Read fill bits for byte alignment */ |
| FDKreadBits(hBs, nBitsLeft); |
| } |
| } |
| |
| bail: |
| return (frameOk); |
| } |
| |
| /*! |
| \brief Read bitstream elements of a SBR channel element |
| \return SbrFrameOK |
| */ |
| 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 */ |
| FDKreadBits(hBs, 4); |
| if ((flags & SBRDEC_SYNTAX_SCAL) || (nCh == 2)) { |
| FDKreadBits(hBs, 4); |
| } |
| } |
| } |
| |
| 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; |
| } |
| |
| 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; |
| } |
| |
| 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; |
| } |
| |
| hFrameDataLeft->sbrPatchingMode = 1; |
| hFrameDataLeft->sbrOversamplingFlag = 0; |
| hFrameDataLeft->sbrPitchInBins = 0; |
| } |
| } else { |
| if (nCh == 2) { |
| hFrameDataRight->sbrPatchingMode = 1; |
| hFrameDataRight->sbrOversamplingFlag = 0; |
| hFrameDataRight->sbrPitchInBins = 0; |
| } |
| |
| hFrameDataLeft->sbrPatchingMode = 1; |
| hFrameDataLeft->sbrOversamplingFlag = 0; |
| hFrameDataLeft->sbrPitchInBins = 0; |
| } |
| |
| /* |
| sbr_grid(): Grid control |
| */ |
| 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 (!checkFrameInfo(&hFrameDataLeft->frameInfo, |
| hHeaderData->numberTimeSlots, overlap, |
| hHeaderData->timeStep)) |
| return 0; |
| } else { |
| if (!extractFrameInfo(hBs, hHeaderData, hFrameDataLeft, 1, flags)) return 0; |
| |
| 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; |
| } |
| } |
| |
| /* |
| sbr_dtdf(): Fetch domain vectors (time or frequency direction for |
| delta-coding) |
| */ |
| sbrGetDirectionControlData(hFrameDataLeft, hBs, flags, |
| hHeaderData->bs_info.pvc_mode); |
| if (nCh == 2) { |
| sbrGetDirectionControlData(hFrameDataRight, hBs, flags, 0); |
| } |
| |
| /* 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; |
| |
| sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); |
| } else if (hFrameDataLeft->coupling) { |
| if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) { |
| return 0; |
| } |
| |
| sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); |
| |
| if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) { |
| return 0; |
| } |
| sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); |
| } else { /* nCh == 2 && no coupling */ |
| |
| if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) return 0; |
| |
| if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) return 0; |
| |
| sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); |
| |
| sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); |
| } |
| |
| sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs, flags); |
| if (nCh == 2) { |
| sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs, flags); |
| } |
| |
| if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { |
| if (!extractExtendedData(hHeaderData, hBs, hParametricStereoDec)) { |
| return 0; |
| } |
| } |
| |
| 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 */ |
| const UINT flags, const int bs_pvc_mode) |
| |
| { |
| int i; |
| int indepFlag = 0; |
| |
| if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { |
| indepFlag = flags & SBRDEC_USAC_INDEP; |
| } |
| |
| 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 */ |
| { |
| int i, j; |
| int delta; |
| COUPLING_MODE coupling; |
| int noNoiseBands = hHeaderData->freqBandData.nNfb; |
| |
| Huffman hcb_noiseF; |
| Huffman hcb_noise; |
| int envDataTableCompFactor; |
| |
| 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" |
| */ |
| envDataTableCompFactor = 1; |
| } else { |
| hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T; |
| 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++) { |
| 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); |
| } |
| |
| for (j = 1; j < noNoiseBands; j++) { |
| delta = DecodeHuffmanCW(hcb_noiseF, hBs); |
| h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] = |
| (FIXP_SGL)(delta << envDataTableCompFactor); |
| } |
| } else { |
| for (j = 0; j < noNoiseBands; j++) { |
| delta = DecodeHuffmanCW(hcb_noise, hBs); |
| 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) { |
| int i, j; |
| UCHAR no_band[MAX_ENVELOPES]; |
| int delta = 0; |
| int offset = 0; |
| COUPLING_MODE coupling = h_frame_data->coupling; |
| int ampRes = hHeaderData->bs_info.ampResolution; |
| int nEnvelopes = h_frame_data->frameInfo.nEnvelopes; |
| int envDataTableCompFactor; |
| int start_bits, start_bits_balance; |
| Huffman hcb_t, hcb_f; |
| |
| h_frame_data->nScaleFactors = 0; |
| |
| if ((h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1)) { |
| if (flags & SBRDEC_ELD_GRID) |
| ampRes = h_frame_data->ampResolutionCurrentFrame; |
| else |
| ampRes = 0; |
| } |
| h_frame_data->ampResolutionCurrentFrame = ampRes; |
| |
| /* |
| Set number of bits for first value depending on amplitude resolution |
| */ |
| if (ampRes == 1) { |
| start_bits = 6; |
| start_bits_balance = 5; |
| } else { |
| start_bits = 7; |
| start_bits_balance = 6; |
| } |
| |
| /* |
| 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]]; |
| h_frame_data->nScaleFactors += no_band[i]; |
| } |
| if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) return 0; |
| |
| /* |
| Select Huffman codebook depending on coupling mode and amplitude resolution |
| */ |
| if (coupling == COUPLING_BAL) { |
| envDataTableCompFactor = 1; |
| if (ampRes == 0) { |
| hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10T; |
| hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10F; |
| } else { |
| hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11T; |
| hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; |
| } |
| } else { |
| envDataTableCompFactor = 0; |
| if (ampRes == 0) { |
| hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10T; |
| hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10F; |
| } 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 { |
| h_frame_data->iEnvelope[offset] = |
| (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 { |
| delta = DecodeHuffmanCW(hcb_t, hBs); |
| } |
| |
| 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) */ |
| for (i = 0; i < h_frame_data->nScaleFactors; i++) { |
| h_frame_data->iEnvelope[i] <<= ENV_EXP_FRACT; |
| } |
| #endif |
| |
| return 1; |
| } |
| |
| /***************************************************************************/ |
| /*! |
| \brief Generates frame info for FIXFIXonly frame class used for low delay |
| version |
| |
| \return zero for error, one for correct. |
| ****************************************************************************/ |
| static int 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: |
| return 0; |
| } |
| |
| /* 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; |
| |
| return 1; |
| } |
| |
| /*! |
| \brief Extracts LowDelaySBR control data from the bitstream. |
| |
| \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, 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; |
| |
| /* 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; |
| |
| default: |
| return 0; |
| } |
| |
| /* For "case 15" only*/ |
| if (temp >= timeSlots) { |
| return 0; |
| } |
| |
| /* calculate borders according to the transient position */ |
| if (!generateFixFixOnly(pFrameInfo, temp, numberTimeSlots, flags)) { |
| return 0; |
| } |
| |
| /* 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 PVC frame information (structure FRAME_INFO) from the |
| bitstream \return Zero for bitstream error, one for correct. |
| */ |
| 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 (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. |
| */ |
| |
| FDK_ASSERT((pFrameInfo->nEnvelopes == 1) || (pFrameInfo->nEnvelopes == 2)); |
| |
| /* 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; |
| } |
| |
| /* right timeborder-offset: */ |
| pFrameInfo->borders[pFrameInfo->nEnvelopes] = 16 + pFrameInfo->varLength; |
| |
| if (pFrameInfo->nEnvelopes == 2) { |
| pFrameInfo->borders[1] = pFrameInfo->noisePosition; |
| } |
| |
| /* 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; |
| } |
| if (pFrameInfo->nEnvelopes == 2) { |
| pFrameInfo->pvcBorders[1] = pFrameInfo->borders[1]; |
| } |
| pFrameInfo->pvcBorders[pFrameInfo->nEnvelopes] = 16; |
| |
| /* 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; |
| } |
| |
| /*! |
| \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; |
| |
| 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; |
| } |
| } 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; |
| } |
| |
| 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; |
| } |
| |
| /* 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] */ |
| } |
| |
| /* 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 */ |
| |
| /* 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; |
| |
| /* 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; |
| } |
| |
| break; |
| |
| case 3: |
| /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */ |
| |
| aL = FDKreadBits(hBs, 2); /* AL [2 bits], AL -> aL */ |
| |
| aR = FDKreadBits(hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */ |
| |
| nL = FDKreadBits(hBs, 2); /* nL = NL [2 bits] */ |
| |
| nR = FDKreadBits(hBs, 2); /* nR = NR [2 bits] */ |
| |
| /*------------------------------------------------------------------------- |
| Calculate help variables |
| --------------------------------------------------------------------------*/ |
| |
| /* general: */ |
| nEnv = nL + nR + 1; /* # envelopes */ |
| if (nEnv > MAX_ENVELOPES) return 0; |
| b = nEnv + 1; /* # borders */ |
| |
| /*------------------------------------------------------------------------- |
| Decode envelopes |
| --------------------------------------------------------------------------*/ |
| |
| /* L-borders: */ |
| border = aL; /* first border */ |
| pFrameInfo->borders[0] = border; |
| |
| for (k = 1; k <= nL; k++) { |
| temp = FDKreadBits(hBs, 2); /* R [2 bits] */ |
| border += (2 * temp + 2); /* R -> r */ |
| pFrameInfo->borders[k] = border; |
| } |
| |
| /* 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 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 freq res: */ |
| for (k = 0; k < nEnv; k++) { |
| pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ |
| } |
| |
| /*------------------------------------------------------------------------- |
| 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 |
| */ |
| pFrameInfo->nEnvelopes = nEnv; |
| |
| if (nEnv == 1) |
| pFrameInfo->nNoiseEnvelopes = 1; |
| else |
| pFrameInfo->nNoiseEnvelopes = 2; |
| |
| pFrameInfo->frameClass = frameClass; |
| |
| 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]; |
| } |
| |
| 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 */ |
| { |
| int maxPos, i, j; |
| int startPos; |
| int stopPos; |
| int tranEnv; |
| int startPosNoise; |
| int stopPosNoise; |
| int nEnvelopes = pFrameInfo->nEnvelopes; |
| int nNoiseEnvelopes = pFrameInfo->nNoiseEnvelopes; |
| |
| if (nEnvelopes < 1 || nEnvelopes > MAX_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]; |
| |
| if (overlap < 0 || overlap > (3 * (4))) { |
| return 0; |
| } |
| 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 */ |
| return 0; |
| 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 envelope to be shortened is actually among the envelopes */ |
| if (tranEnv > nEnvelopes) return 0; |
| |
| /* Check the noise borders */ |
| 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]) |
| return 0; |
| } |
| |
| /* Check that every noise border is the same as an envelope border*/ |
| for (i = 0; i < nNoiseEnvelopes; i++) { |
| startPosNoise = pFrameInfo->bordersNoise[i]; |
| |
| for (j = 0; j < nEnvelopes; j++) { |
| if (pFrameInfo->borders[j] == startPosNoise) break; |
| } |
| if (j == nEnvelopes) return 0; |
| } |
| |
| return 1; |
| } |