summaryrefslogtreecommitdiff
path: root/libSBRenc/src/env_est.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRenc/src/env_est.cpp')
-rw-r--r--libSBRenc/src/env_est.cpp2030
1 files changed, 0 insertions, 2030 deletions
diff --git a/libSBRenc/src/env_est.cpp b/libSBRenc/src/env_est.cpp
deleted file mode 100644
index 4fcda51..0000000
--- a/libSBRenc/src/env_est.cpp
+++ /dev/null
@@ -1,2030 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-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.
-
- 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
------------------------------------------------------------------------------------------------------------ */
-
-#include "env_est.h"
-#include "tran_det.h"
-
-#include "qmf.h"
-
-#include "fram_gen.h"
-#include "bit_sbr.h"
-#include "cmondata.h"
-#include "sbr_ram.h"
-
-
-#include "genericStds.h"
-
-#define QUANT_ERROR_THRES 200
-#define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */
-
-
-static const UCHAR panTable[2][10] = { { 0, 2, 4, 6, 8,12,16,20,24},
- { 0, 2, 4, 8,12, 0, 0, 0, 0 } };
-static const UCHAR maxIndex[2] = {9, 5};
-
-
-/******************************************************************************
- Functionname: FDKsbrEnc_GetTonality
-******************************************************************************/
-/***************************************************************************/
-/*!
-
- \brief Calculates complete energy per band from the energy values
- of the QMF subsamples.
-
- \brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
- \brief noEstPerFrame - number of estimations per frame
- \brief startIndex - start index for the quota matrix
- \brief Energies - energy matrix
- \brief startBand - start band
- \brief stopBand - number of QMF bands
- \brief numberCols - number of QMF subsamples
-
- \return mean tonality of the 5 bands with the highest energy
- scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
-
-****************************************************************************/
-static FIXP_DBL FDKsbrEnc_GetTonality(
- const FIXP_DBL *const *quotaMatrix,
- const INT noEstPerFrame,
- const INT startIndex,
- const FIXP_DBL *const *Energies,
- const UCHAR startBand,
- const INT stopBand,
- const INT numberCols
- )
-{
- UCHAR b, e, k;
- INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = { -1, -1, -1, -1, -1 };
- FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
- FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
- UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
- FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f) };
- FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
- FIXP_DBL energyBand[QMF_CHANNELS];
- INT maxNEnergyValues; /* max. number of max. energy values */
-
- /*** Sum up energies for each band ***/
- FDK_ASSERT(numberCols==15||numberCols==16);
- /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
- energyBands are initialized with the [15]th column.
- The rest of the column energies are added in the next step. */
- if (numberCols==15) {
- for (b=startBand; b<stopBand; b++) {
- energyBand[b]=FL2FXCONST_DBL(0.0f);
- }
- } else {
- for (b=startBand; b<stopBand; b++) {
- energyBand[b]=Energies[15][b]>>4;
- }
- }
-
- for (k=0; k<15; k++) {
- for (b=startBand; b<stopBand; b++) {
- energyBand[b] += Energies[k][b]>>4;
- }
- }
-
- /*** Determine 5 highest band-energies ***/
- maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand-startBand);
-
- /* Get min. value in energyMax array */
- energyMaxMin = energyMax[0] = energyBand[startBand];
- no_enMaxBand[0] = startBand;
- posEnergyMaxMin = 0;
- for (k=1; k<maxNEnergyValues; k++) {
- energyMax[k] = energyBand[startBand+k];
- no_enMaxBand[k] = startBand+k;
- if (energyMaxMin > energyMax[k]) {
- energyMaxMin = energyMax[k];
- posEnergyMaxMin = k;
- }
- }
-
- for (b=startBand+maxNEnergyValues; b<stopBand; b++) {
- if (energyBand[b] > energyMaxMin) {
- energyMax[posEnergyMaxMin] = energyBand[b];
- no_enMaxBand[posEnergyMaxMin] = b;
-
- /* Again, get min. value in energyMax array */
- energyMaxMin = energyMax[0];
- posEnergyMaxMin = 0;
- for (k=1; k<maxNEnergyValues; k++) {
- if (energyMaxMin > energyMax[k]) {
- energyMaxMin = energyMax[k];
- posEnergyMaxMin = k;
- }
- }
- }
- }
- /*** End determine 5 highest band-energies ***/
-
- /* Get tonality values for 5 highest energies */
- for (e=0; e<maxNEnergyValues; e++) {
- tonalityBand[e]=FL2FXCONST_DBL(0.0f);
- for (k=0; k<noEstPerFrame; k++) {
- tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
- }
- globalTonality += tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
- }
-
- return globalTonality;
-}
-
-/***************************************************************************/
-/*!
-
- \brief Calculates energy form real and imaginary part of
- the QMF subsamples
-
- \return none
-
-****************************************************************************/
-LNK_SECTION_CODE_L1
-static void
-FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL **RESTRICT energyValues,/*!< the result of the operation */
- FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
- FIXP_DBL **RESTRICT imagValues, /*!< the imaginary part of the QMF subsamples */
- INT numberBands, /*!< number of QMF bands */
- INT numberCols, /*!< number of QMF subsamples */
- INT *qmfScale, /*!< sclefactor of QMF subsamples */
- INT *energyScale) /*!< scalefactor of energies */
-{
- int j, k;
- int scale;
- FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
-
- /* Get Scratch buffer */
- C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, QMF_CHANNELS*QMF_MAX_TIME_SLOTS/2);
-
- /* Get max possible scaling of QMF data */
- scale = DFRACT_BITS;
- for (k=0; k<numberCols; k++) {
- scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), getScalefactor(imagValues[k], numberBands)));
- }
-
- /* Tweak scaling stability for zero signal to non-zero signal transitions */
- if (scale >= DFRACT_BITS-1) {
- scale = (FRACT_BITS-1-*qmfScale);
- }
- /* prevent scaling of QFM values to -1.f */
- scale = fixMax(0,scale-1);
-
- /* Update QMF scale */
- *qmfScale += scale;
-
- /*
- Calculate energy of each time slot pair, max energy
- and shift QMF values as far as possible to the left.
- */
- {
- FIXP_DBL *nrgValues = tmpNrg;
- for (k=0; k<numberCols; k+=2)
- {
- /* Load band vector addresses of 2 consecutive timeslots */
- FIXP_DBL *RESTRICT r0 = realValues[k];
- FIXP_DBL *RESTRICT i0 = imagValues[k];
- FIXP_DBL *RESTRICT r1 = realValues[k+1];
- FIXP_DBL *RESTRICT i1 = imagValues[k+1];
- for (j=0; j<numberBands; j++)
- {
- FIXP_DBL energy;
- FIXP_DBL tr0,tr1,ti0,ti1;
-
- /* Read QMF values of 2 timeslots */
- tr0 = r0[j]; tr1 = r1[j]; ti0 = i0[j]; ti1 = i1[j];
-
- /* Scale QMF Values and Calc Energy of both timeslots */
- tr0 <<= scale;
- ti0 <<= scale;
- energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1;
-
- tr1 <<= scale;
- ti1 <<= scale;
- energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1;
-
- /* Write timeslot pair energy to scratch */
- *nrgValues++ = energy;
- max_val = fixMax(max_val, energy);
-
- /* Write back scaled QMF values */
- r0[j] = tr0; r1[j] = tr1; i0[j] = ti0; i1[j] = ti1;
- }
- }
- }
- /* energyScale: scalefactor energies of current frame */
- *energyScale = 2*(*qmfScale)-1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
-
- /* Scale timeslot pair energies and write to output buffer */
- scale = CountLeadingBits(max_val);
- {
- FIXP_DBL *nrgValues = tmpNrg;
- for (k=0; k<numberCols>>1; k++) {
- scaleValues(energyValues[k], nrgValues, numberBands, scale);
- nrgValues += numberBands;
- }
- *energyScale += scale;
- }
-
- /* Free Scratch buffer */
- C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, QMF_CHANNELS*QMF_MAX_TIME_SLOTS/2);
-}
-
-LNK_SECTION_CODE_L1
-static void
-FDKsbrEnc_getEnergyFromCplxQmfDataFull(FIXP_DBL **RESTRICT energyValues,/*!< the result of the operation */
- FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
- FIXP_DBL **RESTRICT imagValues, /*!< the imaginary part of the QMF subsamples */
- int numberBands, /*!< number of QMF bands */
- int numberCols, /*!< number of QMF subsamples */
- int *qmfScale, /*!< sclefactor of QMF subsamples */
- int *energyScale) /*!< scalefactor of energies */
-{
- int j, k;
- int scale;
- FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
-
- /* Get Scratch buffer */
- C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, QMF_MAX_TIME_SLOTS*QMF_CHANNELS/2);
-
- FDK_ASSERT(numberBands <= QMF_CHANNELS);
- FDK_ASSERT(numberCols <= QMF_MAX_TIME_SLOTS/2);
-
- /* Get max possible scaling of QMF data */
- scale = DFRACT_BITS;
- for (k=0; k<numberCols; k++) {
- scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), getScalefactor(imagValues[k], numberBands)));
- }
-
- /* Tweak scaling stability for zero signal to non-zero signal transitions */
- if (scale >= DFRACT_BITS-1) {
- scale = (FRACT_BITS-1-*qmfScale);
- }
- /* prevent scaling of QFM values to -1.f */
- scale = fixMax(0,scale-1);
-
- /* Update QMF scale */
- *qmfScale += scale;
-
- /*
- Calculate energy of each time slot pair, max energy
- and shift QMF values as far as possible to the left.
- */
- {
- FIXP_DBL *nrgValues = tmpNrg;
- for (k=0; k<numberCols; k++)
- {
- /* Load band vector addresses of 2 consecutive timeslots */
- FIXP_DBL *RESTRICT r0 = realValues[k];
- FIXP_DBL *RESTRICT i0 = imagValues[k];
- for (j=0; j<numberBands; j++)
- {
- FIXP_DBL energy;
- FIXP_DBL tr0,ti0;
-
- /* Read QMF values of 2 timeslots */
- tr0 = r0[j]; ti0 = i0[j];
-
- /* Scale QMF Values and Calc Energy of both timeslots */
- tr0 <<= scale;
- ti0 <<= scale;
- energy = fPow2AddDiv2(fPow2Div2(tr0), ti0);
- *nrgValues++ = energy;
-
- max_val = fixMax(max_val, energy);
-
- /* Write back scaled QMF values */
- r0[j] = tr0; i0[j] = ti0;
- }
- }
- }
- /* energyScale: scalefactor energies of current frame */
- *energyScale = 2*(*qmfScale)-1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
-
- /* Scale timeslot pair energies and write to output buffer */
- scale = CountLeadingBits(max_val);
- {
- FIXP_DBL *nrgValues = tmpNrg;
- for (k=0; k<numberCols; k++) {
- scaleValues(energyValues[k], nrgValues, numberBands, scale);
- nrgValues += numberBands;
- }
- *energyScale += scale;
- }
-
- /* Free Scratch buffer */
- C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, QMF_MAX_TIME_SLOTS*QMF_CHANNELS/2);
-}
-
-/***************************************************************************/
-/*!
-
- \brief Quantisation of the panorama value (balance)
-
- \return the quantized pan value
-
-****************************************************************************/
-static INT
-mapPanorama(INT nrgVal, /*! integer value of the energy */
- INT ampRes, /*! amplitude resolution [1.5/3dB] */
- INT *quantError /*! quantization error of energy val*/
- )
-{
- int i;
- INT min_val, val;
- UCHAR panIndex;
- INT sign;
-
- sign = nrgVal > 0 ? 1 : -1;
-
- nrgVal *= sign;
-
- min_val = FDK_INT_MAX;
- panIndex = 0;
- for (i = 0; i < maxIndex[ampRes]; i++) {
- val = fixp_abs ((nrgVal - (INT)panTable[ampRes][i]));
-
- if (val < min_val) {
- min_val = val;
- panIndex = i;
- }
- }
-
- *quantError=min_val;
-
- return panTable[ampRes][maxIndex[ampRes]-1] + sign * panTable[ampRes][panIndex];
-}
-
-
-/***************************************************************************/
-/*!
-
- \brief Quantisation of the noise floor levels
-
- \return void
-
-****************************************************************************/
-static void
-sbrNoiseFloorLevelsQuantisation(SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */
- FIXP_DBL *RESTRICT NoiseLevels, /*! the noise levels */
- INT coupling /*! the coupling flag */
- )
-{
- INT i;
- INT tmp, dummy;
-
- /* Quantisation, similar to sfb quant... */
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
- /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] + (PFLOAT)0.5); */
- /* 30>>6 = 0.46875 */
- if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) {
- tmp = 30;
- }
- else {
- /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/ /* FRACT_BITS+ */ /* 6-1)));*/
- /* tmp = tmp >> (DFRACT_BITS-1-6); */ /* conversion to integer happens here */
- /* rounding is done by shifting one bit less than necessary to the right, adding '1' and then shifting the final bit */
- tmp = ((((INT)NoiseLevels[i])>>(DFRACT_BITS-1-LD_DATA_SHIFT)) ); /* conversion to integer */
- if (tmp != 0)
- tmp += 1;
- }
-
- if (coupling) {
- tmp = tmp < -30 ? -30 : tmp;
- tmp = mapPanorama (tmp,1,&dummy);
- }
- iNoiseLevels[i] = tmp;
- }
-}
-
-/***************************************************************************/
-/*!
-
- \brief Calculation of noise floor for coupling
-
- \return void
-
-****************************************************************************/
-static void
-coupleNoiseFloor(FIXP_DBL *RESTRICT noise_level_left, /*! noise level left (modified)*/
- FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/
- )
-{
- FIXP_DBL cmpValLeft,cmpValRight;
- INT i;
- FIXP_DBL temp1,temp2;
-
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
-
- /* Calculation of the power function using ld64:
- z = x^y;
- z' = CalcLd64(z) = y*CalcLd64(x)/64;
- z = CalcInvLd64(z');
- */
- cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i];
- cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i];
-
- if (cmpValRight < FL2FXCONST_DBL(0.0f)) {
- temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
- }
- else {
- temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
- temp1 = temp1 << (DFRACT_BITS-1-LD_DATA_SHIFT-1); /* INT to fract conversion of result, if input of CalcInvLdData is positiv */
- }
-
- if (cmpValLeft < FL2FXCONST_DBL(0.0f)) {
- temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
- }
- else {
- temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
- temp2 = temp2 << (DFRACT_BITS-1-LD_DATA_SHIFT-1); /* INT to fract conversion of result, if input of CalcInvLdData is positiv */
- }
-
-
- if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && (cmpValRight < FL2FXCONST_DBL(0.0f))) {
- noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - (CalcLdData(((temp1>>1) + (temp2>>1)))); /* no scaling needed! both values are dfract */
- noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
- }
-
- if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
- noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - (CalcLdData(((temp1>>1) + (temp2>>1))) + FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
- noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
- }
-
- if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && (cmpValRight < FL2FXCONST_DBL(0.0f))) {
- noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - (CalcLdData(((temp1>>(7+1)) + (temp2>>1))) + FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
- noise_level_right[i] = (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1);
- }
-
- if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
- noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - (CalcLdData(((temp1>>1) + (temp2>>(7+1)))) + FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
- noise_level_right[i] = CalcLdData(temp2) - (CalcLdData(temp1) + FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
- }
- }
-}
-
-/***************************************************************************/
-/*!
-
- \brief Calculation of energy starting in lower band (li) up to upper band (ui)
- over slots (start_pos) to (stop_pos)
-
- \return void
-
-****************************************************************************/
-static FIXP_DBL
-getEnvSfbEnergy(INT li, /*! lower band */
- INT ui, /*! upper band */
- INT start_pos, /*! start slot */
- INT stop_pos, /*! stop slot */
- INT border_pos, /*! slots scaling border */
- FIXP_DBL **YBuffer, /*! sfb energy buffer */
- INT YBufferSzShift, /*! Energy buffer index scale */
- INT scaleNrg0, /*! scaling of lower slots */
- INT scaleNrg1) /*! scaling of upper slots */
-{
- /* use dynamic scaling for outer energy loop;
- energies are critical and every bit is important */
- int sc0, sc1, k, l;
-
- FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2;
- INT dynScale, dynScale1, dynScale2;
- if(ui-li==0) dynScale = DFRACT_BITS-1;
- else
- dynScale = CalcLdInt(ui-li)>>(DFRACT_BITS-1-LD_DATA_SHIFT);
-
- sc0 = fixMin(scaleNrg0,Y_NRG_SCALE); sc1 = fixMin(scaleNrg1,Y_NRG_SCALE);
- /* dynScale{1,2} is set such that the right shift below is positive */
- dynScale1 = fixMin((scaleNrg0-sc0),dynScale);
- dynScale2 = fixMin((scaleNrg1-sc1),dynScale);
- nrgSum = accu1 = accu2 = (FIXP_DBL)0;
-
- for (k = li; k < ui; k++) {
- nrg1 = nrg2 = (FIXP_DBL)0;
- for (l = start_pos; l < border_pos; l++) {
- nrg1 += YBuffer[l>>YBufferSzShift][k] >> sc0;
- }
- for (; l < stop_pos; l++) {
- nrg2 += YBuffer[l>>YBufferSzShift][k] >> sc1;
- }
- accu1 += (nrg1>>dynScale1);
- accu2 += (nrg2>>dynScale2);
- }
- /* This shift factor is always positive. See comment above. */
- nrgSum += ( accu1 >> fixMin((scaleNrg0-sc0-dynScale1),(DFRACT_BITS-1)) )
- + ( accu2 >> fixMin((scaleNrg1-sc1-dynScale2),(DFRACT_BITS-1)) );
-
- return nrgSum;
-}
-
-/***************************************************************************/
-/*!
-
- \brief Energy compensation in missing harmonic mode
-
- \return void
-
-****************************************************************************/
-static FIXP_DBL
-mhLoweringEnergy(FIXP_DBL nrg, INT M)
-{
- /*
- Compensating for the fact that we in the decoder map the "average energy to every QMF
- band, and use this when we calculate the boost-factor. Since the mapped energy isn't
- the average energy but the maximum energy in case of missing harmonic creation, we will
- in the boost function calculate that too much limiting has been applied and hence we will
- boost the signal although it isn't called for. Hence we need to compensate for this by
- lowering the transmitted energy values for the sines so they will get the correct level
- after the boost is applied.
- */
- if(M > 2){
- INT tmpScale;
- tmpScale = CountLeadingBits(nrg);
- nrg <<= tmpScale;
- nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost is 1.584893, so the maximum attenuation should be square(1/1.584893) = 0.398107267 */
- nrg >>= tmpScale;
- }
- else{
- if(M > 1){
- nrg >>= 1;
- }
- }
-
- return nrg;
-}
-
-/***************************************************************************/
-/*!
-
- \brief Energy compensation in none missing harmonic mode
-
- \return void
-
-****************************************************************************/
-static FIXP_DBL nmhLoweringEnergy(
- FIXP_DBL nrg,
- const FIXP_DBL nrgSum,
- const INT nrgSum_scale,
- const INT M
- )
-{
- if (nrg>FL2FXCONST_DBL(0)) {
- int sc=0;
- /* gain = nrgSum / (nrg*(M+1)) */
- FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M+1));
- sc += nrgSum_scale;
-
- /* reduce nrg if gain smaller 1.f */
- if ( !((sc>=0) && ( gain > ((FIXP_DBL)MAXVAL_DBL>>sc) )) ) {
- nrg = fMult(scaleValue(gain,sc), nrg);
- }
- }
- return nrg;
-}
-
-/***************************************************************************/
-/*!
-
- \brief calculates the envelope values from the energies, depending on
- framing and stereo mode
-
- \return void
-
-****************************************************************************/
-static void
-calculateSbrEnvelope (FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left */
- FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */
- int *RESTRICT YBufferScaleLeft, /*! scale energy buffer left */
- int *RESTRICT YBufferScaleRight, /*! scale energy buffer right */
- const SBR_FRAME_INFO *frame_info, /*! frame info vector */
- SCHAR *RESTRICT sfb_nrgLeft, /*! sfb energy buffer left */
- SCHAR *RESTRICT sfb_nrgRight, /*! sfb energy buffer right */
- HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
- HANDLE_ENV_CHANNEL h_sbr, /*! envelope channel handle */
- SBR_STEREO_MODE stereoMode, /*! stereo coding mode */
- INT* maxQuantError, /*! maximum quantization error, for panorama. */
- int YBufferSzShift) /*! Energy buffer index scale */
-
-{
- int i, j, m = 0;
- INT no_of_bands, start_pos, stop_pos, li, ui;
- FREQ_RES freq_res;
-
- INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res;
- INT oneBitLess = 0;
- if (ca == 2)
- oneBitLess = 1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
-
- INT quantError;
- INT nEnvelopes = frame_info->nEnvelopes;
- INT short_env = frame_info->shortEnv - 1;
- INT timeStep = h_sbr->sbrExtractEnvelope.time_step;
- INT commonScale,scaleLeft0,scaleLeft1;
- INT scaleRight0=0,scaleRight1=0;
-
- commonScale = fixMin(YBufferScaleLeft[0],YBufferScaleLeft[1]);
-
- if (stereoMode == SBR_COUPLING) {
- commonScale = fixMin(commonScale,YBufferScaleRight[0]);
- commonScale = fixMin(commonScale,YBufferScaleRight[1]);
- }
-
- commonScale = commonScale - 7;
-
- scaleLeft0 = YBufferScaleLeft[0] - commonScale;
- scaleLeft1 = YBufferScaleLeft[1] - commonScale ;
- FDK_ASSERT ((scaleLeft0 >= 0) && (scaleLeft1 >= 0));
-
- if (stereoMode == SBR_COUPLING) {
- scaleRight0 = YBufferScaleRight[0] - commonScale;
- scaleRight1 = YBufferScaleRight[1] - commonScale;
- FDK_ASSERT ((scaleRight0 >= 0) && (scaleRight1 >= 0));
- *maxQuantError = 0;
- }
-
- for (i = 0; i < nEnvelopes; i++) {
-
- FIXP_DBL pNrgLeft[QMF_MAX_TIME_SLOTS];
- FIXP_DBL pNrgRight[QMF_MAX_TIME_SLOTS];
- int envNrg_scale;
- FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f);
- FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f);
- int missingHarmonic[QMF_MAX_TIME_SLOTS];
- int count[QMF_MAX_TIME_SLOTS];
-
- start_pos = timeStep * frame_info->borders[i];
- stop_pos = timeStep * frame_info->borders[i + 1];
- freq_res = frame_info->freqRes[i];
- no_of_bands = h_con->nSfb[freq_res];
- envNrg_scale = DFRACT_BITS-fNormz((FIXP_DBL)no_of_bands);
-
- if (i == short_env) {
- stop_pos -= fixMax(2, timeStep); /* consider at least 2 QMF slots less for short envelopes (envelopes just before transients) */
- }
-
- for (j = 0; j < no_of_bands; j++) {
- FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f);
- FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f);
-
- li = h_con->freqBandTable[freq_res][j];
- ui = h_con->freqBandTable[freq_res][j + 1];
-
- if(freq_res == FREQ_RES_HIGH){
- if(j == 0 && ui-li > 1){
- li++;
- }
- }
- else{
- if(j == 0 && ui-li > 2){
- li++;
- }
- }
-
- /*
- Find out whether a sine will be missing in the scale-factor
- band that we're currently processing.
- */
- missingHarmonic[j] = 0;
-
- if(h_sbr->encEnvData.addHarmonicFlag){
-
- if(freq_res == FREQ_RES_HIGH){
- if(h_sbr->encEnvData.addHarmonic[j]){ /*A missing sine in the current band*/
- missingHarmonic[j] = 1;
- }
- }
- else{
- INT i;
- INT startBandHigh = 0;
- INT stopBandHigh = 0;
-
- while(h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] < h_con->freqBandTable[FREQ_RES_LOW][j])
- startBandHigh++;
- while(h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] < h_con->freqBandTable[FREQ_RES_LOW][j + 1])
- stopBandHigh++;
-
- for(i = startBandHigh; i<stopBandHigh; i++){
- if(h_sbr->encEnvData.addHarmonic[i]){
- missingHarmonic[j] = 1;
- }
- }
- }
- }
-
- /*
- If a sine is missing in a scalefactorband, with more than one qmf channel
- use the nrg from the channel with the largest nrg rather than the mean.
- Compensate for the boost calculation in the decdoder.
- */
- int border_pos = fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset<<YBufferSzShift);
-
- if(missingHarmonic[j]){
-
- int k;
- count[j] = stop_pos - start_pos;
- nrgLeft = FL2FXCONST_DBL(0.0f);
-
- for (k = li; k < ui; k++) {
- FIXP_DBL tmpNrg;
- tmpNrg = getEnvSfbEnergy(k,
- k+1,
- start_pos,
- stop_pos,
- border_pos,
- YBufferLeft,
- YBufferSzShift,
- scaleLeft0,
- scaleLeft1);
-
- nrgLeft = fixMax(nrgLeft, tmpNrg);
- }
-
- /* Energy lowering compensation */
- nrgLeft = mhLoweringEnergy(nrgLeft, ui-li);
-
- if (stereoMode == SBR_COUPLING) {
-
- nrgRight = FL2FXCONST_DBL(0.0f);
-
- for (k = li; k < ui; k++) {
- FIXP_DBL tmpNrg;
- tmpNrg = getEnvSfbEnergy(k,
- k+1,
- start_pos,
- stop_pos,
- border_pos,
- YBufferRight,
- YBufferSzShift,
- scaleRight0,
- scaleRight1);
-
- nrgRight = fixMax(nrgRight, tmpNrg);
- }
-
- /* Energy lowering compensation */
- nrgRight = mhLoweringEnergy(nrgRight, ui-li);
- }
- } /* end missingHarmonic */
- else{
- count[j] = (stop_pos - start_pos) * (ui - li);
-
- nrgLeft = getEnvSfbEnergy(li,
- ui,
- start_pos,
- stop_pos,
- border_pos,
- YBufferLeft,
- YBufferSzShift,
- scaleLeft0,
- scaleLeft1);
-
- if (stereoMode == SBR_COUPLING) {
- nrgRight = getEnvSfbEnergy(li,
- ui,
- start_pos,
- stop_pos,
- border_pos,
- YBufferRight,
- YBufferSzShift,
- scaleRight0,
- scaleRight1);
- }
- } /* !missingHarmonic */
-
- /* save energies */
- pNrgLeft[j] = nrgLeft;
- pNrgRight[j] = nrgRight;
- envNrgLeft += (nrgLeft>>envNrg_scale);
- envNrgRight += (nrgRight>>envNrg_scale);
- } /* j */
-
- for (j = 0; j < no_of_bands; j++) {
-
- FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f);
- FIXP_DBL nrgLeft = pNrgLeft[j];
- FIXP_DBL nrgRight = pNrgRight[j];
-
- /* None missing harmonic Energy lowering compensation */
- if(!missingHarmonic[j] && h_sbr->fLevelProtect) {
- /* in case of missing energy in base band,
- reduce reference energy to prevent overflows in decoder output */
- nrgLeft = nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands);
- if (stereoMode == SBR_COUPLING) {
- nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale, no_of_bands);
- }
- }
-
- if (stereoMode == SBR_COUPLING) {
- /* calc operation later with log */
- nrgLeft2 = nrgLeft;
- nrgLeft = (nrgRight + nrgLeft) >> 1;
- }
-
- /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * h_sbr->sbrQmf.no_channels))+(PFLOAT)44; */
- /* If nrgLeft == 0 then the Log calculations below do fail. */
- if (nrgLeft > FL2FXCONST_DBL(0.0f))
- {
- FIXP_DBL tmp0,tmp1,tmp2,tmp3;
- INT tmpScale;
-
- tmpScale = CountLeadingBits(nrgLeft);
- nrgLeft = nrgLeft << tmpScale;
-
- tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */
- tmp1 = ((FIXP_DBL) (commonScale+tmpScale)) << (DFRACT_BITS-1-LD_DATA_SHIFT-1); /* scaled by 1/64 */
- tmp2 = ((FIXP_DBL)(count[j]*h_con->noQmfBands)) << (DFRACT_BITS-1-14-1);
- tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */
- tmp3 = FL2FXCONST_DBL(0.6875f-0.21875f-0.015625f)>>1; /* scaled by 1/64 */
-
- nrgLeft = ((tmp0-tmp2)>>1) + (tmp3 - tmp1);
- } else {
- nrgLeft = FL2FXCONST_DBL(-1.0f);
- }
-
- /* ld64 to integer conversion */
- nrgLeft = fixMin(fixMax(nrgLeft,FL2FXCONST_DBL(0.0f)),(FL2FXCONST_DBL(0.5f)>>oneBitLess));
- nrgLeft = (FIXP_DBL)(LONG)nrgLeft >> (DFRACT_BITS-1-LD_DATA_SHIFT-1-oneBitLess-1);
- sfb_nrgLeft[m] = ((INT)nrgLeft+1)>>1; /* rounding */
-
- if (stereoMode == SBR_COUPLING) {
- FIXP_DBL scaleFract;
- int sc0, sc1;
-
- nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2);
- nrgRight = fixMax((FIXP_DBL)0x1, nrgRight);
-
- sc0 = CountLeadingBits(nrgLeft2);
- sc1 = CountLeadingBits(nrgRight);
-
- scaleFract = ((FIXP_DBL)(sc0-sc1)) << (DFRACT_BITS-1-LD_DATA_SHIFT); /* scale value in ld64 representation */
- nrgRight = CalcLdData(nrgLeft2<<sc0) - CalcLdData(nrgRight<<sc1) - scaleFract;
-
- /* ld64 to integer conversion */
- nrgRight = (FIXP_DBL)(LONG)(nrgRight) >> (DFRACT_BITS-1-LD_DATA_SHIFT-1-oneBitLess);
- nrgRight = (nrgRight+(FIXP_DBL)1)>>1; /* rounding */
-
- sfb_nrgRight[m] = mapPanorama (nrgRight,h_sbr->encEnvData.init_sbr_amp_res,&quantError);
-
- *maxQuantError = fixMax(quantError, *maxQuantError);
- }
-
- m++;
- } /* j */
-
- /* Do energy compensation for sines that are present in two
- QMF-bands in the original, but will only occur in one band in
- the decoder due to the synthetic sine coding.*/
- if (h_con->useParametricCoding) {
- m-=no_of_bands;
- for (j = 0; j < no_of_bands; j++) {
- if (freq_res==FREQ_RES_HIGH && h_sbr->sbrExtractEnvelope.envelopeCompensation[j]){
- sfb_nrgLeft[m] -= (ca * fixp_abs((INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j]));
- }
- sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]);
- m++;
- }
- } /* useParametricCoding */
-
- } /* i*/
-}
-
-/***************************************************************************/
-/*!
-
- \brief calculates the noise floor and the envelope values from the
- energies, depending on framing and stereo mode
-
- FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
- envelope and the noise floor. The function includes the following processes:
-
- -Analysis subband filtering.
- -Encoding SA and pan parameters (if enabled).
- -Transient detection.
-
-****************************************************************************/
-
-LNK_SECTION_CODE_L1
-void
-FDKsbrEnc_extractSbrEnvelope1 (
- HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
- HANDLE_ENV_CHANNEL hEnvChan,
- HANDLE_COMMON_DATA hCmonData,
- SBR_ENV_TEMP_DATA *eData,
- SBR_FRAME_TEMP_DATA *fData
- )
-{
-
- HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
-
- if (sbrExtrEnv->YBufferSzShift == 0)
- FDKsbrEnc_getEnergyFromCplxQmfDataFull(&sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
- sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
- sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset,
- h_con->noQmfBands,
- sbrExtrEnv->no_cols,
- &hEnvChan->qmfScale,
- &sbrExtrEnv->YBufferScale[1]);
- else
- FDKsbrEnc_getEnergyFromCplxQmfData(&sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
- sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
- sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset,
- h_con->noQmfBands,
- sbrExtrEnv->no_cols,
- &hEnvChan->qmfScale,
- &sbrExtrEnv->YBufferScale[1]);
-
-
-
- /*
- Precalculation of Tonality Quotas COEFF Transform OK
- */
- FDKsbrEnc_CalculateTonalityQuotas(&hEnvChan->TonCorr,
- sbrExtrEnv->rBuffer,
- sbrExtrEnv->iBuffer,
- h_con->freqBandTable[HI][h_con->nSfb[HI]],
- hEnvChan->qmfScale);
-
-
- if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
- FIXP_DBL tonality = FDKsbrEnc_GetTonality (
- hEnvChan->TonCorr.quotaMatrix,
- hEnvChan->TonCorr.numberOfEstimatesPerFrame,
- hEnvChan->TonCorr.startIndexMatrix,
- sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
- h_con->freqBandTable[HI][0]+1,
- h_con->noQmfBands,
- sbrExtrEnv->no_cols
- );
-
- hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
- hEnvChan->encEnvData.ton_HF[0] = tonality;
-
- /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
- hEnvChan->encEnvData.global_tonality = (hEnvChan->encEnvData.ton_HF[0]>>1) + (hEnvChan->encEnvData.ton_HF[1]>>1);
- }
-
-
-
- /*
- Transient detection COEFF Transform OK
- */
- if(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
- {
- FDKsbrEnc_fastTransientDetect(
- &hEnvChan->sbrFastTransientDetector,
- sbrExtrEnv->YBuffer,
- sbrExtrEnv->YBufferScale,
- sbrExtrEnv->YBufferWriteOffset,
- eData->transient_info
- );
-
- }
- else
- {
- FDKsbrEnc_transientDetect(&hEnvChan->sbrTransientDetector,
- sbrExtrEnv->YBuffer,
- sbrExtrEnv->YBufferScale,
- eData->transient_info,
- sbrExtrEnv->YBufferWriteOffset,
- sbrExtrEnv->YBufferSzShift,
- sbrExtrEnv->time_step,
- hEnvChan->SbrEnvFrame.frameMiddleSlot);
- }
-
-
-
- /*
- Generate flags for 2 env in a FIXFIX-frame.
- Remove this function to get always 1 env per FIXFIX-frame.
- */
-
- /*
- frame Splitter COEFF Transform OK
- */
- FDKsbrEnc_frameSplitter(sbrExtrEnv->YBuffer,
- sbrExtrEnv->YBufferScale,
- &hEnvChan->sbrTransientDetector,
- h_con->freqBandTable[1],
- eData->transient_info,
- sbrExtrEnv->YBufferWriteOffset,
- sbrExtrEnv->YBufferSzShift,
- h_con->nSfb[1],
- sbrExtrEnv->time_step,
- sbrExtrEnv->no_cols,
- &hEnvChan->encEnvData.global_tonality);
-
-
-}
-
-/***************************************************************************/
-/*!
-
- \brief calculates the noise floor and the envelope values from the
- energies, depending on framing and stereo mode
-
- FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
- envelope and the noise floor. The function includes the following processes:
-
- -Determine time/frequency division of current granule.
- -Sending transient info to bitstream.
- -Set amp_res to 1.5 dB if the current frame contains only one envelope.
- -Lock dynamic bandwidth frequency change if the next envelope not starts on a
- frame boundary.
- -MDCT transposer (needed to detect where harmonics will be missing).
- -Spectrum Estimation (used for pulse train and missing harmonics detection).
- -Pulse train detection.
- -Inverse Filtering detection.
- -Waveform Coding.
- -Missing Harmonics detection.
- -Extract envelope of current frame.
- -Noise floor estimation.
- -Noise floor quantisation and coding.
- -Encode envelope of current frame.
- -Send the encoded data to the bitstream.
- -Write to bitstream.
-
-****************************************************************************/
-
-LNK_SECTION_CODE_L1
-void
-FDKsbrEnc_extractSbrEnvelope2 (
- HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */
- HANDLE_SBR_HEADER_DATA sbrHeaderData,
- HANDLE_PARAMETRIC_STEREO hParametricStereo,
- HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,
- HANDLE_ENV_CHANNEL h_envChan0,
- HANDLE_ENV_CHANNEL h_envChan1,
- HANDLE_COMMON_DATA hCmonData,
- SBR_ENV_TEMP_DATA *eData,
- SBR_FRAME_TEMP_DATA *fData,
- int clearOutput
- )
-{
- HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1};
- int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift;
-
- SBR_STEREO_MODE stereoMode = h_con->stereoMode;
- int nChannels = h_con->nChannels;
- const int *v_tuning;
- static const int v_tuningHEAAC[6] = { 0, 2, 4, 0, 0, 0 };
-
- static const int v_tuningELD[6] = { 0, 2, 3, 0, 0, 0 };
-
- if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
- v_tuning = v_tuningELD;
- else
- v_tuning = v_tuningHEAAC;
-
-
- /*
- Select stereo mode.
- */
- if (stereoMode == SBR_COUPLING) {
- if (eData[0].transient_info[1] && eData[1].transient_info[1]) {
- eData[0].transient_info[0] = fixMin(eData[1].transient_info[0], eData[0].transient_info[0]);
- eData[1].transient_info[0] = eData[0].transient_info[0];
- }
- else {
- if (eData[0].transient_info[1] && !eData[1].transient_info[1]) {
- eData[1].transient_info[0] = eData[0].transient_info[0];
- }
- else {
- if (!eData[0].transient_info[1] && eData[1].transient_info[1])
- eData[0].transient_info[0] = eData[1].transient_info[0];
- else {
- eData[0].transient_info[0] = fixMax(eData[1].transient_info[0], eData[0].transient_info[0]);
- eData[1].transient_info[0] = eData[0].transient_info[0];
- }
- }
- }
- }
-
- /*
- Determine time/frequency division of current granule
- */
- eData[0].frame_info = FDKsbrEnc_frameInfoGenerator(&h_envChan[0]->SbrEnvFrame,
- eData[0].transient_info,
- h_envChan[0]->sbrExtractEnvelope.pre_transient_info,
- h_envChan[0]->encEnvData.ldGrid,
- v_tuning);
-
- h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
-
- /* AAC LD patch for transient prediction */
- if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) {
- /* if next frame will start with transient, set shortEnv to numEnvelopes(shortend Envelope = shortEnv-1)*/
- h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv = h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
- }
-
-
- switch (stereoMode) {
- case SBR_LEFT_RIGHT:
- case SBR_SWITCH_LRC:
- eData[1].frame_info = FDKsbrEnc_frameInfoGenerator(&h_envChan[1]->SbrEnvFrame,
- eData[1].transient_info,
- h_envChan[1]->sbrExtractEnvelope.pre_transient_info,
- h_envChan[1]->encEnvData.ldGrid,
- v_tuning);
-
- h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid;
-
- if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) {
- /* if next frame will start with transient, set shortEnv to numEnvelopes(shortend Envelope = shortEnv-1)*/
- h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv = h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
- }
-
- /* compare left and right frame_infos */
- if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) {
- stereoMode = SBR_LEFT_RIGHT;
- } else {
- for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) {
- if (eData[0].frame_info->borders[i] != eData[1].frame_info->borders[i]) {
- stereoMode = SBR_LEFT_RIGHT;
- break;
- }
- }
- for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) {
- if (eData[0].frame_info->freqRes[i] != eData[1].frame_info->freqRes[i]) {
- stereoMode = SBR_LEFT_RIGHT;
- break;
- }
- }
- if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) {
- stereoMode = SBR_LEFT_RIGHT;
- }
- }
- break;
- case SBR_COUPLING:
- eData[1].frame_info = eData[0].frame_info;
- h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
- break;
- case SBR_MONO:
- /* nothing to do */
- break;
- default:
- FDK_ASSERT (0);
- }
-
-
- for (ch = 0; ch < nChannels;ch++)
- {
- HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch];
- HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
- SBR_ENV_TEMP_DATA *ed = &eData[ch];
-
-
- /*
- Send transient info to bitstream and store for next call
- */
- sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0];/* tran_pos */
- sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1];/* tran_flag */
- hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes = ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
-
- /*
- Check if the current frame is divided into one envelope only. If so, set the amplitude
- resolution to 1.5 dB, otherwise may set back to chosen value
- */
- if( ( hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX )
- && ( ed->nEnvelopes == 1 ) )
- {
-
- if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
- {
- /* Note: global_tonaliy_float_value == ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
- threshold_float_value == ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); */
- /* decision of SBR_AMP_RES */
- if (fIsLessThan( /* global_tonality > threshold ? */
- h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
- hEnvChan->encEnvData.global_tonality, RELAXATION_SHIFT+2 )
- )
- {
- hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
- }
- else {
- hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
- }
- } else {
- hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
- }
-
- if ( hEnvChan->encEnvData.currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
-
- FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData,
- &hEnvChan->sbrCodeEnvelope,
- &hEnvChan->sbrCodeNoiseFloor,
- hEnvChan->encEnvData.currentAmpResFF);
- }
- }
- else {
- if(sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res ) {
-
- FDKsbrEnc_InitSbrHuffmanTables(&hEnvChan->encEnvData,
- &hEnvChan->sbrCodeEnvelope,
- &hEnvChan->sbrCodeNoiseFloor,
- sbrHeaderData->sbr_amp_res);
- }
- }
-
- if (!clearOutput) {
-
- /*
- Tonality correction parameter extraction (inverse filtering level, noise floor additional sines).
- */
- FDKsbrEnc_TonCorrParamExtr(&hEnvChan->TonCorr,
- hEnvChan->encEnvData.sbr_invf_mode_vec,
- ed->noiseFloor,
- &hEnvChan->encEnvData.addHarmonicFlag,
- hEnvChan->encEnvData.addHarmonic,
- sbrExtrEnv->envelopeCompensation,
- ed->frame_info,
- ed->transient_info,
- h_con->freqBandTable[HI],
- h_con->nSfb[HI],
- hEnvChan->encEnvData.sbr_xpos_mode,
- h_con->sbrSyntaxFlags);
-
- }
-
- /* Low energy in low band fix */
- if ( hEnvChan->sbrTransientDetector.prevLowBandEnergy < hEnvChan->sbrTransientDetector.prevHighBandEnergy
- && hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
- /* The fix needs the non-fast transient detector running.
- It sets prevLowBandEnergy and prevHighBandEnergy. */
- && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
- )
- {
- int i;
-
- hEnvChan->fLevelProtect = 1;
-
- for (i=0; i<MAX_NUM_NOISE_VALUES; i++)
- hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
- } else {
- hEnvChan->fLevelProtect = 0;
- }
-
- hEnvChan->encEnvData.sbr_invf_mode = hEnvChan->encEnvData.sbr_invf_mode_vec[0];
-
- hEnvChan->encEnvData.noOfnoisebands = hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
-
-
- } /* ch */
-
-
-
- /*
- Save number of scf bands per envelope
- */
- for (ch = 0; ch < nChannels;ch++) {
- for (i = 0; i < eData[ch].nEnvelopes; i++){
- h_envChan[ch]->encEnvData.noScfBands[i] =
- (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH ? h_con->nSfb[FREQ_RES_HIGH] : h_con->nSfb[FREQ_RES_LOW]);
- }
- }
-
- /*
- Extract envelope of current frame.
- */
- switch (stereoMode) {
- case SBR_MONO:
- calculateSbrEnvelope (h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
- h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
- eData[0].frame_info, eData[0].sfb_nrg, NULL,
- h_con, h_envChan[0], SBR_MONO, NULL, YSzShift);
- break;
- case SBR_LEFT_RIGHT:
- calculateSbrEnvelope (h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
- h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
- eData[0].frame_info, eData[0].sfb_nrg, NULL,
- h_con, h_envChan[0], SBR_MONO, NULL, YSzShift);
- calculateSbrEnvelope (h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
- h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
- eData[1].frame_info,eData[1].sfb_nrg, NULL,
- h_con, h_envChan[1], SBR_MONO, NULL, YSzShift);
- break;
- case SBR_COUPLING:
- calculateSbrEnvelope (h_envChan[0]->sbrExtractEnvelope.YBuffer, h_envChan[1]->sbrExtractEnvelope.YBuffer,
- h_envChan[0]->sbrExtractEnvelope.YBufferScale, h_envChan[1]->sbrExtractEnvelope.YBufferScale,
- eData[0].frame_info, eData[0].sfb_nrg, eData[1].sfb_nrg,
- h_con, h_envChan[0], SBR_COUPLING, &fData->maxQuantError, YSzShift);
- break;
- case SBR_SWITCH_LRC:
- calculateSbrEnvelope (h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
- h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
- eData[0].frame_info, eData[0].sfb_nrg, NULL,
- h_con, h_envChan[0], SBR_MONO, NULL, YSzShift);
- calculateSbrEnvelope (h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
- h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
- eData[1].frame_info, eData[1].sfb_nrg, NULL,
- h_con, h_envChan[1], SBR_MONO,NULL, YSzShift);
- calculateSbrEnvelope (h_envChan[0]->sbrExtractEnvelope.YBuffer, h_envChan[1]->sbrExtractEnvelope.YBuffer,
- h_envChan[0]->sbrExtractEnvelope.YBufferScale, h_envChan[1]->sbrExtractEnvelope.YBufferScale,
- eData[0].frame_info, eData[0].sfb_nrg_coupling, eData[1].sfb_nrg_coupling,
- h_con, h_envChan[0], SBR_COUPLING, &fData->maxQuantError, YSzShift);
- break;
- }
-
-
-
- /*
- Noise floor quantisation and coding.
- */
-
- switch (stereoMode) {
- case SBR_MONO:
- sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, 0);
-
- FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
- &h_envChan[0]->sbrCodeNoiseFloor,
- h_envChan[0]->encEnvData.domain_vec_noise, 0,
- (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- break;
- case SBR_LEFT_RIGHT:
- sbrNoiseFloorLevelsQuantisation(eData[0].noise_level,eData[0].noiseFloor, 0);
-
- FDKsbrEnc_codeEnvelope (eData[0].noise_level, fData->res,
- &h_envChan[0]->sbrCodeNoiseFloor,
- h_envChan[0]->encEnvData.domain_vec_noise, 0,
- (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- sbrNoiseFloorLevelsQuantisation(eData[1].noise_level,eData[1].noiseFloor, 0);
-
- FDKsbrEnc_codeEnvelope (eData[1].noise_level, fData->res,
- &h_envChan[1]->sbrCodeNoiseFloor,
- h_envChan[1]->encEnvData.domain_vec_noise, 0,
- (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- break;
-
- case SBR_COUPLING:
- coupleNoiseFloor(eData[0].noiseFloor,eData[1].noiseFloor);
-
- sbrNoiseFloorLevelsQuantisation(eData[0].noise_level,eData[0].noiseFloor, 0);
-
- FDKsbrEnc_codeEnvelope (eData[0].noise_level, fData->res,
- &h_envChan[0]->sbrCodeNoiseFloor,
- h_envChan[0]->encEnvData.domain_vec_noise, 1,
- (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- sbrNoiseFloorLevelsQuantisation(eData[1].noise_level,eData[1].noiseFloor, 1);
-
- FDKsbrEnc_codeEnvelope (eData[1].noise_level, fData->res,
- &h_envChan[1]->sbrCodeNoiseFloor,
- h_envChan[1]->encEnvData.domain_vec_noise, 1,
- (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
- sbrBitstreamData->HeaderActive);
-
- break;
- case SBR_SWITCH_LRC:
- sbrNoiseFloorLevelsQuantisation(eData[0].noise_level,eData[0].noiseFloor, 0);
- sbrNoiseFloorLevelsQuantisation(eData[1].noise_level,eData[1].noiseFloor, 0);
- coupleNoiseFloor(eData[0].noiseFloor,eData[1].noiseFloor);
- sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,eData[0].noiseFloor, 0);
- sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,eData[1].noiseFloor, 1);
- break;
- }
-
-
-
- /*
- Encode envelope of current frame.
- */
- switch (stereoMode) {
- case SBR_MONO:
- sbrHeaderData->coupling = 0;
- h_envChan[0]->encEnvData.balance = 0;
- FDKsbrEnc_codeEnvelope (eData[0].sfb_nrg, eData[0].frame_info->freqRes,
- &h_envChan[0]->sbrCodeEnvelope,
- h_envChan[0]->encEnvData.domain_vec,
- sbrHeaderData->coupling,
- eData[0].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
- break;
- case SBR_LEFT_RIGHT:
- sbrHeaderData->coupling = 0;
-
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 0;
-
-
- FDKsbrEnc_codeEnvelope (eData[0].sfb_nrg, eData[0].frame_info->freqRes,
- &h_envChan[0]->sbrCodeEnvelope,
- h_envChan[0]->encEnvData.domain_vec,
- sbrHeaderData->coupling,
- eData[0].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
- FDKsbrEnc_codeEnvelope (eData[1].sfb_nrg, eData[1].frame_info->freqRes,
- &h_envChan[1]->sbrCodeEnvelope,
- h_envChan[1]->encEnvData.domain_vec,
- sbrHeaderData->coupling,
- eData[1].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
- break;
- case SBR_COUPLING:
- sbrHeaderData->coupling = 1;
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 1;
-
- FDKsbrEnc_codeEnvelope (eData[0].sfb_nrg, eData[0].frame_info->freqRes,
- &h_envChan[0]->sbrCodeEnvelope,
- h_envChan[0]->encEnvData.domain_vec,
- sbrHeaderData->coupling,
- eData[0].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
- FDKsbrEnc_codeEnvelope (eData[1].sfb_nrg, eData[1].frame_info->freqRes,
- &h_envChan[1]->sbrCodeEnvelope,
- h_envChan[1]->encEnvData.domain_vec,
- sbrHeaderData->coupling,
- eData[1].frame_info->nEnvelopes, 1,
- sbrBitstreamData->HeaderActive);
- break;
- case SBR_SWITCH_LRC:
- {
- INT payloadbitsLR;
- INT payloadbitsCOUPLING;
-
- SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
- SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
- INT upDateNrgTemp[MAX_NUM_CHANNELS];
- INT upDateNoiseTemp[MAX_NUM_CHANNELS];
- INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
- INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
-
- INT tempFlagRight = 0;
- INT tempFlagLeft = 0;
-
- /*
- Store previous values, in order to be able to "undo" what is being done.
- */
-
- for(ch = 0; ch < nChannels;ch++){
- FDKmemcpy (sfbNrgPrevTemp[ch], h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
- MAX_FREQ_COEFFS * sizeof (SCHAR));
-
- FDKmemcpy (noisePrevTemp[ch], h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
- MAX_NUM_NOISE_COEFFS * sizeof (SCHAR));
-
- upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
- upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
-
- /*
- forbid time coding in the first envelope in case of a different
- previous stereomode
- */
- if(sbrHeaderData->prev_coupling){
- h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
- h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
- }
- } /* ch */
-
-
- /*
- Code ordinary Left/Right stereo
- */
- FDKsbrEnc_codeEnvelope (eData[0].sfb_nrg, eData[0].frame_info->freqRes,
- &h_envChan[0]->sbrCodeEnvelope,
- h_envChan[0]->encEnvData.domain_vec, 0,
- eData[0].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
- FDKsbrEnc_codeEnvelope (eData[1].sfb_nrg, eData[1].frame_info->freqRes,
- &h_envChan[1]->sbrCodeEnvelope,
- h_envChan[1]->encEnvData.domain_vec, 0,
- eData[1].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
-
- c = 0;
- for (i = 0; i < eData[0].nEnvelopes; i++) {
- for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++)
- {
- h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
- h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
- c++;
- }
- }
-
-
-
- FDKsbrEnc_codeEnvelope (eData[0].noise_level, fData->res,
- &h_envChan[0]->sbrCodeNoiseFloor,
- h_envChan[0]->encEnvData.domain_vec_noise, 0,
- (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
-
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
- h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
-
-
- FDKsbrEnc_codeEnvelope (eData[1].noise_level, fData->res,
- &h_envChan[1]->sbrCodeNoiseFloor,
- h_envChan[1]->encEnvData.domain_vec_noise, 0,
- (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
- h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
-
-
- sbrHeaderData->coupling = 0;
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 0;
-
- payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement (sbrHeaderData,
- hParametricStereo,
- sbrBitstreamData,
- &h_envChan[0]->encEnvData,
- &h_envChan[1]->encEnvData,
- hCmonData,
- h_con->sbrSyntaxFlags);
-
- /*
- swap saved stored with current values
- */
- for(ch = 0; ch < nChannels;ch++){
- INT itmp;
- for(i=0;i<MAX_FREQ_COEFFS;i++){
- /*
- swap sfb energies
- */
- itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
- h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i]=sfbNrgPrevTemp[ch][i];
- sfbNrgPrevTemp[ch][i]=itmp;
- }
- for(i=0;i<MAX_NUM_NOISE_COEFFS;i++){
- /*
- swap noise energies
- */
- itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
- h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i]=noisePrevTemp[ch][i];
- noisePrevTemp[ch][i]=itmp;
- }
- /* swap update flags */
- itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
- h_envChan[ch]->sbrCodeEnvelope.upDate=upDateNrgTemp[ch];
- upDateNrgTemp[ch] = itmp;
-
- itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
- h_envChan[ch]->sbrCodeNoiseFloor.upDate=upDateNoiseTemp[ch];
- upDateNoiseTemp[ch]=itmp;
-
- /*
- save domain vecs
- */
- FDKmemcpy(domainVecTemp[ch],h_envChan[ch]->encEnvData.domain_vec,sizeof(INT)*MAX_ENVELOPES);
- FDKmemcpy(domainVecNoiseTemp[ch],h_envChan[ch]->encEnvData.domain_vec_noise,sizeof(INT)*MAX_ENVELOPES);
-
- /*
- forbid time coding in the first envelope in case of a different
- previous stereomode
- */
-
- if(!sbrHeaderData->prev_coupling){
- h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
- h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
- }
- } /* ch */
-
-
- /*
- Coupling
- */
-
- FDKsbrEnc_codeEnvelope (eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
- &h_envChan[0]->sbrCodeEnvelope,
- h_envChan[0]->encEnvData.domain_vec, 1,
- eData[0].frame_info->nEnvelopes, 0,
- sbrBitstreamData->HeaderActive);
-
- FDKsbrEnc_codeEnvelope (eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
- &h_envChan[1]->sbrCodeEnvelope,
- h_envChan[1]->encEnvData.domain_vec, 1,
- eData[1].frame_info->nEnvelopes, 1,
- sbrBitstreamData->HeaderActive);
-
-
- c = 0;
- for (i = 0; i < eData[0].nEnvelopes; i++) {
- for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
- h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg_coupling[c];
- h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg_coupling[c];
- c++;
- }
- }
-
- FDKsbrEnc_codeEnvelope (eData[0].noise_level_coupling, fData->res,
- &h_envChan[0]->sbrCodeNoiseFloor,
- h_envChan[0]->encEnvData.domain_vec_noise, 1,
- (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
- sbrBitstreamData->HeaderActive);
-
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
- h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level_coupling[i];
-
-
- FDKsbrEnc_codeEnvelope (eData[1].noise_level_coupling, fData->res,
- &h_envChan[1]->sbrCodeNoiseFloor,
- h_envChan[1]->encEnvData.domain_vec_noise, 1,
- (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
- sbrBitstreamData->HeaderActive);
-
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
- h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level_coupling[i];
-
- sbrHeaderData->coupling = 1;
-
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 1;
-
- tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
- tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
-
- payloadbitsCOUPLING =
- FDKsbrEnc_CountSbrChannelPairElement (sbrHeaderData,
- hParametricStereo,
- sbrBitstreamData,
- &h_envChan[0]->encEnvData,
- &h_envChan[1]->encEnvData,
- hCmonData,
- h_con->sbrSyntaxFlags);
-
-
- h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
- h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
-
- if (payloadbitsCOUPLING < payloadbitsLR) {
-
- /*
- copy coded coupling envelope and noise data to l/r
- */
- for(ch = 0; ch < nChannels;ch++){
- SBR_ENV_TEMP_DATA *ed = &eData[ch];
- FDKmemcpy (ed->sfb_nrg, ed->sfb_nrg_coupling,
- MAX_NUM_ENVELOPE_VALUES * sizeof (SCHAR));
- FDKmemcpy (ed->noise_level, ed->noise_level_coupling,
- MAX_NUM_NOISE_VALUES * sizeof (SCHAR));
- }
-
- sbrHeaderData->coupling = 1;
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 1;
- }
- else{
- /*
- restore saved l/r items
- */
- for(ch = 0; ch < nChannels;ch++){
-
- FDKmemcpy (h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
- sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof (SCHAR));
-
- h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
-
- FDKmemcpy (h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
- noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof (SCHAR));
-
- FDKmemcpy (h_envChan[ch]->encEnvData.domain_vec,domainVecTemp[ch],sizeof(INT)*MAX_ENVELOPES);
- FDKmemcpy (h_envChan[ch]->encEnvData.domain_vec_noise,domainVecNoiseTemp[ch],sizeof(INT)*MAX_ENVELOPES);
-
- h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
- }
-
- sbrHeaderData->coupling = 0;
- h_envChan[0]->encEnvData.balance = 0;
- h_envChan[1]->encEnvData.balance = 0;
- }
- }
- break;
- } /* switch */
-
-
- /* tell the envelope encoders how long it has been, since we last sent
- a frame starting with a dF-coded envelope */
- if (stereoMode == SBR_MONO ) {
- if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
- h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
- else
- h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
- }
- else {
- if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
- h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
- h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
- h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
- }
- else {
- h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
- h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
- }
- }
-
- /*
- Send the encoded data to the bitstream
- */
- for(ch = 0; ch < nChannels;ch++){
- SBR_ENV_TEMP_DATA *ed = &eData[ch];
- c = 0;
- for (i = 0; i < ed->nEnvelopes; i++) {
- for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
- h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
-
- c++;
- }
- }
- for (i = 0; i < MAX_NUM_NOISE_VALUES; i++){
- h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
- }
- }/* ch */
-
-
- /*
- Write bitstream
- */
- if (nChannels == 2) {
- FDKsbrEnc_WriteEnvChannelPairElement(sbrHeaderData,
- hParametricStereo,
- sbrBitstreamData,
- &h_envChan[0]->encEnvData,
- &h_envChan[1]->encEnvData,
- hCmonData,
- h_con->sbrSyntaxFlags);
- }
- else {
- FDKsbrEnc_WriteEnvSingleChannelElement(sbrHeaderData,
- hParametricStereo,
- sbrBitstreamData,
- &h_envChan[0]->encEnvData,
- hCmonData,
- h_con->sbrSyntaxFlags);
- }
-
- /*
- * Update buffers.
- */
- for (ch=0; ch<nChannels; ch++)
- {
- int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >> h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
- for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
- FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
- h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
- sizeof(FIXP_DBL)*QMF_CHANNELS);
- }
- h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] = h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
- }
-
- sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
-}
-
-/***************************************************************************/
-/*!
-
- \brief creates an envelope extractor handle
-
- \return error status
-
-****************************************************************************/
-INT
-FDKsbrEnc_CreateExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
- INT channel
- ,INT chInEl
- ,UCHAR* dynamic_RAM
- )
-{
- INT i;
- FIXP_DBL* YBuffer = GetRam_Sbr_envYBuffer(channel);
-
- FDKmemclear(hSbrCut,sizeof(SBR_EXTRACT_ENVELOPE));
- hSbrCut->p_YBuffer = YBuffer;
-
-
- for (i = 0; i < (QMF_MAX_TIME_SLOTS>>1); i++) {
- hSbrCut->YBuffer[i] = YBuffer + (i*QMF_CHANNELS);
- }
- FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
- INT n=0;
- for (; i < QMF_MAX_TIME_SLOTS; i++,n++) {
- hSbrCut->YBuffer[i] = YBufferDyn + (n*QMF_CHANNELS);
- }
-
- FIXP_DBL* rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
- FIXP_DBL* iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
-
- for (i = 0; i < QMF_MAX_TIME_SLOTS; i++) {
- hSbrCut->rBuffer[i] = rBuffer + (i*QMF_CHANNELS);
- hSbrCut->iBuffer[i] = iBuffer + (i*QMF_CHANNELS);
- }
-
- return 0;
-}
-
-
-/***************************************************************************/
-/*!
-
- \brief Initialize an envelope extractor instance.
-
- \return error status
-
-****************************************************************************/
-INT
-FDKsbrEnc_InitExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
- int no_cols,
- int no_rows,
- int start_index,
- int time_slots,
- int time_step,
- int tran_off,
- ULONG statesInitFlag
- ,int chInEl
- ,UCHAR* dynamic_RAM
- ,UINT sbrSyntaxFlags
- )
-{
- int YBufferLength, rBufferLength;
- int i;
-
- if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
- int off = TRANSIENT_OFFSET_LD;
-#ifndef FULL_DELAY
- hSbrCut->YBufferWriteOffset = (no_cols>>1)+off*time_step;
-#else
- hSbrCut->YBufferWriteOffset = no_cols+off*time_step;
-#endif
- } else
- {
- hSbrCut->YBufferWriteOffset = tran_off*time_step;
- }
- hSbrCut->rBufferReadOffset = 0;
-
-
- YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
- rBufferLength = no_cols;
-
- hSbrCut->pre_transient_info[0] = 0;
- hSbrCut->pre_transient_info[1] = 0;
-
-
- hSbrCut->no_cols = no_cols;
- hSbrCut->no_rows = no_rows;
- hSbrCut->start_index = start_index;
-
- hSbrCut->time_slots = time_slots;
- hSbrCut->time_step = time_step;
-
- FDK_ASSERT(no_rows <= QMF_CHANNELS);
-
- /* Use half the Energy values if time step is 2 or greater */
- if (time_step >= 2)
- hSbrCut->YBufferSzShift = 1;
- else
- hSbrCut->YBufferSzShift = 0;
-
- YBufferLength >>= hSbrCut->YBufferSzShift;
- hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
-
- FDK_ASSERT(YBufferLength<=QMF_MAX_TIME_SLOTS);
-
- FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
- INT n=0;
- for (i=(QMF_MAX_TIME_SLOTS>>1); i < QMF_MAX_TIME_SLOTS; i++,n++) {
- hSbrCut->YBuffer[i] = YBufferDyn + (n*QMF_CHANNELS);
- }
-
- if(statesInitFlag) {
- for (i=0; i<YBufferLength; i++) {
- FDKmemclear( hSbrCut->YBuffer[i],QMF_CHANNELS*sizeof(FIXP_DBL));
- }
- }
-
- for (i = 0; i < rBufferLength; i++) {
- FDKmemclear( hSbrCut->rBuffer[i],QMF_CHANNELS*sizeof(FIXP_DBL));
- FDKmemclear( hSbrCut->iBuffer[i],QMF_CHANNELS*sizeof(FIXP_DBL));
- }
-
- FDKmemclear (hSbrCut->envelopeCompensation,sizeof(UCHAR)*MAX_FREQ_COEFFS);
-
- if(statesInitFlag) {
- hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS-1;
- }
-
- return (0);
-}
-
-
-
-
-/***************************************************************************/
-/*!
-
- \brief deinitializes an envelope extractor handle
-
- \return void
-
-****************************************************************************/
-
-void
-FDKsbrEnc_deleteExtractSbrEnvelope (HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut)
-{
-
- if (hSbrCut) {
- FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
- }
-}
-
-INT
-FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr)
-{
- return hSbr->no_rows*((hSbr->YBufferWriteOffset)*2 /* mult 2 because nrg's are grouped half */
- - hSbr->rBufferReadOffset ); /* in reference hold half spec and calc nrg's on overlapped spec */
-
-}
-
-
-
-