summaryrefslogtreecommitdiffstats
path: root/libSBRdec/src/env_calc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libSBRdec/src/env_calc.cpp')
-rw-r--r--libSBRdec/src/env_calc.cpp2229
1 files changed, 0 insertions, 2229 deletions
diff --git a/libSBRdec/src/env_calc.cpp b/libSBRdec/src/env_calc.cpp
deleted file mode 100644
index ade57fc..0000000
--- a/libSBRdec/src/env_calc.cpp
+++ /dev/null
@@ -1,2229 +0,0 @@
-
-/* -----------------------------------------------------------------------------------------------------------
-Software License for The Fraunhofer FDK AAC Codec Library for Android
-
-© Copyright 1995 - 2013 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
------------------------------------------------------------------------------------------------------------ */
-
-/*!
- \file
- \brief Envelope calculation
-
- The envelope adjustor compares the energies present in the transposed
- highband to the reference energies conveyed with the bitstream.
- The highband is amplified (sometimes) or attenuated (mostly) to the
- desired level.
-
- The spectral shape of the reference energies can be changed several times per
- frame if necessary. Each set of energy values corresponding to a certain range
- in time will be called an <em>envelope</em> here.
- The bitstream supports several frequency scales and two resolutions. Normally,
- one or more QMF-subbands are grouped to one SBR-band. An envelope contains
- reference energies for each SBR-band.
- In addition to the energy envelopes, noise envelopes are transmitted that
- define the ratio of energy which is generated by adding noise instead of
- transposing the lowband. The noise envelopes are given in a coarser time
- and frequency resolution.
- If a signal contains strong tonal components, synthetic sines can be
- generated in individual SBR bands.
-
- An overlap buffer of 6 QMF-timeslots is used to allow a more
- flexible alignment of the envelopes in time that is not restricted to the
- core codec's frame borders.
- Therefore the envelope adjustor has access to the spectral data of the
- current frame as well as the last 6 QMF-timeslots of the previous frame.
- However, in average only the data of 1 frame is being processed as
- the adjustor is called once per frame.
-
- Depending on the frequency range set in the bitstream, only QMF-subbands between
- <em>lowSubband</em> and <em>highSubband</em> are adjusted.
-
- Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a special Mantissa-Exponent format
- ( see calculateSbrEnvelope() ) are being used. The main entry point for this modules is calculateSbrEnvelope().
-
- \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref documentationOverview
-*/
-
-
-#include "env_calc.h"
-
-#include "sbrdec_freq_sca.h"
-#include "env_extr.h"
-#include "transcendent.h"
-#include "sbr_ram.h"
-#include "sbr_rom.h"
-
-#include "genericStds.h" /* need FDKpow() for debug outputs */
-
-#if defined(__arm__)
-#include "arm/env_calc_arm.cpp"
-#endif
-
-typedef struct
-{
- FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
- FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
- FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
- FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
- FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
-
- SCHAR nrgRef_e[MAX_FREQ_COEFFS];
- SCHAR nrgEst_e[MAX_FREQ_COEFFS];
- SCHAR nrgGain_e[MAX_FREQ_COEFFS];
- SCHAR noiseLevel_e[MAX_FREQ_COEFFS];
- SCHAR nrgSine_e[MAX_FREQ_COEFFS];
-}
-ENV_CALC_NRGS;
-
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
- SCHAR *filtBuffer_e,
- FIXP_DBL *NrgGain,
- SCHAR *NrgGain_e,
- int subbands);
-
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
- FIXP_DBL **analysBufferImag,
- int lowSubband, int highSubband,
- int start_pos, int next_pos,
- SCHAR frameExp,
- FIXP_DBL *nrgEst,
- SCHAR *nrgEst_e );
-
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
- FIXP_DBL **analysBufferImag,
- int nSfb,
- UCHAR *freqBandTable,
- int start_pos, int next_pos,
- SCHAR input_e,
- FIXP_DBL *nrg_est,
- SCHAR *nrg_est_e );
-
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
- FIXP_DBL tmpNoise, SCHAR tmpNoise_e,
- UCHAR sinePresentFlag,
- UCHAR sineMapped,
- int noNoiseFlag);
-
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
- int lowSubband,
- int highSubband,
- FIXP_DBL *sumRef_m,
- SCHAR *sumRef_e,
- FIXP_DBL *ptrAvgGain_m,
- SCHAR *ptrAvgGain_e);
-
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal,
- ENV_CALC_NRGS* nrgs,
- UCHAR *ptrHarmIndex,
- int lowSubbands,
- int noSubbands,
- int scale_change,
- int noNoiseFlag,
- int *ptrPhaseIndex,
- int fCldfb);
-/*static*/ void adjustTimeSlotHQ(FIXP_DBL *ptrReal,
- FIXP_DBL *ptrImag,
- HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
- ENV_CALC_NRGS* nrgs,
- int lowSubbands,
- int noSubbands,
- int scale_change,
- FIXP_SGL smooth_ratio,
- int noNoiseFlag,
- int filtBufferNoiseShift);
-
-
-/*!
- \brief Map sine flags from bitstream to QMF bands
-
- The bitstream carries only 1 sine flag per band and frame.
- This function maps every sine flag from the bitstream to a specific QMF subband
- and to a specific envelope where the sine shall start.
- The result is stored in the vector sineMapped which contains one entry per
- QMF subband. The value of an entry specifies the envelope where a sine
- shall start. A value of #MAX_ENVELOPES indicates that no sine is present
- in the subband.
- The missing harmonics flags from the previous frame (harmFlagsPrev) determine
- if a sine starts at the beginning of the frame or at the transient position.
- Additionally, the flags in harmFlagsPrev are being updated by this function
- for the next frame.
-*/
-/*static*/ void mapSineFlags(UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
- int nSfb, /*!< Number of bands in the table */
- UCHAR *addHarmonics, /*!< vector with 1 flag per sfb */
- int *harmFlagsPrev, /*!< Packed 'addHarmonics' */
- int tranEnv, /*!< Transient position */
- SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each QMF band */
-
-{
- int i;
- int lowSubband2 = freqBandTable[0]<<1;
- int bitcount = 0;
- int oldflags = *harmFlagsPrev;
- int newflags = 0;
-
- /*
- Format of harmFlagsPrev:
-
- first word = flags for highest 16 sfb bands in use
- second word = flags for next lower 16 sfb bands (if present)
- third word = flags for lowest 16 sfb bands (if present)
-
- Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
- The lowest bit of the first word corresponds to the _highest_ sfb band in use.
- This is ensures that each flag is mapped to the same QMF band even after a
- change of the crossover-frequency.
- */
-
-
- /* Reset the output vector first */
- FDKmemset(sineMapped, MAX_ENVELOPES,MAX_FREQ_COEFFS); /* MAX_ENVELOPES means 'no sine' */
-
- freqBandTable += nSfb;
- addHarmonics += nSfb-1;
-
- for (i=nSfb; i!=0; i--) {
- int ui = *freqBandTable--; /* Upper limit of the current scale factor band. */
- int li = *freqBandTable; /* Lower limit of the current scale factor band. */
-
- if ( *addHarmonics-- ) { /* There is a sine in this band */
-
- unsigned int mask = 1 << bitcount;
- newflags |= mask; /* Set flag */
-
- /*
- If there was a sine in the last frame, let it continue from the first envelope on
- else start at the transient position.
- */
- sineMapped[(ui+li-lowSubband2) >> 1] = ( oldflags & mask ) ? 0 : tranEnv;
- }
-
- if ((++bitcount == 16) || i==1) {
- bitcount = 0;
- *harmFlagsPrev++ = newflags;
- oldflags = *harmFlagsPrev; /* Fetch 16 of the old flags */
- newflags = 0;
- }
- }
-}
-
-
-/*!
- \brief Reduce gain-adjustment induced aliasing for real valued filterbank.
-*/
-/*static*/ void
-aliasingReduction(FIXP_DBL* degreeAlias, /*!< estimated aliasing for each QMF channel */
- ENV_CALC_NRGS* nrgs,
- int* useAliasReduction, /*!< synthetic sine engergy for each subband, used as flag */
- int noSubbands) /*!< number of QMF channels to process */
-{
- FIXP_DBL* nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
- SCHAR* nrgGain_e = nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
- FIXP_DBL* nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
- SCHAR* nrgEst_e = nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
- int grouping = 0, index = 0, noGroups, k;
- int groupVector[MAX_FREQ_COEFFS];
-
- /* Calculate grouping*/
- for (k = 0; k < noSubbands-1; k++ ){
- if ( (degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k] ) {
- if(grouping==0){
- groupVector[index++] = k;
- grouping = 1;
- }
- else{
- if(groupVector[index-1] + 3 == k){
- groupVector[index++] = k + 1;
- grouping = 0;
- }
- }
- }
- else{
- if(grouping){
- if(useAliasReduction[k])
- groupVector[index++] = k + 1;
- else
- groupVector[index++] = k;
- grouping = 0;
- }
- }
- }
-
- if(grouping){
- groupVector[index++] = noSubbands;
- }
- noGroups = index >> 1;
-
-
- /*Calculate new gain*/
- for (int group = 0; group < noGroups; group ++) {
- FIXP_DBL nrgOrig = FL2FXCONST_DBL(0.0f); /* Original signal energy in current group of bands */
- SCHAR nrgOrig_e = 0;
- FIXP_DBL nrgAmp = FL2FXCONST_DBL(0.0f); /* Amplified signal energy in group (using current gains) */
- SCHAR nrgAmp_e = 0;
- FIXP_DBL nrgMod = FL2FXCONST_DBL(0.0f); /* Signal energy in group when applying modified gains */
- SCHAR nrgMod_e = 0;
- FIXP_DBL groupGain; /* Total energy gain in group */
- SCHAR groupGain_e;
- FIXP_DBL compensation; /* Compensation factor for the energy change when applying modified gains */
- SCHAR compensation_e;
-
- int startGroup = groupVector[2*group];
- int stopGroup = groupVector[2*group+1];
-
- /* Calculate total energy in group before and after amplification with current gains: */
- for(k = startGroup; k < stopGroup; k++){
- /* Get original band energy */
- FIXP_DBL tmp = nrgEst[k];
- SCHAR tmp_e = nrgEst_e[k];
-
- FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
-
- /* Multiply band energy with current gain */
- tmp = fMult(tmp,nrgGain[k]);
- tmp_e = tmp_e + nrgGain_e[k];
-
- FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
- }
-
- /* Calculate total energy gain in group */
- FDK_divide_MantExp(nrgAmp, nrgAmp_e,
- nrgOrig, nrgOrig_e,
- &groupGain, &groupGain_e);
-
- for(k = startGroup; k < stopGroup; k++){
- FIXP_DBL tmp;
- SCHAR tmp_e;
-
- FIXP_DBL alpha = degreeAlias[k];
- if (k < noSubbands - 1) {
- if (degreeAlias[k + 1] > alpha)
- alpha = degreeAlias[k + 1];
- }
-
- /* Modify gain depending on the degree of aliasing */
- FDK_add_MantExp( fMult(alpha,groupGain), groupGain_e,
- fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,nrgGain[k]), nrgGain_e[k],
- &nrgGain[k], &nrgGain_e[k] );
-
- /* Apply modified gain to original energy */
- tmp = fMult(nrgGain[k],nrgEst[k]);
- tmp_e = nrgGain_e[k] + nrgEst_e[k];
-
- /* Accumulate energy with modified gains applied */
- FDK_add_MantExp( tmp, tmp_e,
- nrgMod, nrgMod_e,
- &nrgMod, &nrgMod_e );
- }
-
- /* Calculate compensation factor to retain the energy of the amplified signal */
- FDK_divide_MantExp(nrgAmp, nrgAmp_e,
- nrgMod, nrgMod_e,
- &compensation, &compensation_e);
-
- /* Apply compensation factor to all gains of the group */
- for(k = startGroup; k < stopGroup; k++){
- nrgGain[k] = fMult(nrgGain[k],compensation);
- nrgGain_e[k] = nrgGain_e[k] + compensation_e;
- }
- }
-}
-
-
- /* Convert headroom bits to exponent */
-#define SCALE2EXP(s) (15-(s))
-#define EXP2SCALE(e) (15-(e))
-
-/*!
- \brief Apply spectral envelope to subband samples
-
- This function is called from sbr_dec.cpp in each frame.
-
- To enhance accuracy and due to the usage of tables for squareroots and
- inverse, some calculations are performed with the operands being split
- into mantissa and exponent. The variable names in the source code carry
- the suffixes <em>_m</em> and <em>_e</em> respectively. The control data
- in #hFrameData containts envelope data which is represented by this format but
- stored in single words. (See requantizeEnvelopeData() for details). This data
- is unpacked within calculateSbrEnvelope() to follow the described suffix convention.
-
- The actual value (comparable to the corresponding float-variable in the
- research-implementation) of a mantissa/exponent-pair can be calculated as
-
- \f$ value = value\_m * 2^{value\_e} \f$
-
- All energies and noise levels decoded from the bitstream suit for an
- original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore,
- the scale factor <em>hb_scale</em> passed into this function will be converted
- to an 'input exponent' (#input_e), which fits the internal representation.
-
- Before the actual processing, an exponent #adj_e for resulting adjusted
- samples is derived from the maximum reference energy.
-
- Then, for each envelope, the following steps are performed:
-
- \li Calculate energy in the signal to be adjusted. Depending on the the value of
- #interpolFreq (interpolation mode), this is either done seperately
- for each QMF-subband or for each SBR-band.
- The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas)
- and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents).
- \li Calculate gain and noise level for each subband:<br>
- \f$ gain = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) }
- \hspace{2cm}
- noise = \sqrt{ nrgRef \cdot noiseRatio }
- \f$<br>
- where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the
- bitstream and <em>nrgEst</em> is the subband energy before adjustment.
- The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS]
- (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels
- are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS]
- (exponents).
- The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS]
- and #nrgSine_e[#MAX_FREQ_COEFFS].
- \li Noise limiting: The gain for each subband is limited both absolutely
- and relatively compared to the total gain over all subbands.
- \li Boost gain: Calculate and apply boost factor for each limiter band
- in order to compensate for the energy loss imposed by the limiting.
- \li Apply gains and add noise: The gains and noise levels are applied
- to all timeslots of the current envelope. A short FIR-filter (length 4
- QMF-timeslots) can be used to smooth the sudden change at the envelope borders.
- Each complex subband sample of the current timeslot is multiplied by the
- smoothed gain, then random noise with the calculated level is added.
-
- \note
- To reduce the stack size, some of the local arrays could be located within
- the time output buffer. Of the 512 samples temporarily available there,
- about half the size is already used by #SBR_FRAME_DATA. A pointer to the
- remaining free memory could be supplied by an additional argument to calculateSbrEnvelope()
- in sbr_dec:
-
- \par
- \code
- calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
- &hSbrDec->SbrCalculateEnvelope,
- hHeaderData,
- hFrameData,
- QmfBufferReal,
- QmfBufferImag,
- timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1);
- \endcode
-
- \par
- Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays
- #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
-
- \par
- \code
- fract* nrgRef_m = timeOutPtr;
- SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
- fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
- SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
- fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
- \endcode
-
- <br>
-*/
-void
-calculateSbrEnvelope (QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
- HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
- HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
- HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */
- FIXP_DBL **analysBufferReal, /*!< Real part of subband samples to be processed */
- FIXP_DBL **analysBufferImag, /*!< Imag part of subband samples to be processed */
- const int useLP,
- FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
- const UINT flags,
- const int frameErrorFlag
- )
-{
- int c, i, j, envNoise = 0;
- UCHAR* borders = hFrameData->frameInfo.borders;
-
- FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
- HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
-
- int lowSubband = hFreq->lowSubband;
- int highSubband = hFreq->highSubband;
- int noSubbands = highSubband - lowSubband;
-
- int noNoiseBands = hFreq->nNfb;
- int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
- UCHAR first_start = borders[0] * hHeaderData->timeStep;
-
- SCHAR sineMapped[MAX_FREQ_COEFFS];
- SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
- SCHAR adj_e = 0;
- SCHAR output_e;
- SCHAR final_e = 0;
-
- SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
-
- int useAliasReduction[64];
- UCHAR smooth_length = 0;
-
- FIXP_SGL * pIenv = hFrameData->iEnvelope;
-
- /*
- Extract sine flags for all QMF bands
- */
- mapSineFlags(hFreq->freqBandTable[1],
- hFreq->nSfb[1],
- hFrameData->addHarmonics,
- h_sbr_cal_env->harmFlagsPrev,
- hFrameData->frameInfo.tranEnv,
- sineMapped);
-
-
- /*
- Scan for maximum in bufferd noise levels.
- This is needed in case that we had strong noise in the previous frame
- which is smoothed into the current frame.
- The resulting exponent is used as start value for the maximum search
- in reference energies
- */
- if (!useLP)
- adj_e = h_sbr_cal_env->filtBufferNoise_e - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
-
- /*
- Scan for maximum reference energy to be able
- to select appropriate values for adj_e and final_e.
- */
-
- for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
- INT maxSfbNrg_e = -FRACT_BITS+NRG_EXP_OFFSET; /* start value for maximum search */
-
- /* Fetch frequency resolution for current envelope: */
- for (j=hFreq->nSfb[hFrameData->frameInfo.freqRes[i]]; j!=0; j--) {
- maxSfbNrg_e = fixMax(maxSfbNrg_e,(INT)((LONG)(*pIenv++) & MASK_E));
- }
- maxSfbNrg_e -= NRG_EXP_OFFSET;
-
- /* Energy -> magnitude (sqrt halfens exponent) */
- maxSfbNrg_e = (maxSfbNrg_e+1) >> 1; /* +1 to go safe (round to next higher int) */
-
- /* Some safety margin is needed for 2 reasons:
- - The signal energy is not equally spread over all subband samples in
- a specific sfb of an envelope (Nrg could be too high by a factor of
- envWidth * sfbWidth)
- - Smoothing can smear high gains of the previous envelope into the current
- */
- maxSfbNrg_e += 6;
-
- if (borders[i] < hHeaderData->numberTimeSlots)
- /* This envelope affects timeslots that belong to the output frame */
- adj_e = (maxSfbNrg_e > adj_e) ? maxSfbNrg_e : adj_e;
-
- if (borders[i+1] > hHeaderData->numberTimeSlots)
- /* This envelope affects timeslots after the output frame */
- final_e = (maxSfbNrg_e > final_e) ? maxSfbNrg_e : final_e;
-
- }
-
- /*
- Calculate adjustment factors and apply them for every envelope.
- */
- pIenv = hFrameData->iEnvelope;
-
- for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
-
- int k, noNoiseFlag;
- SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
- C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
-
- /*
- Helper variables.
- */
- UCHAR start_pos = hHeaderData->timeStep * borders[i]; /* Start-position in time (subband sample) for current envelope. */
- UCHAR stop_pos = hHeaderData->timeStep * borders[i+1]; /* Stop-position in time (subband sample) for current envelope. */
- UCHAR freq_res = hFrameData->frameInfo.freqRes[i]; /* Frequency resolution for current envelope. */
-
-
- /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in
- cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit
- errors and is tested by some streams from the certification set. */
- FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
-
- /* If the start-pos of the current envelope equals the stop pos of the current
- noise envelope, increase the pointer (i.e. choose the next noise-floor).*/
- if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise+1]){
- noiseLevels += noNoiseBands; /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/
- envNoise++;
- }
-
- if(i==hFrameData->frameInfo.tranEnv || i==h_sbr_cal_env->prevTranEnv) /* attack */
- {
- noNoiseFlag = 1;
- if (!useLP)
- smooth_length = 0; /* No smoothing on attacks! */
- }
- else {
- noNoiseFlag = 0;
- if (!useLP)
- smooth_length = (1 - hHeaderData->bs_data.smoothingLength) << 2; /* can become either 0 or 4 */
- }
-
-
- /*
- Energy estimation in transposed highband.
- */
- if (hHeaderData->bs_data.interpolFreq)
- calcNrgPerSubband(analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- lowSubband, highSubband,
- start_pos, stop_pos,
- input_e,
- pNrgs->nrgEst,
- pNrgs->nrgEst_e);
- else
- calcNrgPerSfb(analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- hFreq->nSfb[freq_res],
- hFreq->freqBandTable[freq_res],
- start_pos, stop_pos,
- input_e,
- pNrgs->nrgEst,
- pNrgs->nrgEst_e);
-
- /*
- Calculate subband gains
- */
- {
- UCHAR * table = hFreq->freqBandTable[freq_res];
- UCHAR * pUiNoise = &hFreq->freqBandTableNoise[1]; /*! Upper limit of the current noise floor band. */
-
- FIXP_SGL * pNoiseLevels = noiseLevels;
-
- FIXP_DBL tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
- SCHAR tmpNoise_e = (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
-
- int cc = 0;
- c = 0;
- for (j = 0; j < hFreq->nSfb[freq_res]; j++) {
-
- FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
- SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
-
- UCHAR sinePresentFlag = 0;
- int li = table[j];
- int ui = table[j+1];
-
- for (k=li; k<ui; k++) {
- sinePresentFlag |= (i >= sineMapped[cc]);
- cc++;
- }
-
- for (k=li; k<ui; k++) {
- if (k >= *pUiNoise) {
- tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
- tmpNoise_e = (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
-
- pUiNoise++;
- }
-
- FDK_ASSERT(k >= lowSubband);
-
- if (useLP)
- useAliasReduction[k-lowSubband] = !sinePresentFlag;
-
- pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
- pNrgs->nrgSine_e[c] = 0;
-
- calcSubbandGain(refNrg, refNrg_e, pNrgs, c,
- tmpNoise, tmpNoise_e,
- sinePresentFlag, i >= sineMapped[c],
- noNoiseFlag);
-
- pNrgs->nrgRef[c] = refNrg;
- pNrgs->nrgRef_e[c] = refNrg_e;
-
- c++;
- }
- pIenv++;
- }
- }
-
- /*
- Noise limiting
- */
-
- for (c = 0; c < hFreq->noLimiterBands; c++) {
-
- FIXP_DBL sumRef, boostGain, maxGain;
- FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
- SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
-
- calcAvgGain(pNrgs,
- hFreq->limiterBandTable[c], hFreq->limiterBandTable[c+1],
- &sumRef, &sumRef_e,
- &maxGain, &maxGain_e);
-
- /* Multiply maxGain with limiterGain: */
- maxGain = fMult(maxGain, FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
- maxGain_e += FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
-
- /* Scale mantissa of MaxGain into range between 0.5 and 1: */
- if (maxGain == FL2FXCONST_DBL(0.0f))
- maxGain_e = -FRACT_BITS;
- else {
- SCHAR charTemp = CountLeadingBits(maxGain);
- maxGain_e -= charTemp;
- maxGain <<= (int)charTemp;
- }
-
- if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
- maxGain = FL2FXCONST_DBL(0.5f);
- maxGain_e = maxGainLimit_e;
- }
-
-
- /* Every subband gain is compared to the scaled "average gain"
- and limited if necessary: */
- for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c+1]; k++) {
- if ( (pNrgs->nrgGain_e[k] > maxGain_e) || (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k]>maxGain) ) {
-
- FIXP_DBL noiseAmp;
- SCHAR noiseAmp_e;
-
- FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
- pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k],noiseAmp);
- pNrgs->noiseLevel_e[k] += noiseAmp_e;
- pNrgs->nrgGain[k] = maxGain;
- pNrgs->nrgGain_e[k] = maxGain_e;
- }
- }
-
- /* -- Boost gain
- Calculate and apply boost factor for each limiter band:
- 1. Check how much energy would be present when using the limited gain
- 2. Calculate boost factor by comparison with reference energy
- 3. Apply boost factor to compensate for the energy loss due to limiting
- */
- for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
-
- /* 1.a Add energy of adjusted signal (using preliminary gain) */
- FIXP_DBL tmp = fMult(pNrgs->nrgGain[k],pNrgs->nrgEst[k]);
- SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
- FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
-
- /* 1.b Add sine energy (if present) */
- if(pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
- FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, &accu, &accu_e);
- }
- else {
- /* 1.c Add noise energy (if present) */
- if(noNoiseFlag == 0) {
- FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, accu_e, &accu, &accu_e);
- }
- }
- }
-
- /* 2.a Calculate ratio of wanted energy and accumulated energy */
- if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
- boostGain = FL2FXCONST_DBL(0.6279716f);
- boostGain_e = 2;
- } else {
- INT div_e;
- boostGain = fDivNorm(sumRef, accu, &div_e);
- boostGain_e = sumRef_e - accu_e + div_e;
- }
-
-
- /* 2.b Result too high? --> Limit the boost factor to +4 dB */
- if((boostGain_e > 3) ||
- (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
- (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f)) )
- {
- boostGain = FL2FXCONST_DBL(0.6279716f);
- boostGain_e = 2;
- }
- /* 3. Multiply all signal components with the boost factor */
- for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
- pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k],boostGain);
- pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
-
- pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k],boostGain);
- pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
-
- pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k],boostGain);
- pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
- }
- }
- /* End of noise limiting */
-
- if (useLP)
- aliasingReduction(degreeAlias+lowSubband,
- pNrgs,
- useAliasReduction,
- noSubbands);
-
- /* For the timeslots within the range for the output frame,
- use the same scale for the noise levels.
- Drawback: If the envelope exceeds the frame border, the noise levels
- will have to be rescaled later to fit final_e of
- the gain-values.
- */
- noise_e = (start_pos < no_cols) ? adj_e : final_e;
-
- /*
- Convert energies to amplitude levels
- */
- for (k=0; k<noSubbands; k++) {
- FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
- FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], &pNrgs->nrgGain_e[k]);
- FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], &noise_e);
- }
-
-
-
- /*
- Apply calculated gains and adaptive noise
- */
-
- /* assembleHfSignals() */
- {
- int scale_change, sc_change;
- FIXP_SGL smooth_ratio;
- int filtBufferNoiseShift=0;
-
- /* Initialize smoothing buffers with the first valid values */
- if (h_sbr_cal_env->startUp)
- {
- if (!useLP) {
- h_sbr_cal_env->filtBufferNoise_e = noise_e;
-
- FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR));
- FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
- FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL));
-
- }
- h_sbr_cal_env->startUp = 0;
- }
-
- if (!useLP) {
-
- equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */
- h_sbr_cal_env->filtBuffer_e, /* buffered */
- pNrgs->nrgGain, /* current */
- pNrgs->nrgGain_e, /* current */
- noSubbands);
-
- /* Adapt exponent of buffered noise levels to the current exponent
- so they can easily be smoothed */
- if((h_sbr_cal_env->filtBufferNoise_e - noise_e)>=0) {
- int shift = fixMin(DFRACT_BITS-1,(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
- for (k=0; k<noSubbands; k++)
- h_sbr_cal_env->filtBufferNoise[k] <<= shift;
- }
- else {
- int shift = fixMin(DFRACT_BITS-1,-(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
- for (k=0; k<noSubbands; k++)
- h_sbr_cal_env->filtBufferNoise[k] >>= shift;
- }
-
- h_sbr_cal_env->filtBufferNoise_e = noise_e;
- }
-
- /* find best scaling! */
- scale_change = -(DFRACT_BITS-1);
- for(k=0;k<noSubbands;k++) {
- scale_change = fixMax(scale_change,(int)pNrgs->nrgGain_e[k]);
- }
- sc_change = (start_pos<no_cols)? adj_e - input_e : final_e - input_e;
-
- if ((scale_change-sc_change+1)<0)
- scale_change-=(scale_change-sc_change+1);
-
- scale_change = (scale_change-sc_change)+1;
-
- for(k=0;k<noSubbands;k++) {
- int sc = scale_change-pNrgs->nrgGain_e[k] + (sc_change-1);
- pNrgs->nrgGain[k] >>= sc;
- pNrgs->nrgGain_e[k] += sc;
- }
-
- if (!useLP) {
- for(k=0;k<noSubbands;k++) {
- int sc = scale_change-h_sbr_cal_env->filtBuffer_e[k] + (sc_change-1);
- h_sbr_cal_env->filtBuffer[k] >>= sc;
- }
- }
-
- for (j = start_pos; j < stop_pos; j++)
- {
- /* This timeslot is located within the first part of the processing buffer
- and will be fed into the QMF-synthesis for the current frame.
- adj_e - input_e
- This timeslot will not yet be fed into the QMF so we do not care
- about the adj_e.
- sc_change = final_e - input_e
- */
- if ( (j==no_cols) && (start_pos<no_cols) )
- {
- int shift = (int) (noise_e - final_e);
- if (!useLP)
- filtBufferNoiseShift = shift; /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */
- if (shift>=0) {
- shift = fixMin(DFRACT_BITS-1,shift);
- for (k=0; k<noSubbands; k++) {
- pNrgs->nrgSine[k] <<= shift;
- pNrgs->noiseLevel[k] <<= shift;
- /*
- if (!useLP)
- h_sbr_cal_env->filtBufferNoise[k] <<= shift;
- */
- }
- }
- else {
- shift = fixMin(DFRACT_BITS-1,-shift);
- for (k=0; k<noSubbands; k++) {
- pNrgs->nrgSine[k] >>= shift;
- pNrgs->noiseLevel[k] >>= shift;
- /*
- if (!useLP)
- h_sbr_cal_env->filtBufferNoise[k] >>= shift;
- */
- }
- }
-
- /* update noise scaling */
- noise_e = final_e;
- if (!useLP)
- h_sbr_cal_env->filtBufferNoise_e = noise_e; /* scaling value unused! */
-
- /* update gain buffer*/
- sc_change -= (final_e - input_e);
-
- if (sc_change<0) {
- for(k=0;k<noSubbands;k++) {
- pNrgs->nrgGain[k] >>= -sc_change;
- pNrgs->nrgGain_e[k] += -sc_change;
- }
- if (!useLP) {
- for(k=0;k<noSubbands;k++) {
- h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
- }
- }
- } else {
- scale_change+=sc_change;
- }
-
- } // if
-
- if (!useLP) {
-
- /* Prevent the smoothing filter from running on constant levels */
- if (j-start_pos < smooth_length)
- smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
-
- else
- smooth_ratio = FL2FXCONST_SGL(0.0f);
-
- adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
- &analysBufferImag[j][lowSubband],
- h_sbr_cal_env,
- pNrgs,
- lowSubband,
- noSubbands,
- scale_change,
- smooth_ratio,
- noNoiseFlag,
- filtBufferNoiseShift);
- }
- else
- {
- adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
- pNrgs,
- &h_sbr_cal_env->harmIndex,
- lowSubband,
- noSubbands,
- scale_change,
- noNoiseFlag,
- &h_sbr_cal_env->phaseIndex,
- (flags & SBRDEC_ELD_GRID));
- }
- } // for
-
- if (!useLP) {
- /* Update time-smoothing-buffers for gains and noise levels
- The gains and the noise values of the current envelope are copied into the buffer.
- This has to be done at the end of each envelope as the values are required for
- a smooth transition to the next envelope. */
- FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, noSubbands*sizeof(FIXP_DBL));
- FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, noSubbands*sizeof(SCHAR));
- FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
- }
-
- }
- C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
- }
-
- /* Rescale output samples */
- {
- FIXP_DBL maxVal;
- int ov_reserve, reserve;
-
- /* Determine headroom in old adjusted samples */
- maxVal = maxSubbandSample( analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- lowSubband,
- highSubband,
- 0,
- first_start);
-
- ov_reserve = fNorm(maxVal);
-
- /* Determine headroom in new adjusted samples */
- maxVal = maxSubbandSample( analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- lowSubband,
- highSubband,
- first_start,
- no_cols);
-
- reserve = fNorm(maxVal);
-
- /* Determine common output exponent */
- if (ov_adj_e - ov_reserve > adj_e - reserve ) /* set output_e to the maximum */
- output_e = ov_adj_e - ov_reserve;
- else
- output_e = adj_e - reserve;
-
- /* Rescale old samples */
- rescaleSubbandSamples( analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- lowSubband, highSubband,
- 0, first_start,
- ov_adj_e - output_e);
-
- /* Rescale new samples */
- rescaleSubbandSamples( analysBufferReal,
- (useLP) ? NULL : analysBufferImag,
- lowSubband, highSubband,
- first_start, no_cols,
- adj_e - output_e);
- }
-
- /* Update hb_scale */
- sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
-
- /* Save the current final exponent for the next frame: */
- sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e);
-
-
- /* We need to remeber to the next frame that the transient
- will occur in the first envelope (if tranEnv == nEnvelopes). */
- if(hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
- h_sbr_cal_env->prevTranEnv = 0;
- else
- h_sbr_cal_env->prevTranEnv = -1;
-
-}
-
-
-/*!
- \brief Create envelope instance
-
- Must be called once for each channel before calculateSbrEnvelope() can be used.
-
- \return errorCode, 0 if successful
-*/
-SBR_ERROR
-createSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
- HANDLE_SBR_HEADER_DATA hHeaderData, /*!< static SBR control data, initialized with defaults */
- const int chan, /*!< Channel for which to assign buffers */
- const UINT flags)
-{
- SBR_ERROR err = SBRDEC_OK;
- int i;
-
- /* Clear previous missing harmonics flags */
- for (i=0; i<(MAX_FREQ_COEFFS+15)>>4; i++) {
- hs->harmFlagsPrev[i] = 0;
- }
- hs->harmIndex = 0;
-
- /*
- Setup pointers for time smoothing.
- The buffer itself will be initialized later triggered by the startUp-flag.
- */
- hs->prevTranEnv = -1;
-
-
- /* initialization */
- resetSbrEnvelopeCalc(hs);
-
- if (chan==0) { /* do this only once */
- err = resetFreqBandTables(hHeaderData, flags);
- }
-
- return err;
-}
-
-/*!
- \brief Create envelope instance
-
- Must be called once for each channel before calculateSbrEnvelope() can be used.
-
- \return errorCode, 0 if successful
-*/
-int
-deleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs)
-{
- return 0;
-}
-
-
-/*!
- \brief Reset envelope instance
-
- This function must be called for each channel on a change of configuration.
- Note that resetFreqBandTables should also be called in this case.
-
- \return errorCode, 0 if successful
-*/
-void
-resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
-{
- hCalEnv->phaseIndex = 0;
-
- /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */
- hCalEnv->filtBufferNoise_e = 0;
-
- hCalEnv->startUp = 1;
-}
-
-
-/*!
- \brief Equalize exponents of the buffered gain values and the new ones
-
- After equalization of exponents, the FIR-filter addition for smoothing
- can be performed.
- This function is called once for each envelope before adjusting.
-*/
-/*static*/ void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, /*!< bufferd gains */
- SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */
- FIXP_DBL *nrgGain, /*!< gains for current envelope */
- SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */
- int subbands) /*!< Number of QMF subbands */
-{
- int band;
- int diff;
-
- for (band=0; band<subbands; band++){
- diff = (int) (nrgGain_e[band] - filtBuffer_e[band]);
- if (diff>0) {
- filtBuffer[band] >>= diff; /* Compensate for the scale change by shifting the mantissa. */
- filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
- }
- else if (diff<0) {
- /* The buffered gains seem to be larger, but maybe there
- are some unused bits left in the mantissa */
-
- int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band]))-1;
-
- if ((-diff) <= reserve) {
- /* There is enough space in the buffered mantissa so
- that we can take the new exponent as common.
- */
- filtBuffer[band] <<= (-diff);
- filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
- }
- else {
- filtBuffer[band] <<= reserve; /* Shift the mantissa as far as possible: */
- filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
-
- /* For the remaining difference, change the new gain value */
- diff = fixMin(-(reserve + diff),DFRACT_BITS-1);
- nrgGain[band] >>= diff;
- nrgGain_e[band] += diff;
- }
- }
- }
-}
-
-/*!
- \brief Shift left the mantissas of all subband samples
- in the giventime and frequency range by the specified number of bits.
-
- This function is used to rescale the audio data in the overlap buffer
- which has already been envelope adjusted with the last frame.
-*/
-void rescaleSubbandSamples(FIXP_DBL ** re, /*!< Real part of input and output subband samples */
- FIXP_DBL ** im, /*!< Imaginary part of input and output subband samples */
- int lowSubband, /*!< Begin of frequency range to process */
- int highSubband, /*!< End of frequency range to process */
- int start_pos, /*!< Begin of time rage (QMF-timeslot) */
- int next_pos, /*!< End of time rage (QMF-timeslot) */
- int shift) /*!< number of bits to shift */
-{
- int width = highSubband-lowSubband;
-
- if ( (width > 0) && (shift!=0) ) {
- if (im!=NULL) {
- for (int l=start_pos; l<next_pos; l++) {
- scaleValues(&re[l][lowSubband], width, shift);
- scaleValues(&im[l][lowSubband], width, shift);
- }
- } else
- {
- for (int l=start_pos; l<next_pos; l++) {
- scaleValues(&re[l][lowSubband], width, shift);
- }
- }
- }
-}
-
-
-/*!
- \brief Determine headroom for shifting
-
- Determine by how much the spectrum can be shifted left
- for better accuracy in later processing.
-
- \return Number of free bits in the biggest spectral value
-*/
-
-FIXP_DBL maxSubbandSample( FIXP_DBL ** re, /*!< Real part of input and output subband samples */
- FIXP_DBL ** im, /*!< Real part of input and output subband samples */
- int lowSubband, /*!< Begin of frequency range to process */
- int highSubband, /*!< Number of QMF bands to process */
- int start_pos, /*!< Begin of time rage (QMF-timeslot) */
- int next_pos /*!< End of time rage (QMF-timeslot) */
- )
-{
- FIXP_DBL maxVal = FL2FX_DBL(0.0f);
- unsigned int width = highSubband - lowSubband;
-
- FDK_ASSERT(width <= (64));
-
- if ( width > 0 ) {
- if (im!=NULL)
- {
- for (int l=start_pos; l<next_pos; l++)
- {
-#ifdef FUNCTION_FDK_get_maxval
- maxVal = FDK_get_maxval(maxVal, &re[l][lowSubband], &im[l][lowSubband], width);
-#else
- int k=width;
- FIXP_DBL *reTmp = &re[l][lowSubband];
- FIXP_DBL *imTmp = &im[l][lowSubband];
- do{
- FIXP_DBL tmp1 = *(reTmp++);
- FIXP_DBL tmp2 = *(imTmp++);
- maxVal |= (FIXP_DBL)((LONG)(tmp1)^((LONG)tmp1>>(DFRACT_BITS-1)));
- maxVal |= (FIXP_DBL)((LONG)(tmp2)^((LONG)tmp2>>(DFRACT_BITS-1)));
- } while(--k!=0);
-#endif
- }
- } else
- {
- for (int l=start_pos; l<next_pos; l++) {
- int k=width;
- FIXP_DBL *reTmp = &re[l][lowSubband];
- do{
- FIXP_DBL tmp = *(reTmp++);
- maxVal |= (FIXP_DBL)((LONG)(tmp)^((LONG)tmp>>(DFRACT_BITS-1)));
- }while(--k!=0);
- }
- }
- }
-
- return(maxVal);
-}
-
-#define SHIFT_BEFORE_SQUARE (3) /* (7/2) */
-/*!<
- If the accumulator does not provide enough overflow bits or
- does not provide a high dynamic range, the below energy calculation
- requires an additional shift operation for each sample.
- On the other hand, doing the shift allows using a single-precision
- multiplication for the square (at least 16bit x 16bit).
- For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
- is required for the energy accumulation.
- Theoretically, the sample-squares can sum up to a value of 76,
- requiring 7 overflow bits. However since such situations are *very*
- rare, accu can be limited to 64.
- In case native saturated arithmetic is not available, overflows
- can be prevented by replacing the above #define by
- #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
- which will result in slightly reduced accuracy.
-*/
-
-/*!
- \brief Estimates the mean energy of each filter-bank channel for the
- duration of the current envelope
-
- This function is used when interpolFreq is true.
-*/
-/*static*/ void calcNrgPerSubband(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
- FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
- int lowSubband, /*!< Begin of the SBR frequency range */
- int highSubband, /*!< High end of the SBR frequency range */
- int start_pos, /*!< First QMF-slot of current envelope */
- int next_pos, /*!< Last QMF-slot of current envelope + 1 */
- SCHAR frameExp, /*!< Common exponent for all input samples */
- FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
- SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */
-{
- FIXP_SGL invWidth;
- SCHAR preShift;
- SCHAR shift;
- FIXP_DBL sum;
- int k,l;
-
- /* Divide by width of envelope later: */
- invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
- /* The common exponent needs to be doubled because all mantissas are squared: */
- frameExp = frameExp << 1;
-
- for (k=lowSubband; k<highSubband; k++) {
- FIXP_DBL bufferReal[(((1024)/(32))+(6))];
- FIXP_DBL bufferImag[(((1024)/(32))+(6))];
- FIXP_DBL maxVal = FL2FX_DBL(0.0f);
-
- if (analysBufferImag!=NULL)
- {
- for (l=start_pos;l<next_pos;l++)
- {
- bufferImag[l] = analysBufferImag[l][k];
- maxVal |= (FIXP_DBL)((LONG)(bufferImag[l])^((LONG)bufferImag[l]>>(DFRACT_BITS-1)));
- bufferReal[l] = analysBufferReal[l][k];
- maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
- }
- }
- else
- {
- for (l=start_pos;l<next_pos;l++)
- {
- bufferReal[l] = analysBufferReal[l][k];
- maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
- }
- }
-
- if (maxVal!=FL2FXCONST_DBL(0.f)) {
-
-
- /* If the accu does not provide enough overflow bits, we cannot
- shift the samples up to the limit.
- Instead, keep up to 3 free bits in each sample, i.e. up to
- 6 bits after calculation of square.
- Please note the comment on saturated arithmetic above!
- */
- FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
- preShift = CntLeadingZeros(maxVal)-1;
- preShift -= SHIFT_BEFORE_SQUARE;
-
- if (preShift>=0) {
- if (analysBufferImag!=NULL) {
- for (l=start_pos; l<next_pos; l++) {
- FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
- FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
- accu = fPow2AddDiv2(accu, temp1);
- accu = fPow2AddDiv2(accu, temp2);
- }
- } else
- {
- for (l=start_pos; l<next_pos; l++) {
- FIXP_DBL temp = bufferReal[l] << (int)preShift;
- accu = fPow2AddDiv2(accu, temp);
- }
- }
- }
- else { /* if negative shift value */
- int negpreShift = -preShift;
- if (analysBufferImag!=NULL) {
- for (l=start_pos; l<next_pos; l++) {
- FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
- FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
- accu = fPow2AddDiv2(accu, temp1);
- accu = fPow2AddDiv2(accu, temp2);
- }
- } else
- {
- for (l=start_pos; l<next_pos; l++) {
- FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
- accu = fPow2AddDiv2(accu, temp);
- }
- }
- }
- accu <<= 1;
-
- /* Convert double precision to Mantissa/Exponent: */
- shift = fNorm(accu);
- sum = accu << (int)shift;
-
- /* Divide by width of envelope and apply frame scale: */
- *nrgEst++ = fMult(sum, invWidth);
- shift += 2 * preShift;
- if (analysBufferImag!=NULL)
- *nrgEst_e++ = frameExp - shift;
- else
- *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
- } /* maxVal!=0 */
- else {
-
- /* Prevent a zero-mantissa-number from being misinterpreted
- due to its exponent. */
- *nrgEst++ = FL2FXCONST_DBL(0.0f);
- *nrgEst_e++ = 0;
- }
- }
-}
-
-/*!
- \brief Estimates the mean energy of each Scale factor band for the
- duration of the current envelope.
-
- This function is used when interpolFreq is false.
-*/
-/*static*/ void calcNrgPerSfb(FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
- FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
- int nSfb, /*!< Number of scale factor bands */
- UCHAR *freqBandTable, /*!< First Subband for each Sfb */
- int start_pos, /*!< First QMF-slot of current envelope */
- int next_pos, /*!< Last QMF-slot of current envelope + 1 */
- SCHAR input_e, /*!< Common exponent for all input samples */
- FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */
- SCHAR *nrgEst_e ) /*!< Exponent of resulting Energy */
-{
- FIXP_SGL invWidth;
- FIXP_DBL temp;
- SCHAR preShift;
- SCHAR shift, sum_e;
- FIXP_DBL sum;
-
- int j,k,l,li,ui;
- FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
- but overflow bits are required for accumulation */
-
- /* Divide by width of envelope later: */
- invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
- /* The common exponent needs to be doubled because all mantissas are squared: */
- input_e = input_e << 1;
-
- for(j=0; j<nSfb; j++) {
- li = freqBandTable[j];
- ui = freqBandTable[j+1];
-
- FIXP_DBL maxVal = maxSubbandSample( analysBufferReal,
- analysBufferImag,
- li,
- ui,
- start_pos,
- next_pos );
-
- if (maxVal!=FL2FXCONST_DBL(0.f)) {
-
- preShift = CntLeadingZeros(maxVal)-1;
-
- /* If the accu does not provide enough overflow bits, we cannot
- shift the samples up to the limit.
- Instead, keep up to 3 free bits in each sample, i.e. up to
- 6 bits after calculation of square.
- Please note the comment on saturated arithmetic above!
- */
- preShift -= SHIFT_BEFORE_SQUARE;
-
- sumAll = FL2FXCONST_DBL(0.0f);
-
-
- for (k=li; k<ui; k++) {
-
- sumLine = FL2FXCONST_DBL(0.0f);
-
- if (analysBufferImag!=NULL) {
- if (preShift>=0) {
- for (l=start_pos; l<next_pos; l++) {
- temp = analysBufferReal[l][k] << (int)preShift;
- sumLine += fPow2Div2(temp);
- temp = analysBufferImag[l][k] << (int)preShift;
- sumLine += fPow2Div2(temp);
-
- }
- } else {
- for (l=start_pos; l<next_pos; l++) {
- temp = analysBufferReal[l][k] >> -(int)preShift;
- sumLine += fPow2Div2(temp);
- temp = analysBufferImag[l][k] >> -(int)preShift;
- sumLine += fPow2Div2(temp);
- }
- }
- } else
- {
- if (preShift>=0) {
- for (l=start_pos; l<next_pos; l++) {
- temp = analysBufferReal[l][k] << (int)preShift;
- sumLine += fPow2Div2(temp);
- }
- } else {
- for (l=start_pos; l<next_pos; l++) {
- temp = analysBufferReal[l][k] >> -(int)preShift;
- sumLine += fPow2Div2(temp);
- }
- }
- }
-
- /* The number of QMF-channels per SBR bands may be up to 15.
- Shift right to avoid overflows in sum over all channels. */
- sumLine = sumLine >> (4-1);
- sumAll += sumLine;
- }
-
- /* Convert double precision to Mantissa/Exponent: */
- shift = fNorm(sumAll);
- sum = sumAll << (int)shift;
-
- /* Divide by width of envelope: */
- sum = fMult(sum,invWidth);
-
- /* Divide by width of Sfb: */
- sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui-li)));
-
- /* Set all Subband energies in the Sfb to the average energy: */
- if (analysBufferImag!=NULL)
- sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
- else
- sum_e = input_e + 4 + 1 - shift; /* -4 to compensate right-shift; +1 due to missing imag. part */
-
- sum_e -= 2 * preShift;
- } /* maxVal!=0 */
- else {
-
- /* Prevent a zero-mantissa-number from being misinterpreted
- due to its exponent. */
- sum = FL2FXCONST_DBL(0.0f);
- sum_e = 0;
- }
-
- for (k=li; k<ui; k++)
- {
- *nrgEst++ = sum;
- *nrgEst_e++ = sum_e;
- }
- }
-}
-
-
-/*!
- \brief Calculate gain, noise, and additional sine level for one subband.
-
- The resulting energy gain is given by mantissa and exponent.
-*/
-/*static*/ void calcSubbandGain(FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
- SCHAR nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
- ENV_CALC_NRGS* nrgs,
- int i,
- FIXP_DBL tmpNoise, /*!< Relative noise level */
- SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */
- UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
- UCHAR sineMapped, /*!< Indicates if sine must be added */
- int noNoiseFlag) /*!< Flag to suppress noise addition */
-{
- FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
- SCHAR nrgEst_e = nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
- FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
- SCHAR *ptrNrgGain_e = &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
- FIXP_DBL *ptrNoiseLevel = &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
- SCHAR *ptrNoiseLevel_e = &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
- FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
- SCHAR *ptrNrgSine_e = &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
-
- FIXP_DBL a, b, c;
- SCHAR a_e, b_e, c_e;
-
- /*
- This addition of 1 prevents divisions by zero in the reference code.
- For very small energies in nrgEst, it prevents the gains from becoming
- very high which could cause some trouble due to the smoothing.
- */
- b_e = (int)(nrgEst_e - 1);
- if (b_e>=0) {
- nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (nrgEst >> 1);
- nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
-
- } else {
- nrgEst = (nrgEst >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
- nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
- }
-
- /* A = NrgRef * TmpNoise */
- a = fMult(nrgRef,tmpNoise);
- a_e = nrgRef_e + tmpNoise_e;
-
- /* B = 1 + TmpNoise */
- b_e = (int)(tmpNoise_e - 1);
- if (b_e>=0) {
- b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (tmpNoise >> 1);
- b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
- } else {
- b = (tmpNoise >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
- b_e = 2; /* shift by 1 bit to avoid overflow */
- }
-
- /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
- FDK_divide_MantExp( a, a_e,
- b, b_e,
- ptrNoiseLevel, ptrNoiseLevel_e);
-
- if (sinePresentFlag) {
-
- /* C = (1 + TmpNoise) * NrgEst */
- c = fMult(b,nrgEst);
- c_e = b_e + nrgEst_e;
-
- /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
- FDK_divide_MantExp( a, a_e,
- c, c_e,
- ptrNrgGain, ptrNrgGain_e);
-
- if (sineMapped) {
-
- /* sineLevel = nrgRef/ (1 + TmpNoise) */
- FDK_divide_MantExp( nrgRef, nrgRef_e,
- b, b_e,
- ptrNrgSine, ptrNrgSine_e);
- }
- }
- else {
- if (noNoiseFlag) {
- /* B = NrgEst */
- b = nrgEst;
- b_e = nrgEst_e;
- }
- else {
- /* B = NrgEst * (1 + TmpNoise) */
- b = fMult(b,nrgEst);
- b_e = b_e + nrgEst_e;
- }
-
-
- /* gain = nrgRef / B */
- FDK_divide_MantExp( nrgRef, nrgRef_e,
- b, b_e,
- ptrNrgGain, ptrNrgGain_e);
- }
-}
-
-
-/*!
- \brief Calculate "average gain" for the specified subband range.
-
- This is rather a gain of the average magnitude than the average
- of gains!
- The result is used as a relative limit for all gains within the
- current "limiter band" (a certain frequency range).
-*/
-/*static*/ void calcAvgGain(ENV_CALC_NRGS* nrgs,
- int lowSubband, /*!< Begin of the limiter band */
- int highSubband, /*!< High end of the limiter band */
- FIXP_DBL *ptrSumRef,
- SCHAR *ptrSumRef_e,
- FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
- SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */
-{
- FIXP_DBL *nrgRef = nrgs->nrgRef; /*!< Reference Energy according to envelope data */
- SCHAR *nrgRef_e = nrgs->nrgRef_e; /*!< Reference Energy according to envelope data (exponent) */
- FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
- SCHAR *nrgEst_e = nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
-
- FIXP_DBL sumRef = 1;
- FIXP_DBL sumEst = 1;
- SCHAR sumRef_e = -FRACT_BITS;
- SCHAR sumEst_e = -FRACT_BITS;
- int k;
-
- for (k=lowSubband; k<highSubband; k++){
- /* Add nrgRef[k] to sumRef: */
- FDK_add_MantExp( sumRef, sumRef_e,
- nrgRef[k], nrgRef_e[k],
- &sumRef, &sumRef_e );
-
- /* Add nrgEst[k] to sumEst: */
- FDK_add_MantExp( sumEst, sumEst_e,
- nrgEst[k], nrgEst_e[k],
- &sumEst, &sumEst_e );
- }
-
- FDK_divide_MantExp(sumRef, sumRef_e,
- sumEst, sumEst_e,
- ptrAvgGain, ptrAvgGain_e);
-
- *ptrSumRef = sumRef;
- *ptrSumRef_e = sumRef_e;
-}
-
-
-/*!
- \brief Amplify one timeslot of the signal with the calculated gains
- and add the noisefloor.
-*/
-
-/*static*/ void adjustTimeSlotLC(FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
- ENV_CALC_NRGS* nrgs,
- UCHAR *ptrHarmIndex, /*!< Harmonic index */
- int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
- int noSubbands, /*!< Number of QMF subbands */
- int scale_change, /*!< Number of bits to shift adjusted samples */
- int noNoiseFlag, /*!< Flag to suppress noise addition */
- int *ptrPhaseIndex, /*!< Start index to random number array */
- int fCldfb) /*!< CLDFB 80 flag */
-{
- FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
- FIXP_DBL *pNoiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
- FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
-
- int k;
- int index = *ptrPhaseIndex;
- UCHAR harmIndex = *ptrHarmIndex;
- UCHAR freqInvFlag = (lowSubband & 1);
- FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
- int tone_count = 0;
- int sineSign = 1;
-
- #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f))
- #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f))
-
- /*
- First pass for k=0 pulled out of the loop:
- */
-
- index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
-
- /*
- The next multiplication constitutes the actual envelope adjustment
- of the signal and should be carried out with full accuracy
- (supplying #FRACT_BITS valid bits).
- */
- signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
- sineLevel = *pSineLevel++;
- sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
-
- if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
-
- else if (!noNoiseFlag)
- /* Add noisefloor to the amplified signal */
- signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
-
- if (fCldfb) {
-
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
- *ptrReal++ = signalReal;
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- int shift = (int) (scale_change+1);
- shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
-
- FIXP_DBL tmp1 = scaleValue( fMultDiv2(C1_CLDFB, sineLevel), -shift );
-
- FIXP_DBL tmp2 = fMultDiv2(C1_CLDFB, sineLevelNext);
-
-
- /* save switch and compare operations and reduce to XOR statement */
- if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
- *(ptrReal-1) += tmp1;
- signalReal -= tmp2;
- } else {
- *(ptrReal-1) -= tmp1;
- signalReal += tmp2;
- }
- *ptrReal++ = signalReal;
- freqInvFlag = !freqInvFlag;
- }
-
- } else
- {
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
- *ptrReal++ = signalReal;
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- int shift = (int) (scale_change+1);
- shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
-
- FIXP_DBL tmp1 = (shift>=0) ? ( fMultDiv2(C1, sineLevel) >> shift )
- : ( fMultDiv2(C1, sineLevel) << (-shift) );
- FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
-
-
- /* save switch and compare operations and reduce to XOR statement */
- if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
- *(ptrReal-1) += tmp1;
- signalReal -= tmp2;
- } else {
- *(ptrReal-1) -= tmp1;
- signalReal += tmp2;
- }
- *ptrReal++ = signalReal;
- freqInvFlag = !freqInvFlag;
- }
- }
-
- pNoiseLevel++;
-
- if ( noSubbands > 2 ) {
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- if(!harmIndex)
- {
- sineSign = 0;
- }
-
- for (k=noSubbands-2; k!=0; k--) {
- FIXP_DBL sinelevel = *pSineLevel++;
- index++;
- if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == FL2FXCONST_DBL(0.0f)) && !noNoiseFlag)
- {
- /* Add noisefloor to the amplified signal */
- index &= (SBR_NF_NO_RANDOM_VAL - 1);
- signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
- }
-
- /* The next multiplication constitutes the actual envelope adjustment of the signal. */
- signalReal += fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
-
- pNoiseLevel++;
- *ptrReal++ = signalReal;
- } /* for ... */
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- if (harmIndex==1) freqInvFlag = !freqInvFlag;
-
- for (k=noSubbands-2; k!=0; k--) {
- index++;
- /* The next multiplication constitutes the actual envelope adjustment of the signal. */
- signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
-
- if (*pSineLevel++!=FL2FXCONST_DBL(0.0f)) tone_count++;
- else if (!noNoiseFlag) {
- /* Add noisefloor to the amplified signal */
- index &= (SBR_NF_NO_RANDOM_VAL - 1);
- signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
- }
-
- pNoiseLevel++;
-
- if (tone_count <= 16) {
- FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
- signalReal += (freqInvFlag) ? (-addSine) : (addSine);
- }
-
- *ptrReal++ = signalReal;
- freqInvFlag = !freqInvFlag;
- } /* for ... */
- }
- }
-
- if (noSubbands > -1) {
- index++;
- /* The next multiplication constitutes the actual envelope adjustment of the signal. */
- signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
- sineLevelPrev = fMultDiv2(pSineLevel[-1],FL2FX_SGL(0.0163f));
- sineLevel = pSineLevel[0];
-
- if (pSineLevel[0]!=FL2FXCONST_DBL(0.0f)) tone_count++;
- else if (!noNoiseFlag) {
- /* Add noisefloor to the amplified signal */
- index &= (SBR_NF_NO_RANDOM_VAL - 1);
- signalReal = signalReal + (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
- }
-
- if (!(harmIndex&0x1)) {
- /* harmIndex 0,2 */
- *ptrReal = signalReal + ( (sineSign) ? -sineLevel : sineLevel);
- }
- else {
- /* harmIndex 1,3 in combination with freqInvFlag */
- if(tone_count <= 16){
- if (freqInvFlag) {
- *ptrReal++ = signalReal - sineLevelPrev;
- if (noSubbands + lowSubband < 63)
- *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
- }
- else {
- *ptrReal++ = signalReal + sineLevelPrev;
- if (noSubbands + lowSubband < 63)
- *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
- }
- }
- else *ptrReal = signalReal;
- }
- }
- *ptrHarmIndex = (harmIndex + 1) & 3;
- *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
-}
-void adjustTimeSlotHQ(FIXP_DBL *RESTRICT ptrReal, /*!< Subband samples to be adjusted, real part */
- FIXP_DBL *RESTRICT ptrImag, /*!< Subband samples to be adjusted, imag part */
- HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
- ENV_CALC_NRGS* nrgs,
- int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
- int noSubbands, /*!< Number of QMF subbands */
- int scale_change, /*!< Number of bits to shift adjusted samples */
- FIXP_SGL smooth_ratio, /*!< Impact of last envelope */
- int noNoiseFlag, /*!< Start index to random number array */
- int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
-{
-
- FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
- FIXP_DBL *RESTRICT noiseLevel = nrgs->noiseLevel; /*!< Noise levels of current envelope */
- FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
-
- FIXP_DBL *RESTRICT filtBuffer = h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
- FIXP_DBL *RESTRICT filtBufferNoise = h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
- UCHAR *RESTRICT ptrHarmIndex =&h_sbr_cal_env->harmIndex; /*!< Harmonic index */
- int *RESTRICT ptrPhaseIndex =&h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
-
- int k;
- FIXP_DBL signalReal, signalImag;
- FIXP_DBL noiseReal, noiseImag;
- FIXP_DBL smoothedGain, smoothedNoise;
- FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
- int index = *ptrPhaseIndex;
- UCHAR harmIndex = *ptrHarmIndex;
- register int freqInvFlag = (lowSubband & 1);
- FIXP_DBL sineLevel;
- int shift;
-
- *ptrPhaseIndex = (index+noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
- *ptrHarmIndex = (harmIndex + 1) & 3;
-
- /*
- Possible optimization:
- smooth_ratio and harmIndex stay constant during the loop.
- It might be faster to include a separate loop in each path.
-
- the check for smooth_ratio is now outside the loop and the workload
- of the whole function decreased by about 20 %
- */
-
- filtBufferNoiseShift += 1; /* due to later use of fMultDiv2 instead of fMult */
- if (filtBufferNoiseShift<0)
- shift = fixMin(DFRACT_BITS-1,-filtBufferNoiseShift);
- else
- shift = fixMin(DFRACT_BITS-1, filtBufferNoiseShift);
-
- if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
-
- for (k=0; k<noSubbands; k++) {
- /*
- Smoothing: The old envelope has been bufferd and a certain ratio
- of the old gains and noise levels is used.
- */
-
- smoothedGain = fMult(smooth_ratio,filtBuffer[k]) +
- fMult(direct_ratio,gain[k]);
-
- if (filtBufferNoiseShift<0) {
- smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])>>shift) +
- fMult(direct_ratio,noiseLevel[k]);
- }
- else {
- smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])<<shift) +
- fMult(direct_ratio,noiseLevel[k]);
- }
-
- /*
- The next 2 multiplications constitute the actual envelope adjustment
- of the signal and should be carried out with full accuracy
- (supplying #DFRACT_BITS valid bits).
- */
- signalReal = fMultDiv2(*ptrReal,smoothedGain)<<((int)scale_change);
- signalImag = fMultDiv2(*ptrImag,smoothedGain)<<((int)scale_change);
-
- index++;
-
- if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
- sineLevel = pSineLevel[k];
-
- switch(harmIndex) {
- case 0:
- *ptrReal++ = (signalReal + sineLevel);
- *ptrImag++ = (signalImag);
- break;
- case 2:
- *ptrReal++ = (signalReal - sineLevel);
- *ptrImag++ = (signalImag);
- break;
- case 1:
- *ptrReal++ = (signalReal);
- if (freqInvFlag)
- *ptrImag++ = (signalImag - sineLevel);
- else
- *ptrImag++ = (signalImag + sineLevel);
- break;
- case 3:
- *ptrReal++ = signalReal;
- if (freqInvFlag)
- *ptrImag++ = (signalImag + sineLevel);
- else
- *ptrImag++ = (signalImag - sineLevel);
- break;
- }
- }
- else {
- if (noNoiseFlag) {
- /* Just the amplified signal is saved */
- *ptrReal++ = (signalReal);
- *ptrImag++ = (signalImag);
- }
- else {
- /* Add noisefloor to the amplified signal */
- index &= (SBR_NF_NO_RANDOM_VAL - 1);
- noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)<<4;
- noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)<<4;
- *ptrReal++ = (signalReal + noiseReal);
- *ptrImag++ = (signalImag + noiseImag);
- }
- }
- freqInvFlag ^= 1;
- }
-
- }
- else
- {
- for (k=0; k<noSubbands; k++)
- {
- smoothedGain = gain[k];
- signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
- signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
-
- index++;
-
- if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f))
- {
- switch (harmIndex)
- {
- case 0:
- signalReal += sineLevel;
- break;
- case 1:
- if (freqInvFlag)
- signalImag -= sineLevel;
- else
- signalImag += sineLevel;
- break;
- case 2:
- signalReal -= sineLevel;
- break;
- case 3:
- if (freqInvFlag)
- signalImag += sineLevel;
- else
- signalImag -= sineLevel;
- break;
- }
- }
- else
- {
- if (noNoiseFlag == 0)
- {
- /* Add noisefloor to the amplified signal */
- smoothedNoise = noiseLevel[k];
- index &= (SBR_NF_NO_RANDOM_VAL - 1);
- noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
- noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
- signalReal += noiseReal<<4;
- signalImag += noiseImag<<4;
- }
- }
- *ptrReal++ = signalReal;
- *ptrImag++ = signalImag;
-
- freqInvFlag ^= 1;
- }
- }
-}
-
-
-/*!
- \brief Reset limiter bands.
-
- Build frequency band table for the gain limiter dependent on
- the previously generated transposer patch areas.
-
- \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error
-*/
-SBR_ERROR
-ResetLimiterBands ( UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
- UCHAR *noLimiterBands, /*!< Resulting number of limiter band */
- UCHAR *freqBandTable, /*!< Table with possible band borders */
- int noFreqBands, /*!< Number of bands in freqBandTable */
- const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
- int noPatches, /*!< Number of transposer patches */
- int limiterBands) /*!< Selected 'band density' from bitstream */
-{
- int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
- UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
- int patchBorders[MAX_NUM_PATCHES + 1];
- int kx, k2;
- FIXP_DBL temp;
-
- int lowSubband = freqBandTable[0];
- int highSubband = freqBandTable[noFreqBands];
-
- /* 1 limiter band. */
- if(limiterBands == 0) {
- limiterBandTable[0] = 0;
- limiterBandTable[1] = highSubband - lowSubband;
- nBands = 1;
- } else {
- for (i = 0; i < noPatches; i++) {
- patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
- }
- patchBorders[i] = highSubband - lowSubband;
-
- /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
- for (k = 0; k <= noFreqBands; k++) {
- workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
- }
- for (k = 1; k < noPatches; k++) {
- workLimiterBandTable[noFreqBands + k] = patchBorders[k];
- }
-
- tempNoLim = nBands = noFreqBands + noPatches - 1;
- shellsort(workLimiterBandTable, tempNoLim + 1);
-
- loLimIndex = 0;
- hiLimIndex = 1;
-
-
- while (hiLimIndex <= tempNoLim) {
- k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
- kx = workLimiterBandTable[loLimIndex] + lowSubband;
-
- temp = FX_SGL2FX_DBL(FDK_getNumOctavesDiv8(kx,k2)); /* Number of octaves */
- temp = fMult(temp, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[limiterBands]);
-
- if (temp < FL2FXCONST_DBL (0.49f)>>5) {
- if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
- workLimiterBandTable[hiLimIndex] = highSubband;
- nBands--;
- hiLimIndex++;
- continue;
- }
- isPatchBorder[0] = isPatchBorder[1] = 0;
- for (k = 0; k <= noPatches; k++) {
- if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
- isPatchBorder[1] = 1;
- break;
- }
- }
- if (!isPatchBorder[1]) {
- workLimiterBandTable[hiLimIndex] = highSubband;
- nBands--;
- hiLimIndex++;
- continue;
- }
- for (k = 0; k <= noPatches; k++) {
- if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
- isPatchBorder[0] = 1;
- break;
- }
- }
- if (!isPatchBorder[0]) {
- workLimiterBandTable[loLimIndex] = highSubband;
- nBands--;
- }
- }
- loLimIndex = hiLimIndex;
- hiLimIndex++;
-
- }
- shellsort(workLimiterBandTable, tempNoLim + 1);
-
- /* Test if algorithm exceeded maximum allowed limiterbands */
- if( nBands > MAX_NUM_LIMITERS || nBands <= 0) {
- return SBRDEC_UNSUPPORTED_CONFIG;
- }
-
- /* Copy limiterbands from working buffer into final destination */
- for (k = 0; k <= nBands; k++) {
- limiterBandTable[k] = workLimiterBandTable[k];
- }
- }
- *noLimiterBands = nBands;
-
- return SBRDEC_OK;
-}
-