1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2015 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /*!
85   \file
86   \brief  Envelope calculation
87 
88   The envelope adjustor compares the energies present in the transposed
89   highband to the reference energies conveyed with the bitstream.
90   The highband is amplified (sometimes) or attenuated (mostly) to the
91   desired level.
92 
93   The spectral shape of the reference energies can be changed several times per
94   frame if necessary. Each set of energy values corresponding to a certain range
95   in time will be called an <em>envelope</em> here.
96   The bitstream supports several frequency scales and two resolutions. Normally,
97   one or more QMF-subbands are grouped to one SBR-band. An envelope contains
98   reference energies for each SBR-band.
99   In addition to the energy envelopes, noise envelopes are transmitted that
100   define the ratio of energy which is generated by adding noise instead of
101   transposing the lowband. The noise envelopes are given in a coarser time
102   and frequency resolution.
103   If a signal contains strong tonal components, synthetic sines can be
104   generated in individual SBR bands.
105 
106   An overlap buffer of 6 QMF-timeslots is used to allow a more
107   flexible alignment of the envelopes in time that is not restricted to the
108   core codec's frame borders.
109   Therefore the envelope adjustor has access to the spectral data of the
110   current frame as well as the last 6 QMF-timeslots of the previous frame.
111   However, in average only the data of 1 frame is being processed as
112   the adjustor is called once per frame.
113 
114   Depending on the frequency range set in the bitstream, only QMF-subbands between
115   <em>lowSubband</em> and <em>highSubband</em> are adjusted.
116 
117   Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a special Mantissa-Exponent format
118   ( see  calculateSbrEnvelope() ) are being used. The main entry point for this modules is calculateSbrEnvelope().
119 
120   \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref documentationOverview
121 */
122 
123 
124 #include "env_calc.h"
125 
126 #include "sbrdec_freq_sca.h"
127 #include "env_extr.h"
128 #include "transcendent.h"
129 #include "sbr_ram.h"
130 #include "sbr_rom.h"
131 
132 #include "genericStds.h"           /* need FDKpow() for debug outputs */
133 
134 #if defined(__arm__)
135 #include "arm/env_calc_arm.cpp"
136 #endif
137 
138 typedef struct
139 {
140     FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
141     FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
142     FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
143     FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
144     FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
145 
146     SCHAR   nrgRef_e[MAX_FREQ_COEFFS];
147     SCHAR   nrgEst_e[MAX_FREQ_COEFFS];
148     SCHAR   nrgGain_e[MAX_FREQ_COEFFS];
149     SCHAR   noiseLevel_e[MAX_FREQ_COEFFS];
150     SCHAR   nrgSine_e[MAX_FREQ_COEFFS];
151 }
152 ENV_CALC_NRGS;
153 
154 static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,
155                                   SCHAR   *filtBuffer_e,
156                                   FIXP_DBL *NrgGain,
157                                   SCHAR   *NrgGain_e,
158                                   int    subbands);
159 
160 static void calcNrgPerSubband(FIXP_DBL  **analysBufferReal,
161                               FIXP_DBL  **analysBufferImag,
162                               int       lowSubband, int highSubband,
163                               int       start_pos,  int next_pos,
164                               SCHAR     frameExp,
165                               FIXP_DBL *nrgEst,
166                               SCHAR    *nrgEst_e );
167 
168 static void calcNrgPerSfb(FIXP_DBL  **analysBufferReal,
169                           FIXP_DBL  **analysBufferImag,
170                           int       nSfb,
171                           UCHAR    *freqBandTable,
172                           int       start_pos,  int next_pos,
173                           SCHAR     input_e,
174                           FIXP_DBL *nrg_est,
175                           SCHAR    *nrg_est_e );
176 
177 static void calcSubbandGain(FIXP_DBL  nrgRef, SCHAR nrgRef_e, ENV_CALC_NRGS* nrgs, int c,
178                             FIXP_DBL  tmpNoise, SCHAR tmpNoise_e,
179                             UCHAR     sinePresentFlag,
180                             UCHAR     sineMapped,
181                             int       noNoiseFlag);
182 
183 static void calcAvgGain(ENV_CALC_NRGS* nrgs,
184                         int        lowSubband,
185                         int        highSubband,
186                         FIXP_DBL  *sumRef_m,
187                         SCHAR     *sumRef_e,
188                         FIXP_DBL  *ptrAvgGain_m,
189                         SCHAR     *ptrAvgGain_e);
190 
191 static void adjustTimeSlot_EldGrid(FIXP_DBL  *ptrReal,
192                            ENV_CALC_NRGS* nrgs,
193                            UCHAR *ptrHarmIndex,
194                            int    lowSubbands,
195                            int    noSubbands,
196                            int    scale_change,
197                            int    noNoiseFlag,
198                            int   *ptrPhaseIndex,
199                            int    scale_diff_low);
200 
201 static void adjustTimeSlotLC(FIXP_DBL  *ptrReal,
202                            ENV_CALC_NRGS* nrgs,
203                            UCHAR *ptrHarmIndex,
204                            int    lowSubbands,
205                            int    noSubbands,
206                            int    scale_change,
207                            int    noNoiseFlag,
208                            int   *ptrPhaseIndex);
209 static void adjustTimeSlotHQ(FIXP_DBL  *ptrReal,
210                            FIXP_DBL  *ptrImag,
211                            HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
212                            ENV_CALC_NRGS* nrgs,
213                            int    lowSubbands,
214                            int    noSubbands,
215                            int    scale_change,
216                            FIXP_SGL smooth_ratio,
217                            int    noNoiseFlag,
218                            int    filtBufferNoiseShift);
219 
220 
221 /*!
222   \brief     Map sine flags from bitstream to QMF bands
223 
224   The bitstream carries only 1 sine flag per band and frame.
225   This function maps every sine flag from the bitstream to a specific QMF subband
226   and to a specific envelope where the sine shall start.
227   The result is stored in the vector sineMapped which contains one entry per
228   QMF subband. The value of an entry specifies the envelope where a sine
229   shall start. A value of #MAX_ENVELOPES indicates that no sine is present
230   in the subband.
231   The missing harmonics flags from the previous frame (harmFlagsPrev) determine
232   if a sine starts at the beginning of the frame or at the transient position.
233   Additionally, the flags in harmFlagsPrev are being updated by this function
234   for the next frame.
235 */
mapSineFlags(UCHAR * freqBandTable,int nSfb,UCHAR * addHarmonics,int * harmFlagsPrev,int tranEnv,SCHAR * sineMapped)236 static void mapSineFlags(UCHAR *freqBandTable,         /*!< Band borders (there's only 1 flag per band) */
237                          int nSfb,                     /*!< Number of bands in the table */
238                          UCHAR *addHarmonics,           /*!< vector with 1 flag per sfb */
239                          int *harmFlagsPrev,           /*!< Packed 'addHarmonics' */
240                          int tranEnv,                  /*!< Transient position */
241                          SCHAR *sineMapped)            /*!< Resulting vector of sine start positions for each QMF band */
242 
243 {
244   int i;
245   int lowSubband2 = freqBandTable[0]<<1;
246   int bitcount = 0;
247   int oldflags = *harmFlagsPrev;
248   int newflags = 0;
249 
250   /*
251     Format of harmFlagsPrev:
252 
253     first word = flags for highest 16 sfb bands in use
254     second word = flags for next lower 16 sfb bands (if present)
255     third word = flags for lowest 16 sfb bands (if present)
256 
257     Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
258     The lowest bit of the first word corresponds to the _highest_ sfb band in use.
259     This is ensures that each flag is  mapped to the same QMF band even after a
260     change of the crossover-frequency.
261   */
262 
263 
264   /* Reset the output vector first */
265   FDKmemset(sineMapped, MAX_ENVELOPES,MAX_FREQ_COEFFS); /* MAX_ENVELOPES means 'no sine' */
266 
267   freqBandTable += nSfb;
268   addHarmonics  += nSfb-1;
269 
270   for (i=nSfb; i!=0; i--) {
271     int ui = *freqBandTable--;                 /* Upper limit of the current scale factor band. */
272     int li = *freqBandTable;                   /* Lower limit of the current scale factor band. */
273 
274     if ( *addHarmonics-- ) {                   /* There is a sine in this band */
275 
276       unsigned int mask = 1 << bitcount;
277       newflags |= mask;                        /* Set flag */
278 
279       /*
280         If there was a sine in the last frame, let it continue from the first envelope on
281         else start at the transient position.
282       */
283       sineMapped[(ui+li-lowSubband2) >> 1] = ( oldflags & mask ) ? 0 : tranEnv;
284     }
285 
286     if ((++bitcount == 16) || i==1) {
287       bitcount = 0;
288       *harmFlagsPrev++ = newflags;
289       oldflags = *harmFlagsPrev;               /* Fetch 16 of the old flags */
290       newflags = 0;
291     }
292   }
293 }
294 
295 
296 /*!
297   \brief     Reduce gain-adjustment induced aliasing for real valued filterbank.
298 */
299 /*static*/ void
aliasingReduction(FIXP_DBL * degreeAlias,ENV_CALC_NRGS * nrgs,int * useAliasReduction,int noSubbands)300 aliasingReduction(FIXP_DBL* degreeAlias,       /*!< estimated aliasing for each QMF channel */
301                   ENV_CALC_NRGS* nrgs,
302                   int*      useAliasReduction, /*!< synthetic sine engergy for each subband, used as flag */
303                   int       noSubbands)        /*!< number of QMF channels to process */
304 {
305   FIXP_DBL* nrgGain   = nrgs->nrgGain;          /*!< subband gains to be modified */
306   SCHAR*    nrgGain_e = nrgs->nrgGain_e;        /*!< subband gains to be modified (exponents) */
307   FIXP_DBL* nrgEst    = nrgs->nrgEst;           /*!< subband energy before amplification */
308   SCHAR*    nrgEst_e  = nrgs->nrgEst_e;         /*!< subband energy before amplification (exponents) */
309   int grouping = 0, index = 0, noGroups, k;
310   int groupVector[MAX_FREQ_COEFFS];
311 
312   /* Calculate grouping*/
313   for (k = 0; k < noSubbands-1; k++ ){
314     if ( (degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k] ) {
315       if(grouping==0){
316         groupVector[index++] = k;
317         grouping = 1;
318       }
319       else{
320         if(groupVector[index-1] + 3 == k){
321           groupVector[index++] = k + 1;
322           grouping = 0;
323         }
324       }
325     }
326     else{
327       if(grouping){
328         if(useAliasReduction[k])
329           groupVector[index++] = k + 1;
330         else
331           groupVector[index++] = k;
332         grouping = 0;
333       }
334     }
335   }
336 
337   if(grouping){
338     groupVector[index++] = noSubbands;
339   }
340   noGroups = index >> 1;
341 
342 
343   /*Calculate new gain*/
344   for (int group = 0; group < noGroups; group ++) {
345     FIXP_DBL nrgOrig = FL2FXCONST_DBL(0.0f);    /* Original signal energy in current group of bands */
346     SCHAR    nrgOrig_e = 0;
347     FIXP_DBL nrgAmp = FL2FXCONST_DBL(0.0f);     /* Amplified signal energy in group (using current gains) */
348     SCHAR    nrgAmp_e = 0;
349     FIXP_DBL nrgMod = FL2FXCONST_DBL(0.0f);   /* Signal energy in group when applying modified gains */
350     SCHAR    nrgMod_e = 0;
351     FIXP_DBL groupGain;         /* Total energy gain in group */
352     SCHAR    groupGain_e;
353     FIXP_DBL compensation;      /* Compensation factor for the energy change when applying modified gains */
354     SCHAR    compensation_e;
355 
356     int startGroup = groupVector[2*group];
357     int stopGroup  = groupVector[2*group+1];
358 
359     /* Calculate total energy in group before and after amplification with current gains: */
360     for(k = startGroup; k < stopGroup; k++){
361       /* Get original band energy */
362       FIXP_DBL tmp = nrgEst[k];
363       SCHAR    tmp_e = nrgEst_e[k];
364 
365       FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
366 
367       /* Multiply band energy with current gain */
368       tmp = fMult(tmp,nrgGain[k]);
369       tmp_e = tmp_e + nrgGain_e[k];
370 
371       FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
372     }
373 
374     /* Calculate total energy gain in group */
375     FDK_divide_MantExp(nrgAmp, nrgAmp_e,
376                        nrgOrig, nrgOrig_e,
377                        &groupGain, &groupGain_e);
378 
379     for(k = startGroup; k < stopGroup; k++){
380       FIXP_DBL tmp;
381       SCHAR    tmp_e;
382 
383       FIXP_DBL alpha = degreeAlias[k];
384       if (k < noSubbands - 1) {
385         if (degreeAlias[k + 1] > alpha)
386           alpha = degreeAlias[k + 1];
387       }
388 
389       /* Modify gain depending on the degree of aliasing */
390       FDK_add_MantExp( fMult(alpha,groupGain), groupGain_e,
391                        fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,nrgGain[k]), nrgGain_e[k],
392                        &nrgGain[k], &nrgGain_e[k] );
393 
394       /* Apply modified gain to original energy */
395       tmp = fMult(nrgGain[k],nrgEst[k]);
396       tmp_e = nrgGain_e[k] + nrgEst_e[k];
397 
398       /* Accumulate energy with modified gains applied */
399       FDK_add_MantExp( tmp, tmp_e,
400                        nrgMod, nrgMod_e,
401                        &nrgMod, &nrgMod_e );
402     }
403 
404     /* Calculate compensation factor to retain the energy of the amplified signal */
405     FDK_divide_MantExp(nrgAmp, nrgAmp_e,
406                        nrgMod, nrgMod_e,
407                        &compensation, &compensation_e);
408 
409     /* Apply compensation factor to all gains of the group */
410     for(k = startGroup; k < stopGroup; k++){
411       nrgGain[k] = fMult(nrgGain[k],compensation);
412       nrgGain_e[k] = nrgGain_e[k] + compensation_e;
413     }
414   }
415 }
416 
417 
418  /* Convert headroom bits to exponent */
419 #define SCALE2EXP(s) (15-(s))
420 #define EXP2SCALE(e) (15-(e))
421 
422 /*!
423   \brief  Apply spectral envelope to subband samples
424 
425   This function is called from sbr_dec.cpp in each frame.
426 
427   To enhance accuracy and due to the usage of tables for squareroots and
428   inverse, some calculations are performed with the operands being split
429   into mantissa and exponent. The variable names in the source code carry
430   the suffixes <em>_m</em> and  <em>_e</em> respectively. The control data
431   in #hFrameData containts envelope data which is represented by this format but
432   stored in single words. (See requantizeEnvelopeData() for details). This data
433   is unpacked within calculateSbrEnvelope() to follow the described suffix convention.
434 
435   The actual value (comparable to the corresponding float-variable in the
436   research-implementation) of a mantissa/exponent-pair can be calculated as
437 
438   \f$ value = value\_m * 2^{value\_e} \f$
439 
440   All energies and noise levels decoded from the bitstream suit for an
441   original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. Therefore,
442   the scale factor <em>hb_scale</em> passed into this function will be converted
443   to an 'input exponent' (#input_e), which fits the internal representation.
444 
445   Before the actual processing, an exponent #adj_e for resulting adjusted
446   samples is derived from the maximum reference energy.
447 
448   Then, for each envelope, the following steps are performed:
449 
450   \li Calculate energy in the signal to be adjusted. Depending on the the value of
451       #interpolFreq (interpolation mode), this is either done seperately
452       for each QMF-subband or for each SBR-band.
453       The resulting energies are stored in #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas)
454       and #nrgEst_e[#MAX_FREQ_COEFFS] (exponents).
455   \li Calculate gain and noise level for each subband:<br>
456       \f$ gain  = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) }
457           \hspace{2cm}
458           noise = \sqrt{ nrgRef \cdot noiseRatio }
459       \f$<br>
460       where <em>noiseRatio</em> and <em>nrgRef</em> are extracted from the
461       bitstream and <em>nrgEst</em> is the subband energy before adjustment.
462       The resulting gains are stored in #nrgGain_m[#MAX_FREQ_COEFFS]
463       (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] (exponents), the noise levels
464       are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] and #noiseLevel_e[#MAX_FREQ_COEFFS]
465       (exponents).
466       The sine levels are stored in #nrgSine_m[#MAX_FREQ_COEFFS]
467       and #nrgSine_e[#MAX_FREQ_COEFFS].
468   \li Noise limiting: The gain for each subband is limited both absolutely
469       and relatively compared to the total gain over all subbands.
470   \li Boost gain: Calculate and apply boost factor for each limiter band
471       in order to compensate for the energy loss imposed by the limiting.
472   \li Apply gains and add noise: The gains and noise levels are applied
473       to all timeslots of the current envelope. A short FIR-filter (length 4
474       QMF-timeslots) can be used to smooth the sudden change at the envelope borders.
475       Each complex subband sample of the current timeslot is multiplied by the
476       smoothed gain, then random noise with the calculated level is added.
477 
478   \note
479   To reduce the stack size, some of the local arrays could be located within
480   the time output buffer. Of the 512 samples temporarily available there,
481   about half the size is already used by #SBR_FRAME_DATA. A pointer to the
482   remaining free memory could be supplied by an additional argument to calculateSbrEnvelope()
483   in sbr_dec:
484 
485   \par
486   \code
487     calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
488                           &hSbrDec->SbrCalculateEnvelope,
489                           hHeaderData,
490                           hFrameData,
491                           QmfBufferReal,
492                           QmfBufferImag,
493                           timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + 1);
494   \endcode
495 
496   \par
497   Within calculateSbrEnvelope(), some pointers could be defined instead of the arrays
498   #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
499 
500   \par
501   \code
502     fract*        nrgRef_m = timeOutPtr;
503     SCHAR*        nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
504     fract*        nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
505     SCHAR*        nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
506     fract*        noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
507   \endcode
508 
509   <br>
510 */
511 void
calculateSbrEnvelope(QMF_SCALE_FACTOR * sbrScaleFactor,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_FRAME_DATA hFrameData,FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,const int useLP,FIXP_DBL * degreeAlias,const UINT flags,const int frameErrorFlag)512 calculateSbrEnvelope (QMF_SCALE_FACTOR  *sbrScaleFactor,           /*!< Scaling factors */
513                       HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
514                       HANDLE_SBR_HEADER_DATA hHeaderData,          /*!< Static control data */
515                       HANDLE_SBR_FRAME_DATA  hFrameData,           /*!< Control data of current frame */
516                       FIXP_DBL **analysBufferReal,                 /*!< Real part of subband samples to be processed */
517                       FIXP_DBL **analysBufferImag,                 /*!< Imag part of subband samples to be processed */
518                       const int useLP,
519                       FIXP_DBL *degreeAlias,                       /*!< Estimated aliasing for each QMF channel */
520                       const UINT flags,
521                       const int frameErrorFlag
522                       )
523 {
524   int c, i, j, envNoise = 0;
525   UCHAR*   borders = hFrameData->frameInfo.borders;
526 
527   FIXP_SGL *noiseLevels       = hFrameData->sbrNoiseFloorLevel;
528   HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
529 
530   int lowSubband  = hFreq->lowSubband;
531   int highSubband = hFreq->highSubband;
532   int noSubbands  = highSubband - lowSubband;
533 
534   int    noNoiseBands = hFreq->nNfb;
535   int    no_cols      = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
536   UCHAR  first_start  = borders[0] * hHeaderData->timeStep;
537 
538   SCHAR  sineMapped[MAX_FREQ_COEFFS];
539   SCHAR  ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
540   SCHAR  adj_e = 0;
541   SCHAR  output_e;
542   SCHAR  final_e = 0;
543 
544   SCHAR  maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
545 
546   int useAliasReduction[64];
547   UCHAR smooth_length = 0;
548 
549   FIXP_SGL * pIenv = hFrameData->iEnvelope;
550 
551   /*
552     Extract sine flags for all QMF bands
553   */
554   mapSineFlags(hFreq->freqBandTable[1],
555                hFreq->nSfb[1],
556                hFrameData->addHarmonics,
557                h_sbr_cal_env->harmFlagsPrev,
558                hFrameData->frameInfo.tranEnv,
559                sineMapped);
560 
561 
562   /*
563     Scan for maximum in bufferd noise levels.
564     This is needed in case that we had strong noise in the previous frame
565     which is smoothed into the current frame.
566     The resulting exponent is used as start value for the maximum search
567     in reference energies
568   */
569   if (!useLP)
570     adj_e = h_sbr_cal_env->filtBufferNoise_e - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
571 
572   /*
573     Scan for maximum reference energy to be able
574     to select appropriate values for adj_e and final_e.
575   */
576 
577   for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
578     INT maxSfbNrg_e = -FRACT_BITS+NRG_EXP_OFFSET; /* start value for maximum search */
579 
580     /* Fetch frequency resolution for current envelope: */
581     for (j=hFreq->nSfb[hFrameData->frameInfo.freqRes[i]]; j!=0; j--) {
582       maxSfbNrg_e = fixMax(maxSfbNrg_e,(INT)((LONG)(*pIenv++) & MASK_E));
583     }
584     maxSfbNrg_e -= NRG_EXP_OFFSET;
585 
586     /* Energy -> magnitude (sqrt halfens exponent) */
587     maxSfbNrg_e = (maxSfbNrg_e+1) >> 1;  /* +1 to go safe (round to next higher int) */
588 
589     /* Some safety margin is needed for 2 reasons:
590        - The signal energy is not equally spread over all subband samples in
591          a specific sfb of an envelope (Nrg could be too high by a factor of
592          envWidth * sfbWidth)
593        - Smoothing can smear high gains of the previous envelope into the current
594     */
595     maxSfbNrg_e += 6;
596 
597     if (borders[i] < hHeaderData->numberTimeSlots)
598       /* This envelope affects timeslots that belong to the output frame */
599       adj_e = (maxSfbNrg_e > adj_e) ? maxSfbNrg_e : adj_e;
600 
601     if (borders[i+1] > hHeaderData->numberTimeSlots)
602       /* This envelope affects timeslots after the output frame */
603       final_e =  (maxSfbNrg_e > final_e) ? maxSfbNrg_e : final_e;
604 
605   }
606 
607   /*
608     Calculate adjustment factors and apply them for every envelope.
609   */
610   pIenv = hFrameData->iEnvelope;
611 
612   for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
613 
614     int k, noNoiseFlag;
615     SCHAR  noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
616     C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
617 
618     /*
619       Helper variables.
620     */
621     UCHAR start_pos = hHeaderData->timeStep * borders[i];  /* Start-position in time (subband sample) for current envelope. */
622     UCHAR stop_pos = hHeaderData->timeStep * borders[i+1]; /* Stop-position in time (subband sample) for current envelope. */
623     UCHAR freq_res = hFrameData->frameInfo.freqRes[i];     /* Frequency resolution for current envelope. */
624 
625 
626     /* Always do fully initialize the temporary energy table. This prevents negative energies and extreme gain factors in
627        cases where the number of limiter bands exceeds the number of subbands. The latter can be caused by undetected bit
628        errors and is tested by some streams from the certification set. */
629     FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
630 
631     /* If the start-pos of the current envelope equals the stop pos of the current
632        noise envelope, increase the pointer (i.e. choose the next noise-floor).*/
633     if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise+1]){
634       noiseLevels += noNoiseBands;   /* The noise floor data is stored in a row [noiseFloor1 noiseFloor2...].*/
635       envNoise++;
636     }
637 
638     if(i==hFrameData->frameInfo.tranEnv || i==h_sbr_cal_env->prevTranEnv) /* attack */
639     {
640       noNoiseFlag = 1;
641       if (!useLP)
642         smooth_length = 0;  /* No smoothing on attacks! */
643     }
644     else {
645       noNoiseFlag = 0;
646       if (!useLP)
647         smooth_length = (1 - hHeaderData->bs_data.smoothingLength) << 2;  /* can become either 0 or 4 */
648     }
649 
650 
651     /*
652       Energy estimation in transposed highband.
653     */
654     if (hHeaderData->bs_data.interpolFreq)
655       calcNrgPerSubband(analysBufferReal,
656                         (useLP) ? NULL : analysBufferImag,
657                         lowSubband, highSubband,
658                         start_pos, stop_pos,
659                         input_e,
660                         pNrgs->nrgEst,
661                         pNrgs->nrgEst_e);
662     else
663       calcNrgPerSfb(analysBufferReal,
664                     (useLP) ? NULL : analysBufferImag,
665                     hFreq->nSfb[freq_res],
666                     hFreq->freqBandTable[freq_res],
667                     start_pos, stop_pos,
668                     input_e,
669                     pNrgs->nrgEst,
670                     pNrgs->nrgEst_e);
671 
672     /*
673       Calculate subband gains
674     */
675     {
676       UCHAR * table = hFreq->freqBandTable[freq_res];
677       UCHAR * pUiNoise = &hFreq->freqBandTableNoise[1]; /*! Upper limit of the current noise floor band. */
678 
679       FIXP_SGL * pNoiseLevels = noiseLevels;
680 
681       FIXP_DBL tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
682       SCHAR    tmpNoise_e = (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
683 
684       int cc = 0;
685       c = 0;
686       for (j = 0; j < hFreq->nSfb[freq_res]; j++) {
687 
688         FIXP_DBL refNrg   = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
689         SCHAR    refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
690 
691         UCHAR sinePresentFlag = 0;
692         int li = table[j];
693         int ui = table[j+1];
694 
695         for (k=li; k<ui; k++) {
696           sinePresentFlag |= (i >= sineMapped[cc]);
697           cc++;
698         }
699 
700         for (k=li; k<ui; k++) {
701           if (k >= *pUiNoise) {
702             tmpNoise = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
703             tmpNoise_e = (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
704 
705             pUiNoise++;
706           }
707 
708           FDK_ASSERT(k >= lowSubband);
709 
710           if (useLP)
711             useAliasReduction[k-lowSubband] = !sinePresentFlag;
712 
713           pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
714           pNrgs->nrgSine_e[c] = 0;
715 
716           calcSubbandGain(refNrg, refNrg_e, pNrgs, c,
717                           tmpNoise, tmpNoise_e,
718                           sinePresentFlag, i >= sineMapped[c],
719                           noNoiseFlag);
720 
721           pNrgs->nrgRef[c]   = refNrg;
722           pNrgs->nrgRef_e[c] = refNrg_e;
723 
724           c++;
725         }
726         pIenv++;
727       }
728     }
729 
730     /*
731       Noise limiting
732     */
733 
734     for (c = 0; c < hFreq->noLimiterBands; c++) {
735 
736       FIXP_DBL sumRef, boostGain, maxGain;
737       FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
738       SCHAR   sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
739 
740       calcAvgGain(pNrgs,
741                   hFreq->limiterBandTable[c], hFreq->limiterBandTable[c+1],
742                   &sumRef, &sumRef_e,
743                   &maxGain, &maxGain_e);
744 
745       /* Multiply maxGain with limiterGain: */
746       maxGain = fMult(maxGain, FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
747       maxGain_e += FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
748 
749       /* Scale mantissa of MaxGain into range between 0.5 and 1: */
750       if (maxGain == FL2FXCONST_DBL(0.0f))
751         maxGain_e = -FRACT_BITS;
752       else {
753         SCHAR charTemp = CountLeadingBits(maxGain);
754         maxGain_e -= charTemp;
755         maxGain  <<= (int)charTemp;
756       }
757 
758       if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
759         maxGain = FL2FXCONST_DBL(0.5f);
760         maxGain_e = maxGainLimit_e;
761       }
762 
763 
764       /* Every subband gain is compared to the scaled "average gain"
765          and limited if necessary: */
766       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c+1]; k++) {
767         if ( (pNrgs->nrgGain_e[k] > maxGain_e) || (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k]>maxGain) ) {
768 
769           FIXP_DBL noiseAmp;
770           SCHAR    noiseAmp_e;
771 
772           FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
773           pNrgs->noiseLevel[k]    = fMult(pNrgs->noiseLevel[k],noiseAmp);
774           pNrgs->noiseLevel_e[k] += noiseAmp_e;
775           pNrgs->nrgGain[k]       = maxGain;
776           pNrgs->nrgGain_e[k]     = maxGain_e;
777         }
778       }
779 
780       /* -- Boost gain
781         Calculate and apply boost factor for each limiter band:
782         1. Check how much energy would be present when using the limited gain
783         2. Calculate boost factor by comparison with reference energy
784         3. Apply boost factor to compensate for the energy loss due to limiting
785       */
786       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
787 
788         /* 1.a  Add energy of adjusted signal (using preliminary gain) */
789         FIXP_DBL  tmp   = fMult(pNrgs->nrgGain[k],pNrgs->nrgEst[k]);
790         SCHAR     tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
791         FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
792 
793         /* 1.b  Add sine energy (if present) */
794         if(pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
795           FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, &accu, &accu_e);
796         }
797         else {
798           /* 1.c  Add noise energy (if present) */
799           if(noNoiseFlag == 0) {
800             FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, accu_e, &accu, &accu_e);
801           }
802         }
803       }
804 
805       /* 2.a  Calculate ratio of wanted energy and accumulated energy */
806       if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
807         boostGain = FL2FXCONST_DBL(0.6279716f);
808         boostGain_e = 2;
809       } else {
810         INT div_e;
811         boostGain = fDivNorm(sumRef, accu, &div_e);
812         boostGain_e = sumRef_e - accu_e + div_e;
813       }
814 
815 
816       /* 2.b Result too high? --> Limit the boost factor to +4 dB */
817       if((boostGain_e  > 3) ||
818          (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
819          (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f)) )
820       {
821         boostGain = FL2FXCONST_DBL(0.6279716f);
822         boostGain_e = 2;
823       }
824       /* 3.  Multiply all signal components with the boost factor */
825       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; k++) {
826         pNrgs->nrgGain[k]   = fMultDiv2(pNrgs->nrgGain[k],boostGain);
827         pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
828 
829         pNrgs->nrgSine[k]   = fMultDiv2(pNrgs->nrgSine[k],boostGain);
830         pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
831 
832         pNrgs->noiseLevel[k]   = fMultDiv2(pNrgs->noiseLevel[k],boostGain);
833         pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
834       }
835     }
836     /* End of noise limiting */
837 
838     if (useLP)
839       aliasingReduction(degreeAlias+lowSubband,
840                         pNrgs,
841                         useAliasReduction,
842                         noSubbands);
843 
844     /* For the timeslots within the range for the output frame,
845        use the same scale for the noise levels.
846        Drawback: If the envelope exceeds the frame border, the noise levels
847                  will have to be rescaled later to fit final_e of
848                  the gain-values.
849     */
850     noise_e = (start_pos < no_cols) ? adj_e : final_e;
851 
852     /*
853       Convert energies to amplitude levels
854     */
855     for (k=0; k<noSubbands; k++) {
856       FDK_sqrt_MantExp(&pNrgs->nrgSine[k],    &pNrgs->nrgSine_e[k],    &noise_e);
857       FDK_sqrt_MantExp(&pNrgs->nrgGain[k],    &pNrgs->nrgGain_e[k],    &pNrgs->nrgGain_e[k]);
858       FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], &noise_e);
859     }
860 
861 
862 
863     /*
864       Apply calculated gains and adaptive noise
865     */
866 
867     /* assembleHfSignals() */
868     {
869       int scale_change, sc_change;
870       FIXP_SGL smooth_ratio;
871       int filtBufferNoiseShift=0;
872 
873       /* Initialize smoothing buffers with the first valid values */
874       if (h_sbr_cal_env->startUp)
875       {
876         if (!useLP) {
877           h_sbr_cal_env->filtBufferNoise_e = noise_e;
878 
879           FDKmemcpy(h_sbr_cal_env->filtBuffer_e,    pNrgs->nrgGain_e,  noSubbands*sizeof(SCHAR));
880           FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
881           FDKmemcpy(h_sbr_cal_env->filtBuffer,      pNrgs->nrgGain,    noSubbands*sizeof(FIXP_DBL));
882 
883         }
884         h_sbr_cal_env->startUp = 0;
885       }
886 
887       if (!useLP) {
888 
889         equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer,    /* buffered */
890                               h_sbr_cal_env->filtBuffer_e,  /* buffered */
891                               pNrgs->nrgGain,               /* current  */
892                               pNrgs->nrgGain_e,             /* current  */
893                               noSubbands);
894 
895         /* Adapt exponent of buffered noise levels to the current exponent
896            so they can easily be smoothed */
897         if((h_sbr_cal_env->filtBufferNoise_e - noise_e)>=0) {
898           int shift = fixMin(DFRACT_BITS-1,(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
899           for (k=0; k<noSubbands; k++)
900             h_sbr_cal_env->filtBufferNoise[k] <<= shift;
901         }
902         else {
903           int shift = fixMin(DFRACT_BITS-1,-(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
904           for (k=0; k<noSubbands; k++)
905             h_sbr_cal_env->filtBufferNoise[k] >>= shift;
906         }
907 
908         h_sbr_cal_env->filtBufferNoise_e = noise_e;
909       }
910 
911       /* find best scaling! */
912       scale_change = -(DFRACT_BITS-1);
913       for(k=0;k<noSubbands;k++) {
914           scale_change = fixMax(scale_change,(int)pNrgs->nrgGain_e[k]);
915       }
916       sc_change = (start_pos<no_cols)? adj_e - input_e : final_e - input_e;
917 
918       if ((scale_change-sc_change+1)<0)
919           scale_change-=(scale_change-sc_change+1);
920 
921       scale_change = (scale_change-sc_change)+1;
922 
923       for(k=0;k<noSubbands;k++) {
924           int sc = scale_change-pNrgs->nrgGain_e[k] + (sc_change-1);
925           pNrgs->nrgGain[k]  >>= sc;
926           pNrgs->nrgGain_e[k] += sc;
927       }
928 
929       if (!useLP) {
930         for(k=0;k<noSubbands;k++) {
931           int sc = scale_change-h_sbr_cal_env->filtBuffer_e[k] + (sc_change-1);
932           h_sbr_cal_env->filtBuffer[k] >>= sc;
933         }
934       }
935 
936       for (j = start_pos; j < stop_pos; j++)
937       {
938         /* This timeslot is located within the first part of the processing buffer
939            and will be fed into the QMF-synthesis for the current frame.
940                adj_e - input_e
941            This timeslot will not yet be fed into the QMF so we do not care
942            about the adj_e.
943                sc_change = final_e - input_e
944         */
945         if ( (j==no_cols) && (start_pos<no_cols) )
946         {
947           int shift = (int) (noise_e - final_e);
948           if (!useLP)
949             filtBufferNoiseShift = shift;               /* shifting of h_sbr_cal_env->filtBufferNoise[k] will be applied in function adjustTimeSlotHQ() */
950           if (shift>=0) {
951             shift = fixMin(DFRACT_BITS-1,shift);
952             for (k=0; k<noSubbands; k++) {
953               pNrgs->nrgSine[k] <<= shift;
954               pNrgs->noiseLevel[k]  <<= shift;
955               /*
956               if (!useLP)
957                 h_sbr_cal_env->filtBufferNoise[k]  <<= shift;
958               */
959             }
960           }
961           else {
962             shift = fixMin(DFRACT_BITS-1,-shift);
963             for (k=0; k<noSubbands; k++) {
964               pNrgs->nrgSine[k] >>= shift;
965               pNrgs->noiseLevel[k]  >>= shift;
966               /*
967               if (!useLP)
968                 h_sbr_cal_env->filtBufferNoise[k]  >>= shift;
969               */
970             }
971           }
972 
973           /* update noise scaling */
974           noise_e = final_e;
975           if (!useLP)
976             h_sbr_cal_env->filtBufferNoise_e = noise_e;  /* scaling value unused! */
977 
978           /* update gain buffer*/
979           sc_change -= (final_e - input_e);
980 
981           if (sc_change<0) {
982             for(k=0;k<noSubbands;k++) {
983                 pNrgs->nrgGain[k]  >>= -sc_change;
984                 pNrgs->nrgGain_e[k] += -sc_change;
985             }
986             if (!useLP) {
987               for(k=0;k<noSubbands;k++) {
988                     h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
989               }
990             }
991           } else {
992             scale_change+=sc_change;
993           }
994 
995         } // if
996 
997         if (!useLP) {
998 
999           /* Prevent the smoothing filter from running on constant levels */
1000           if (j-start_pos < smooth_length)
1001             smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j-start_pos];
1002           else
1003             smooth_ratio = FL2FXCONST_SGL(0.0f);
1004 
1005           adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1006                            &analysBufferImag[j][lowSubband],
1007                            h_sbr_cal_env,
1008                            pNrgs,
1009                            lowSubband,
1010                            noSubbands,
1011                            scale_change,
1012                            smooth_ratio,
1013                            noNoiseFlag,
1014                            filtBufferNoiseShift);
1015         }
1016         else
1017         {
1018           if (flags & SBRDEC_ELD_GRID) {
1019             adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband],
1020                            pNrgs,
1021                           &h_sbr_cal_env->harmIndex,
1022                            lowSubband,
1023                            noSubbands,
1024                            scale_change,
1025                            noNoiseFlag,
1026                           &h_sbr_cal_env->phaseIndex,
1027                            EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale);
1028           } else
1029           {
1030             adjustTimeSlotLC(&analysBufferReal[j][lowSubband],
1031                            pNrgs,
1032                           &h_sbr_cal_env->harmIndex,
1033                            lowSubband,
1034                            noSubbands,
1035                            scale_change,
1036                            noNoiseFlag,
1037                           &h_sbr_cal_env->phaseIndex);
1038           }
1039         }
1040       } // for
1041 
1042       if (!useLP) {
1043         /* Update time-smoothing-buffers for gains and noise levels
1044            The gains and the noise values of the current envelope are copied into the buffer.
1045            This has to be done at the end of each envelope as the values are required for
1046            a smooth transition to the next envelope. */
1047         FDKmemcpy(h_sbr_cal_env->filtBuffer,      pNrgs->nrgGain,    noSubbands*sizeof(FIXP_DBL));
1048         FDKmemcpy(h_sbr_cal_env->filtBuffer_e,    pNrgs->nrgGain_e,  noSubbands*sizeof(SCHAR));
1049         FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, noSubbands*sizeof(FIXP_DBL));
1050       }
1051 
1052     }
1053     C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1054   }
1055 
1056   /* Rescale output samples */
1057   {
1058     FIXP_DBL maxVal;
1059     int ov_reserve, reserve;
1060 
1061     /* Determine headroom in old adjusted samples */
1062     maxVal = maxSubbandSample( analysBufferReal,
1063                               (useLP) ? NULL : analysBufferImag,
1064                                lowSubband,
1065                                highSubband,
1066                                0,
1067                                first_start);
1068 
1069     ov_reserve = fNorm(maxVal);
1070 
1071     /* Determine headroom in new adjusted samples */
1072     maxVal = maxSubbandSample( analysBufferReal,
1073                                (useLP) ? NULL : analysBufferImag,
1074                                lowSubband,
1075                                highSubband,
1076                                first_start,
1077                                no_cols);
1078 
1079     reserve = fNorm(maxVal);
1080 
1081     /* Determine common output exponent */
1082     if (ov_adj_e - ov_reserve  >  adj_e - reserve ) /* set output_e to the maximum */
1083       output_e = ov_adj_e - ov_reserve;
1084     else
1085       output_e = adj_e - reserve;
1086 
1087     /* Rescale old samples */
1088     rescaleSubbandSamples( analysBufferReal,
1089                            (useLP) ? NULL : analysBufferImag,
1090                            lowSubband, highSubband,
1091                            0, first_start,
1092                            ov_adj_e - output_e);
1093 
1094     /* Rescale new samples */
1095     rescaleSubbandSamples( analysBufferReal,
1096                            (useLP) ? NULL : analysBufferImag,
1097                            lowSubband, highSubband,
1098                            first_start, no_cols,
1099                            adj_e - output_e);
1100   }
1101 
1102   /* Update hb_scale */
1103   sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
1104 
1105   /* Save the current final exponent for the next frame: */
1106   sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e);
1107 
1108 
1109   /* We need to remeber to the next frame that the transient
1110      will occur in the first envelope (if tranEnv == nEnvelopes). */
1111   if(hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1112     h_sbr_cal_env->prevTranEnv = 0;
1113   else
1114     h_sbr_cal_env->prevTranEnv = -1;
1115 
1116 }
1117 
1118 
1119 /*!
1120   \brief   Create envelope instance
1121 
1122   Must be called once for each channel before calculateSbrEnvelope() can be used.
1123 
1124   \return  errorCode, 0 if successful
1125 */
1126 SBR_ERROR
createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs,HANDLE_SBR_HEADER_DATA hHeaderData,const int chan,const UINT flags)1127 createSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs,   /*!< pointer to envelope instance */
1128                        HANDLE_SBR_HEADER_DATA hHeaderData, /*!< static SBR control data, initialized with defaults */
1129                        const int chan,                     /*!< Channel for which to assign buffers */
1130                        const UINT flags)
1131 {
1132   SBR_ERROR err = SBRDEC_OK;
1133   int i;
1134 
1135   /* Clear previous missing harmonics flags */
1136   for (i=0; i<(MAX_FREQ_COEFFS+15)>>4; i++) {
1137     hs->harmFlagsPrev[i] = 0;
1138   }
1139   hs->harmIndex = 0;
1140 
1141   /*
1142     Setup pointers for time smoothing.
1143     The buffer itself will be initialized later triggered by the startUp-flag.
1144   */
1145   hs->prevTranEnv = -1;
1146 
1147 
1148   /* initialization */
1149   resetSbrEnvelopeCalc(hs);
1150 
1151   if (chan==0) { /* do this only once */
1152     err = resetFreqBandTables(hHeaderData, flags);
1153   }
1154 
1155   return err;
1156 }
1157 
1158 /*!
1159   \brief   Create envelope instance
1160 
1161   Must be called once for each channel before calculateSbrEnvelope() can be used.
1162 
1163   \return  errorCode, 0 if successful
1164 */
1165 int
deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs)1166 deleteSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hs)
1167 {
1168   return 0;
1169 }
1170 
1171 
1172 /*!
1173   \brief   Reset envelope instance
1174 
1175   This function must be called for each channel on a change of configuration.
1176   Note that resetFreqBandTables should also be called in this case.
1177 
1178   \return  errorCode, 0 if successful
1179 */
1180 void
resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv)1181 resetSbrEnvelopeCalc (HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
1182 {
1183   hCalEnv->phaseIndex = 0;
1184 
1185   /* Noise exponent needs to be reset because the output exponent for the next frame depends on it */
1186   hCalEnv->filtBufferNoise_e = 0;
1187 
1188   hCalEnv->startUp = 1;
1189 }
1190 
1191 
1192 /*!
1193   \brief  Equalize exponents of the buffered gain values and the new ones
1194 
1195   After equalization of exponents, the FIR-filter addition for smoothing
1196   can be performed.
1197   This function is called once for each envelope before adjusting.
1198 */
equalizeFiltBufferExp(FIXP_DBL * filtBuffer,SCHAR * filtBuffer_e,FIXP_DBL * nrgGain,SCHAR * nrgGain_e,int subbands)1199 static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer,     /*!< bufferd gains */
1200                                   SCHAR    *filtBuffer_e,   /*!< exponents of bufferd gains */
1201                                   FIXP_DBL *nrgGain,        /*!< gains for current envelope */
1202                                   SCHAR    *nrgGain_e,      /*!< exponents of gains for current envelope */
1203                                   int       subbands)       /*!< Number of QMF subbands */
1204 {
1205   int   band;
1206   int  diff;
1207 
1208   for (band=0; band<subbands; band++){
1209     diff = (int) (nrgGain_e[band] - filtBuffer_e[band]);
1210     if (diff>0) {
1211       filtBuffer[band] >>= diff;   /* Compensate for the scale change by shifting the mantissa. */
1212       filtBuffer_e[band] += diff;  /* New gain is bigger, use its exponent */
1213     }
1214     else if (diff<0) {
1215       /* The buffered gains seem to be larger, but maybe there
1216          are some unused bits left in the mantissa */
1217 
1218       int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band]))-1;
1219 
1220       if ((-diff) <= reserve) {
1221         /* There is enough space in the buffered mantissa so
1222            that we can take the new exponent as common.
1223         */
1224         filtBuffer[band] <<= (-diff);
1225         filtBuffer_e[band] += diff;  /* becomes equal to *ptrNewExp */
1226       }
1227       else {
1228         filtBuffer[band] <<= reserve;   /* Shift the mantissa as far as possible: */
1229         filtBuffer_e[band] -= reserve;  /* Compensate in the exponent: */
1230 
1231         /* For the remaining difference, change the new gain value */
1232         diff = fixMin(-(reserve + diff),DFRACT_BITS-1);
1233         nrgGain[band] >>= diff;
1234         nrgGain_e[band] += diff;
1235       }
1236     }
1237   }
1238 }
1239 
1240 /*!
1241   \brief  Shift left the mantissas of all subband samples
1242           in the giventime and frequency range by the specified number of bits.
1243 
1244   This function is used to rescale the audio data in the overlap buffer
1245   which has already been envelope adjusted with the last frame.
1246 */
rescaleSubbandSamples(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos,int shift)1247 void rescaleSubbandSamples(FIXP_DBL ** re,   /*!< Real part of input and output subband samples */
1248                            FIXP_DBL ** im,   /*!< Imaginary part of input and output subband samples */
1249                            int lowSubband,   /*!< Begin of frequency range to process */
1250                            int highSubband,  /*!< End of frequency range to process */
1251                            int start_pos,    /*!< Begin of time rage (QMF-timeslot) */
1252                            int next_pos,     /*!< End of time rage (QMF-timeslot) */
1253                            int shift)        /*!< number of bits to shift */
1254 {
1255   int width = highSubband-lowSubband;
1256 
1257   if ( (width > 0) && (shift!=0) ) {
1258     if (im!=NULL) {
1259       for (int l=start_pos; l<next_pos; l++) {
1260           scaleValues(&re[l][lowSubband], width, shift);
1261           scaleValues(&im[l][lowSubband], width, shift);
1262       }
1263     } else
1264     {
1265       for (int l=start_pos; l<next_pos; l++) {
1266           scaleValues(&re[l][lowSubband], width, shift);
1267       }
1268     }
1269   }
1270 }
1271 
1272 
1273 /*!
1274   \brief   Determine headroom for shifting
1275 
1276   Determine by how much the spectrum can be shifted left
1277   for better accuracy in later processing.
1278 
1279   \return  Number of free bits in the biggest spectral value
1280 */
1281 
maxSubbandSample(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos)1282 FIXP_DBL maxSubbandSample( FIXP_DBL ** re,   /*!< Real part of input and output subband samples */
1283                            FIXP_DBL ** im,   /*!< Real part of input and output subband samples */
1284                            int lowSubband,   /*!< Begin of frequency range to process */
1285                            int highSubband,  /*!< Number of QMF bands to process */
1286                            int start_pos,    /*!< Begin of time rage (QMF-timeslot) */
1287                            int next_pos      /*!< End of time rage (QMF-timeslot) */
1288                           )
1289 {
1290   FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1291   unsigned int width = highSubband - lowSubband;
1292 
1293   FDK_ASSERT(width <= (64));
1294 
1295   if ( width > 0 ) {
1296     if (im!=NULL)
1297     {
1298       for (int l=start_pos; l<next_pos; l++)
1299       {
1300 #ifdef FUNCTION_FDK_get_maxval
1301         maxVal = FDK_get_maxval(maxVal, &re[l][lowSubband], &im[l][lowSubband], width);
1302 #else
1303         int k=width;
1304         FIXP_DBL *reTmp = &re[l][lowSubband];
1305         FIXP_DBL *imTmp = &im[l][lowSubband];
1306         do{
1307           FIXP_DBL tmp1 = *(reTmp++);
1308           FIXP_DBL tmp2 = *(imTmp++);
1309           maxVal |= (FIXP_DBL)((LONG)(tmp1)^((LONG)tmp1>>(DFRACT_BITS-1)));
1310           maxVal |= (FIXP_DBL)((LONG)(tmp2)^((LONG)tmp2>>(DFRACT_BITS-1)));
1311         } while(--k!=0);
1312 #endif
1313       }
1314     } else
1315     {
1316       for (int l=start_pos; l<next_pos; l++) {
1317         int k=width;
1318         FIXP_DBL *reTmp = &re[l][lowSubband];
1319         do{
1320           FIXP_DBL tmp = *(reTmp++);
1321           maxVal |= (FIXP_DBL)((LONG)(tmp)^((LONG)tmp>>(DFRACT_BITS-1)));
1322         }while(--k!=0);
1323       }
1324     }
1325   }
1326 
1327   return(maxVal);
1328 }
1329 
1330 #define SHIFT_BEFORE_SQUARE (3) /* (7/2) */
1331 /*!<
1332   If the accumulator does not provide enough overflow bits or
1333   does not provide a high dynamic range, the below energy calculation
1334   requires an additional shift operation for each sample.
1335   On the other hand, doing the shift allows using a single-precision
1336   multiplication for the square (at least 16bit x 16bit).
1337   For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1338   is required for the energy accumulation.
1339   Theoretically, the sample-squares can sum up to a value of 76,
1340   requiring 7 overflow bits. However since such situations are *very*
1341   rare, accu can be limited to 64.
1342   In case native saturated arithmetic is not available, overflows
1343   can be prevented by replacing the above #define by
1344     #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1345   which will result in slightly reduced accuracy.
1346 */
1347 
1348 /*!
1349   \brief  Estimates the mean energy of each filter-bank channel for the
1350           duration of the current envelope
1351 
1352   This function is used when interpolFreq is true.
1353 */
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)1354 static void calcNrgPerSubband(FIXP_DBL  **analysBufferReal, /*!< Real part of subband samples */
1355                               FIXP_DBL  **analysBufferImag, /*!< Imaginary part of subband samples */
1356                               int       lowSubband,           /*!< Begin of the SBR frequency range */
1357                               int       highSubband,          /*!< High end of the SBR frequency range */
1358                               int       start_pos,            /*!< First QMF-slot of current envelope */
1359                               int       next_pos,             /*!< Last QMF-slot of current envelope + 1 */
1360                               SCHAR     frameExp,             /*!< Common exponent for all input samples */
1361                               FIXP_DBL *nrgEst,               /*!< resulting Energy (0..1) */
1362                               SCHAR    *nrgEst_e )            /*!< Exponent of resulting Energy */
1363 {
1364   FIXP_SGL invWidth;
1365   SCHAR  preShift;
1366   SCHAR  shift;
1367   FIXP_DBL sum;
1368   int k,l;
1369 
1370   /* Divide by width of envelope later: */
1371   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
1372   /* The common exponent needs to be doubled because all mantissas are squared: */
1373   frameExp = frameExp << 1;
1374 
1375   for (k=lowSubband; k<highSubband; k++) {
1376     FIXP_DBL  bufferReal[(((1024)/(32))+(6))];
1377     FIXP_DBL  bufferImag[(((1024)/(32))+(6))];
1378     FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1379 
1380     if (analysBufferImag!=NULL)
1381     {
1382       for (l=start_pos;l<next_pos;l++)
1383       {
1384         bufferImag[l] = analysBufferImag[l][k];
1385         maxVal |= (FIXP_DBL)((LONG)(bufferImag[l])^((LONG)bufferImag[l]>>(DFRACT_BITS-1)));
1386         bufferReal[l] = analysBufferReal[l][k];
1387         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
1388       }
1389     }
1390     else
1391     {
1392       for (l=start_pos;l<next_pos;l++)
1393       {
1394         bufferReal[l] = analysBufferReal[l][k];
1395         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l])^((LONG)bufferReal[l]>>(DFRACT_BITS-1)));
1396       }
1397     }
1398 
1399     if (maxVal!=FL2FXCONST_DBL(0.f)) {
1400 
1401 
1402       /* If the accu does not provide enough overflow bits, we cannot
1403          shift the samples up to the limit.
1404          Instead, keep up to 3 free bits in each sample, i.e. up to
1405          6 bits after calculation of square.
1406          Please note the comment on saturated arithmetic above!
1407       */
1408       FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1409       preShift = CntLeadingZeros(maxVal)-1;
1410       preShift -= SHIFT_BEFORE_SQUARE;
1411 
1412       if (preShift>=0) {
1413         if (analysBufferImag!=NULL) {
1414           for (l=start_pos; l<next_pos; l++) {
1415             FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
1416             FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
1417             accu = fPow2AddDiv2(accu, temp1);
1418             accu = fPow2AddDiv2(accu, temp2);
1419           }
1420         } else
1421         {
1422           for (l=start_pos; l<next_pos; l++) {
1423             FIXP_DBL temp = bufferReal[l] << (int)preShift;
1424             accu = fPow2AddDiv2(accu, temp);
1425           }
1426         }
1427       }
1428       else {    /* if negative shift value */
1429         int negpreShift = -preShift;
1430         if (analysBufferImag!=NULL) {
1431           for (l=start_pos; l<next_pos; l++) {
1432             FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
1433             FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
1434             accu = fPow2AddDiv2(accu, temp1);
1435             accu = fPow2AddDiv2(accu, temp2);
1436           }
1437         } else
1438         {
1439           for (l=start_pos; l<next_pos; l++) {
1440             FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
1441             accu = fPow2AddDiv2(accu, temp);
1442           }
1443         }
1444       }
1445       accu <<= 1;
1446 
1447       /* Convert double precision to Mantissa/Exponent: */
1448       shift = fNorm(accu);
1449       sum = accu << (int)shift;
1450 
1451       /* Divide by width of envelope and apply frame scale: */
1452       *nrgEst++ = fMult(sum, invWidth);
1453       shift += 2 * preShift;
1454       if (analysBufferImag!=NULL)
1455         *nrgEst_e++ = frameExp - shift;
1456       else
1457         *nrgEst_e++ = frameExp - shift + 1;  /* +1 due to missing imag. part */
1458     } /* maxVal!=0 */
1459     else {
1460 
1461       /* Prevent a zero-mantissa-number from being misinterpreted
1462          due to its exponent. */
1463       *nrgEst++ = FL2FXCONST_DBL(0.0f);
1464       *nrgEst_e++ = 0;
1465     }
1466   }
1467 }
1468 
1469 /*!
1470   \brief   Estimates the mean energy of each Scale factor band for the
1471            duration of the current envelope.
1472 
1473   This function is used when interpolFreq is false.
1474 */
calcNrgPerSfb(FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,int nSfb,UCHAR * freqBandTable,int start_pos,int next_pos,SCHAR input_e,FIXP_DBL * nrgEst,SCHAR * nrgEst_e)1475 static void calcNrgPerSfb(FIXP_DBL  **analysBufferReal,  /*!< Real part of subband samples */
1476                           FIXP_DBL  **analysBufferImag,  /*!< Imaginary part of subband samples */
1477                           int       nSfb,                /*!< Number of scale factor bands */
1478                           UCHAR    *freqBandTable,       /*!< First Subband for each Sfb */
1479                           int       start_pos,           /*!< First QMF-slot of current envelope */
1480                           int       next_pos,            /*!< Last QMF-slot of current envelope + 1 */
1481                           SCHAR     input_e,             /*!< Common exponent for all input samples */
1482                           FIXP_DBL *nrgEst,              /*!< resulting Energy (0..1) */
1483                           SCHAR    *nrgEst_e )           /*!< Exponent of resulting Energy */
1484 {
1485   FIXP_SGL  invWidth;
1486   FIXP_DBL  temp;
1487   SCHAR  preShift;
1488   SCHAR   shift, sum_e;
1489   FIXP_DBL  sum;
1490 
1491   int j,k,l,li,ui;
1492   FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
1493                              but overflow bits are required for accumulation */
1494 
1495   /* Divide by width of envelope later: */
1496   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
1497   /* The common exponent needs to be doubled because all mantissas are squared: */
1498   input_e = input_e << 1;
1499 
1500   for(j=0; j<nSfb; j++) {
1501     li = freqBandTable[j];
1502     ui = freqBandTable[j+1];
1503 
1504     FIXP_DBL maxVal = maxSubbandSample( analysBufferReal,
1505                                         analysBufferImag,
1506                                         li,
1507                                         ui,
1508                                         start_pos,
1509                                         next_pos );
1510 
1511     if (maxVal!=FL2FXCONST_DBL(0.f)) {
1512 
1513       preShift = CntLeadingZeros(maxVal)-1;
1514 
1515       /* If the accu does not provide enough overflow bits, we cannot
1516          shift the samples up to the limit.
1517          Instead, keep up to 3 free bits in each sample, i.e. up to
1518          6 bits after calculation of square.
1519          Please note the comment on saturated arithmetic above!
1520       */
1521       preShift -= SHIFT_BEFORE_SQUARE;
1522 
1523       sumAll = FL2FXCONST_DBL(0.0f);
1524 
1525 
1526       for (k=li; k<ui; k++) {
1527 
1528         sumLine = FL2FXCONST_DBL(0.0f);
1529 
1530         if (analysBufferImag!=NULL) {
1531           if (preShift>=0) {
1532             for (l=start_pos; l<next_pos; l++) {
1533               temp   = analysBufferReal[l][k] << (int)preShift;
1534               sumLine += fPow2Div2(temp);
1535               temp   = analysBufferImag[l][k] << (int)preShift;
1536               sumLine += fPow2Div2(temp);
1537 
1538             }
1539           } else {
1540             for (l=start_pos; l<next_pos; l++) {
1541               temp   = analysBufferReal[l][k] >> -(int)preShift;
1542               sumLine += fPow2Div2(temp);
1543               temp   = analysBufferImag[l][k] >> -(int)preShift;
1544               sumLine += fPow2Div2(temp);
1545             }
1546           }
1547         } else
1548         {
1549           if (preShift>=0) {
1550             for (l=start_pos; l<next_pos; l++) {
1551               temp   = analysBufferReal[l][k] << (int)preShift;
1552               sumLine += fPow2Div2(temp);
1553             }
1554           } else {
1555             for (l=start_pos; l<next_pos; l++) {
1556               temp   = analysBufferReal[l][k] >> -(int)preShift;
1557               sumLine += fPow2Div2(temp);
1558             }
1559           }
1560         }
1561 
1562         /* The number of QMF-channels per SBR bands may be up to 15.
1563            Shift right to avoid overflows in sum over all channels. */
1564         sumLine = sumLine >> (4-1);
1565         sumAll  += sumLine;
1566       }
1567 
1568       /* Convert double precision to Mantissa/Exponent: */
1569       shift = fNorm(sumAll);
1570       sum = sumAll << (int)shift;
1571 
1572       /* Divide by width of envelope: */
1573       sum = fMult(sum,invWidth);
1574 
1575       /* Divide by width of Sfb: */
1576       sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui-li)));
1577 
1578       /* Set all Subband energies in the Sfb to the average energy: */
1579       if (analysBufferImag!=NULL)
1580         sum_e = input_e + 4 - shift;  /* -4 to compensate right-shift */
1581       else
1582         sum_e = input_e + 4 + 1 - shift;  /* -4 to compensate right-shift; +1 due to missing imag. part */
1583 
1584       sum_e -= 2 * preShift;
1585     } /* maxVal!=0 */
1586     else {
1587 
1588       /* Prevent a zero-mantissa-number from being misinterpreted
1589          due to its exponent. */
1590       sum = FL2FXCONST_DBL(0.0f);
1591       sum_e = 0;
1592     }
1593 
1594     for (k=li; k<ui; k++)
1595     {
1596       *nrgEst++   = sum;
1597       *nrgEst_e++ = sum_e;
1598     }
1599   }
1600 }
1601 
1602 
1603 /*!
1604   \brief  Calculate gain, noise, and additional sine level for one subband.
1605 
1606   The resulting energy gain is given by mantissa and exponent.
1607 */
calcSubbandGain(FIXP_DBL nrgRef,SCHAR nrgRef_e,ENV_CALC_NRGS * nrgs,int i,FIXP_DBL tmpNoise,SCHAR tmpNoise_e,UCHAR sinePresentFlag,UCHAR sineMapped,int noNoiseFlag)1608 static void calcSubbandGain(FIXP_DBL  nrgRef,            /*!< Reference Energy according to envelope data */
1609                             SCHAR     nrgRef_e,          /*!< Reference Energy according to envelope data (exponent) */
1610                             ENV_CALC_NRGS* nrgs,
1611                             int       i,
1612                             FIXP_DBL  tmpNoise,          /*!< Relative noise level */
1613                             SCHAR     tmpNoise_e,        /*!< Relative noise level (exponent) */
1614                             UCHAR     sinePresentFlag,   /*!< Indicates if sine is present on band */
1615                             UCHAR     sineMapped,        /*!< Indicates if sine must be added */
1616                             int       noNoiseFlag)       /*!< Flag to suppress noise addition */
1617 {
1618   FIXP_DBL  nrgEst          = nrgs->nrgEst[i];            /*!< Energy in transposed signal */
1619   SCHAR     nrgEst_e        = nrgs->nrgEst_e[i];          /*!< Energy in transposed signal (exponent) */
1620   FIXP_DBL *ptrNrgGain      = &nrgs->nrgGain[i];          /*!< Resulting energy gain */
1621   SCHAR    *ptrNrgGain_e    = &nrgs->nrgGain_e[i];        /*!< Resulting energy gain (exponent) */
1622   FIXP_DBL *ptrNoiseLevel   = &nrgs->noiseLevel[i];       /*!< Resulting absolute noise energy */
1623   SCHAR    *ptrNoiseLevel_e = &nrgs->noiseLevel_e[i];     /*!< Resulting absolute noise energy (exponent) */
1624   FIXP_DBL *ptrNrgSine      = &nrgs->nrgSine[i];          /*!< Additional sine energy */
1625   SCHAR    *ptrNrgSine_e    = &nrgs->nrgSine_e[i];        /*!< Additional sine energy (exponent) */
1626 
1627   FIXP_DBL a, b, c;
1628   SCHAR    a_e, b_e, c_e;
1629 
1630   /*
1631      This addition of 1 prevents divisions by zero in the reference code.
1632      For very small energies in nrgEst, it prevents the gains from becoming
1633      very high which could cause some trouble due to the smoothing.
1634   */
1635   b_e = (int)(nrgEst_e - 1);
1636   if (b_e>=0) {
1637     nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (nrgEst >> 1);
1638     nrgEst_e += 1;  /* shift by 1 bit to avoid overflow */
1639 
1640   } else {
1641     nrgEst = (nrgEst >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
1642     nrgEst_e = 2;  /* shift by 1 bit to avoid overflow */
1643   }
1644 
1645   /*  A = NrgRef * TmpNoise */
1646   a = fMult(nrgRef,tmpNoise);
1647   a_e = nrgRef_e + tmpNoise_e;
1648 
1649   /*  B = 1 + TmpNoise */
1650   b_e = (int)(tmpNoise_e - 1);
1651   if (b_e>=0) {
1652     b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e+1,DFRACT_BITS-1)) + (tmpNoise >> 1);
1653     b_e = tmpNoise_e + 1;  /* shift by 1 bit to avoid overflow */
1654   } else {
1655     b = (tmpNoise >> (INT)(fixMin(-b_e+1,DFRACT_BITS-1))) + (FL2FXCONST_DBL(0.5f) >> 1);
1656     b_e = 2;  /* shift by 1 bit to avoid overflow */
1657   }
1658 
1659   /*  noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
1660   FDK_divide_MantExp( a,  a_e,
1661                       b,  b_e,
1662                       ptrNoiseLevel, ptrNoiseLevel_e);
1663 
1664   if (sinePresentFlag) {
1665 
1666     /*  C = (1 + TmpNoise) * NrgEst */
1667     c = fMult(b,nrgEst);
1668     c_e = b_e + nrgEst_e;
1669 
1670     /*  gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
1671     FDK_divide_MantExp( a,  a_e,
1672                         c,  c_e,
1673                         ptrNrgGain, ptrNrgGain_e);
1674 
1675     if (sineMapped) {
1676 
1677       /*  sineLevel = nrgRef/ (1 + TmpNoise) */
1678       FDK_divide_MantExp( nrgRef,  nrgRef_e,
1679                           b,  b_e,
1680                           ptrNrgSine, ptrNrgSine_e);
1681     }
1682   }
1683   else {
1684     if (noNoiseFlag) {
1685       /*  B = NrgEst */
1686       b = nrgEst;
1687       b_e = nrgEst_e;
1688     }
1689     else {
1690       /*  B = NrgEst * (1 + TmpNoise) */
1691       b = fMult(b,nrgEst);
1692       b_e = b_e + nrgEst_e;
1693     }
1694 
1695 
1696     /*  gain = nrgRef / B */
1697     FDK_divide_MantExp( nrgRef,  nrgRef_e,
1698                         b,  b_e,
1699                         ptrNrgGain, ptrNrgGain_e);
1700   }
1701 }
1702 
1703 
1704 /*!
1705   \brief  Calculate "average gain" for the specified subband range.
1706 
1707   This is rather a gain of the average magnitude than the average
1708   of gains!
1709   The result is used as a relative limit for all gains within the
1710   current "limiter band" (a certain frequency range).
1711 */
calcAvgGain(ENV_CALC_NRGS * nrgs,int lowSubband,int highSubband,FIXP_DBL * ptrSumRef,SCHAR * ptrSumRef_e,FIXP_DBL * ptrAvgGain,SCHAR * ptrAvgGain_e)1712 static void calcAvgGain(ENV_CALC_NRGS* nrgs,
1713                         int        lowSubband,    /*!< Begin of the limiter band */
1714                         int        highSubband,   /*!< High end of the limiter band */
1715                         FIXP_DBL  *ptrSumRef,
1716                         SCHAR     *ptrSumRef_e,
1717                         FIXP_DBL  *ptrAvgGain,  /*!< Resulting overall gain (mantissa) */
1718                         SCHAR     *ptrAvgGain_e)  /*!< Resulting overall gain (exponent) */
1719 {
1720   FIXP_DBL  *nrgRef   = nrgs->nrgRef;       /*!< Reference Energy according to envelope data */
1721   SCHAR     *nrgRef_e = nrgs->nrgRef_e;     /*!< Reference Energy according to envelope data (exponent) */
1722   FIXP_DBL  *nrgEst   = nrgs->nrgEst;       /*!< Energy in transposed signal */
1723   SCHAR     *nrgEst_e = nrgs->nrgEst_e;     /*!< Energy in transposed signal (exponent) */
1724 
1725   FIXP_DBL sumRef = 1;
1726   FIXP_DBL sumEst = 1;
1727   SCHAR    sumRef_e = -FRACT_BITS;
1728   SCHAR    sumEst_e = -FRACT_BITS;
1729   int      k;
1730 
1731   for (k=lowSubband; k<highSubband; k++){
1732     /* Add nrgRef[k] to sumRef: */
1733     FDK_add_MantExp( sumRef, sumRef_e,
1734                      nrgRef[k], nrgRef_e[k],
1735                      &sumRef, &sumRef_e );
1736 
1737     /* Add nrgEst[k] to sumEst: */
1738     FDK_add_MantExp( sumEst, sumEst_e,
1739                      nrgEst[k], nrgEst_e[k],
1740                      &sumEst, &sumEst_e );
1741   }
1742 
1743   FDK_divide_MantExp(sumRef, sumRef_e,
1744                      sumEst, sumEst_e,
1745                      ptrAvgGain, ptrAvgGain_e);
1746 
1747   *ptrSumRef = sumRef;
1748   *ptrSumRef_e = sumRef_e;
1749 }
1750 
adjustTimeSlot_EldGrid(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex,int scale_diff_low)1751 static void adjustTimeSlot_EldGrid(
1752                               FIXP_DBL *ptrReal,        /*!< Subband samples to be adjusted, real part */
1753                               ENV_CALC_NRGS* nrgs,
1754                               UCHAR    *ptrHarmIndex,   /*!< Harmonic index */
1755                               int       lowSubband,     /*!< Lowest QMF-channel in the currently used SBR range. */
1756                               int       noSubbands,     /*!< Number of QMF subbands */
1757                               int       scale_change,   /*!< Number of bits to shift adjusted samples */
1758                               int       noNoiseFlag,    /*!< Flag to suppress noise addition */
1759                               int      *ptrPhaseIndex,  /*!< Start index to random number array */
1760                               int       scale_diff_low) /*!<  */
1761 {
1762   int k;
1763   FIXP_DBL  signalReal, sbNoise;
1764   int tone_count = 0;
1765 
1766   FIXP_DBL *pGain       = nrgs->nrgGain;     /*!< Gains of current envelope */
1767   FIXP_DBL *pNoiseLevel = nrgs->noiseLevel;  /*!< Noise levels of current envelope */
1768   FIXP_DBL *pSineLevel  = nrgs->nrgSine;     /*!< Sine levels */
1769 
1770   int    phaseIndex = *ptrPhaseIndex;
1771   UCHAR  harmIndex  = *ptrHarmIndex;
1772 
1773   static const INT harmonicPhase [2][4] = {
1774     { 1, 0, -1,  0},
1775     { 0, 1,  0, -1}
1776   };
1777 
1778   static const FIXP_DBL harmonicPhaseX [2][4] = {
1779     { FL2FXCONST_DBL(2.0*1.245183154539139e-001),  FL2FXCONST_DBL(2.0*-1.123767859325028e-001),  FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0* 1.123767859325028e-001) },
1780     { FL2FXCONST_DBL(2.0*1.245183154539139e-001),  FL2FXCONST_DBL(2.0* 1.123767859325028e-001),  FL2FXCONST_DBL(2.0*-1.245183154539139e-001), FL2FXCONST_DBL(2.0*-1.123767859325028e-001) }
1781   };
1782 
1783   for (k=0; k < noSubbands; k++) {
1784 
1785     phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
1786 
1787     if( (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) || (noNoiseFlag == 1) ){
1788       sbNoise = FL2FXCONST_DBL(0.0f);
1789     } else {
1790       sbNoise = pNoiseLevel[0];
1791     }
1792 
1793     signalReal = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
1794 
1795     signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise)<<4);
1796 
1797     signalReal += pSineLevel[0] * harmonicPhase[0][harmIndex];
1798 
1799     *ptrReal = signalReal;
1800 
1801     if (k == 0) {
1802       *(ptrReal-1) += scaleValue(fMultDiv2(harmonicPhaseX[lowSubband&1][harmIndex], pSineLevel[0]), -scale_diff_low)  ;
1803       if (k < noSubbands - 1) {
1804         *(ptrReal)   += fMultDiv2(pSineLevel[1], harmonicPhaseX[(lowSubband+1)&1][harmIndex]);
1805       }
1806     }
1807     if (k > 0 && k < noSubbands - 1 && tone_count < 16) {
1808       *(ptrReal)   += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1]  [harmIndex]);
1809       *(ptrReal)   += fMultDiv2(pSineLevel[+ 1], harmonicPhaseX [(lowSubband+k+1)&1][harmIndex]);
1810     }
1811     if (k == noSubbands - 1 && tone_count < 16) {
1812       if (k > 0) {
1813         *(ptrReal)   += fMultDiv2(pSineLevel[- 1], harmonicPhaseX [(lowSubband+k)&1][harmIndex]);
1814       }
1815       if (k + lowSubband + 1< 63) {
1816         *(ptrReal+1) += fMultDiv2(pSineLevel[0], harmonicPhaseX[(lowSubband+k+1)&1][harmIndex]);
1817       }
1818     }
1819 
1820     if(pSineLevel[0] != FL2FXCONST_DBL(0.0f)){
1821       tone_count++;
1822     }
1823     ptrReal++;
1824     pNoiseLevel++;
1825     pGain++;
1826     pSineLevel++;
1827   }
1828 
1829   *ptrHarmIndex = (harmIndex + 1) & 3;
1830   *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
1831 }
1832 
1833 /*!
1834   \brief   Amplify one timeslot of the signal with the calculated gains
1835            and add the noisefloor.
1836 */
1837 
adjustTimeSlotLC(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex)1838 static void adjustTimeSlotLC(FIXP_DBL *ptrReal,       /*!< Subband samples to be adjusted, real part */
1839                              ENV_CALC_NRGS* nrgs,
1840                              UCHAR    *ptrHarmIndex,  /*!< Harmonic index */
1841                              int       lowSubband,    /*!< Lowest QMF-channel in the currently used SBR range. */
1842                              int       noSubbands,    /*!< Number of QMF subbands */
1843                              int       scale_change,  /*!< Number of bits to shift adjusted samples */
1844                              int       noNoiseFlag,   /*!< Flag to suppress noise addition */
1845                              int      *ptrPhaseIndex) /*!< Start index to random number array */
1846 {
1847   FIXP_DBL *pGain       = nrgs->nrgGain;     /*!< Gains of current envelope */
1848   FIXP_DBL *pNoiseLevel = nrgs->noiseLevel;  /*!< Noise levels of current envelope */
1849   FIXP_DBL *pSineLevel  = nrgs->nrgSine;     /*!< Sine levels */
1850 
1851   int    k;
1852   int    index = *ptrPhaseIndex;
1853   UCHAR  harmIndex = *ptrHarmIndex;
1854   UCHAR  freqInvFlag = (lowSubband & 1);
1855   FIXP_DBL  signalReal, sineLevel, sineLevelNext, sineLevelPrev;
1856   int    tone_count = 0;
1857   int    sineSign = 1;
1858 
1859   #define C1   ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.00815f))
1860   #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f*0.16773f))
1861 
1862   /*
1863     First pass for k=0 pulled out of the loop:
1864   */
1865 
1866   index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
1867 
1868   /*
1869     The next multiplication constitutes the actual envelope adjustment
1870     of the signal and should be carried out with full accuracy
1871     (supplying #FRACT_BITS valid bits).
1872   */
1873   signalReal    = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1874   sineLevel     = *pSineLevel++;
1875   sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
1876 
1877   if (sineLevel!=FL2FXCONST_DBL(0.0f)) tone_count++;
1878   else if (!noNoiseFlag)
1879         /* Add noisefloor to the amplified signal */
1880         signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1881 
1882   {
1883     if (!(harmIndex&0x1)) {
1884       /* harmIndex 0,2 */
1885       signalReal += (harmIndex&0x2) ? -sineLevel : sineLevel;
1886       *ptrReal++ = signalReal;
1887     }
1888     else {
1889       /* harmIndex 1,3 in combination with freqInvFlag */
1890       int shift = (int) (scale_change+1);
1891       shift = (shift>=0) ? fixMin(DFRACT_BITS-1,shift) : fixMax(-(DFRACT_BITS-1),shift);
1892 
1893       FIXP_DBL tmp1 = (shift>=0) ? ( fMultDiv2(C1, sineLevel) >> shift )
1894                                  : ( fMultDiv2(C1, sineLevel) << (-shift) );
1895       FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
1896 
1897 
1898       /* save switch and compare operations and reduce to XOR statement */
1899       if ( ((harmIndex>>1)&0x1)^freqInvFlag) {
1900           *(ptrReal-1) += tmp1;
1901           signalReal   -= tmp2;
1902       } else {
1903           *(ptrReal-1) -= tmp1;
1904           signalReal   += tmp2;
1905       }
1906       *ptrReal++ = signalReal;
1907       freqInvFlag = !freqInvFlag;
1908     }
1909   }
1910 
1911   pNoiseLevel++;
1912 
1913   if ( noSubbands > 2 ) {
1914     if (!(harmIndex&0x1)) {
1915       /* harmIndex 0,2 */
1916       if(!harmIndex)
1917       {
1918         sineSign = 0;
1919       }
1920 
1921       for (k=noSubbands-2; k!=0; k--) {
1922         FIXP_DBL sinelevel = *pSineLevel++;
1923         index++;
1924         if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == FL2FXCONST_DBL(0.0f))  && !noNoiseFlag)
1925         {
1926           /* Add noisefloor to the amplified signal */
1927           index &= (SBR_NF_NO_RANDOM_VAL - 1);
1928           signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1929         }
1930 
1931         /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1932         signalReal += fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1933 
1934         pNoiseLevel++;
1935         *ptrReal++ = signalReal;
1936       } /* for ... */
1937     }
1938     else {
1939       /* harmIndex 1,3 in combination with freqInvFlag */
1940       if (harmIndex==1) freqInvFlag = !freqInvFlag;
1941 
1942       for (k=noSubbands-2; k!=0; k--) {
1943         index++;
1944         /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1945         signalReal = fMultDiv2(*ptrReal,*pGain++) << ((int)scale_change);
1946 
1947         if (*pSineLevel++!=FL2FXCONST_DBL(0.0f)) tone_count++;
1948         else if (!noNoiseFlag) {
1949           /* Add noisefloor to the amplified signal */
1950           index &= (SBR_NF_NO_RANDOM_VAL - 1);
1951           signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1952         }
1953 
1954         pNoiseLevel++;
1955 
1956         if (tone_count <= 16) {
1957           FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
1958           signalReal += (freqInvFlag) ? (-addSine) : (addSine);
1959         }
1960 
1961         *ptrReal++ = signalReal;
1962         freqInvFlag = !freqInvFlag;
1963       } /* for ... */
1964     }
1965   }
1966 
1967   if (noSubbands > -1) {
1968     index++;
1969     /* The next multiplication constitutes the actual envelope adjustment of the signal. */
1970     signalReal    = fMultDiv2(*ptrReal,*pGain) << ((int)scale_change);
1971     sineLevelPrev = fMultDiv2(pSineLevel[-1],FL2FX_SGL(0.0163f));
1972     sineLevel     = pSineLevel[0];
1973 
1974     if (pSineLevel[0]!=FL2FXCONST_DBL(0.0f)) tone_count++;
1975     else if (!noNoiseFlag) {
1976         /* Add noisefloor to the amplified signal */
1977         index &= (SBR_NF_NO_RANDOM_VAL - 1);
1978         signalReal = signalReal + (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0])<<4);
1979     }
1980 
1981     if (!(harmIndex&0x1)) {
1982       /* harmIndex 0,2 */
1983       *ptrReal = signalReal + ( (sineSign) ? -sineLevel : sineLevel);
1984     }
1985     else {
1986       /* harmIndex 1,3 in combination with freqInvFlag */
1987       if(tone_count <= 16){
1988         if (freqInvFlag) {
1989           *ptrReal++   = signalReal - sineLevelPrev;
1990           if (noSubbands + lowSubband < 63)
1991             *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
1992         }
1993         else {
1994           *ptrReal++ = signalReal + sineLevelPrev;
1995           if (noSubbands + lowSubband < 63)
1996             *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
1997         }
1998       }
1999       else *ptrReal = signalReal;
2000     }
2001   }
2002   *ptrHarmIndex = (harmIndex + 1) & 3;
2003   *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2004 }
adjustTimeSlotHQ(FIXP_DBL * RESTRICT ptrReal,FIXP_DBL * RESTRICT ptrImag,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,ENV_CALC_NRGS * nrgs,int lowSubband,int noSubbands,int scale_change,FIXP_SGL smooth_ratio,int noNoiseFlag,int filtBufferNoiseShift)2005 static void adjustTimeSlotHQ(
2006                       FIXP_DBL *RESTRICT ptrReal,      /*!< Subband samples to be adjusted, real part */
2007                       FIXP_DBL *RESTRICT ptrImag,      /*!< Subband samples to be adjusted, imag part */
2008                       HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
2009                       ENV_CALC_NRGS* nrgs,
2010                       int       lowSubband,            /*!< Lowest QMF-channel in the currently used SBR range. */
2011                       int       noSubbands,            /*!< Number of QMF subbands */
2012                       int       scale_change,          /*!< Number of bits to shift adjusted samples */
2013                       FIXP_SGL  smooth_ratio,          /*!< Impact of last envelope */
2014                       int       noNoiseFlag,           /*!< Start index to random number array */
2015                       int       filtBufferNoiseShift)  /*!< Shift factor of filtBufferNoise */
2016 {
2017 
2018   FIXP_DBL *RESTRICT gain       = nrgs->nrgGain;        /*!< Gains of current envelope */
2019   FIXP_DBL *RESTRICT noiseLevel = nrgs->noiseLevel;     /*!< Noise levels of current envelope */
2020   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine;        /*!< Sine levels */
2021 
2022   FIXP_DBL *RESTRICT filtBuffer      = h_sbr_cal_env->filtBuffer;      /*!< Gains of last envelope */
2023   FIXP_DBL *RESTRICT filtBufferNoise = h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2024   UCHAR    *RESTRICT ptrHarmIndex    =&h_sbr_cal_env->harmIndex;       /*!< Harmonic index */
2025   int      *RESTRICT ptrPhaseIndex   =&h_sbr_cal_env->phaseIndex;      /*!< Start index to random number array */
2026 
2027   int    k;
2028   FIXP_DBL signalReal, signalImag;
2029   FIXP_DBL noiseReal,  noiseImag;
2030   FIXP_DBL  smoothedGain, smoothedNoise;
2031   FIXP_SGL direct_ratio = /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2032   int    index = *ptrPhaseIndex;
2033   UCHAR   harmIndex = *ptrHarmIndex;
2034   register int freqInvFlag = (lowSubband & 1);
2035   FIXP_DBL sineLevel;
2036   int shift;
2037 
2038   *ptrPhaseIndex = (index+noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2039   *ptrHarmIndex = (harmIndex + 1) & 3;
2040 
2041   /*
2042     Possible optimization:
2043     smooth_ratio and harmIndex stay constant during the loop.
2044     It might be faster to include a separate loop in each path.
2045 
2046     the check for smooth_ratio is now outside the loop and the workload
2047     of the whole function decreased by about 20 %
2048   */
2049 
2050   filtBufferNoiseShift += 1;      /* due to later use of fMultDiv2 instead of fMult */
2051   if (filtBufferNoiseShift<0)
2052     shift = fixMin(DFRACT_BITS-1,-filtBufferNoiseShift);
2053   else
2054     shift = fixMin(DFRACT_BITS-1, filtBufferNoiseShift);
2055 
2056   if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2057 
2058     for (k=0; k<noSubbands; k++) {
2059       /*
2060         Smoothing: The old envelope has been bufferd and a certain ratio
2061         of the old gains and noise levels is used.
2062       */
2063 
2064       smoothedGain = fMult(smooth_ratio,filtBuffer[k]) +
2065                      fMult(direct_ratio,gain[k]);
2066 
2067       if (filtBufferNoiseShift<0) {
2068         smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])>>shift) +
2069                          fMult(direct_ratio,noiseLevel[k]);
2070       }
2071       else {
2072         smoothedNoise = (fMultDiv2(smooth_ratio,filtBufferNoise[k])<<shift) +
2073                          fMult(direct_ratio,noiseLevel[k]);
2074       }
2075 
2076       /*
2077         The next 2 multiplications constitute the actual envelope adjustment
2078         of the signal and should be carried out with full accuracy
2079         (supplying #DFRACT_BITS valid bits).
2080       */
2081       signalReal = fMultDiv2(*ptrReal,smoothedGain)<<((int)scale_change);
2082       signalImag = fMultDiv2(*ptrImag,smoothedGain)<<((int)scale_change);
2083 
2084       index++;
2085 
2086       if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2087         sineLevel = pSineLevel[k];
2088 
2089         switch(harmIndex) {
2090         case 0:
2091           *ptrReal++ = (signalReal + sineLevel);
2092           *ptrImag++ = (signalImag);
2093           break;
2094         case 2:
2095           *ptrReal++ = (signalReal - sineLevel);
2096           *ptrImag++ = (signalImag);
2097           break;
2098         case 1:
2099           *ptrReal++ = (signalReal);
2100           if (freqInvFlag)
2101             *ptrImag++ = (signalImag - sineLevel);
2102           else
2103             *ptrImag++ = (signalImag + sineLevel);
2104           break;
2105         case 3:
2106           *ptrReal++ = signalReal;
2107           if (freqInvFlag)
2108             *ptrImag++ = (signalImag + sineLevel);
2109           else
2110             *ptrImag++ = (signalImag - sineLevel);
2111           break;
2112         }
2113       }
2114       else {
2115         if (noNoiseFlag) {
2116           /* Just the amplified signal is saved */
2117           *ptrReal++ = (signalReal);
2118           *ptrImag++ = (signalImag);
2119         }
2120         else {
2121           /* Add noisefloor to the amplified signal */
2122           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2123           noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise)<<4;
2124           noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise)<<4;
2125           *ptrReal++ = (signalReal + noiseReal);
2126           *ptrImag++ = (signalImag + noiseImag);
2127         }
2128       }
2129       freqInvFlag ^= 1;
2130     }
2131 
2132   }
2133   else
2134   {
2135     for (k=0; k<noSubbands; k++)
2136     {
2137       smoothedGain  = gain[k];
2138       signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change;
2139       signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change;
2140 
2141       index++;
2142 
2143       if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f))
2144       {
2145         switch (harmIndex)
2146         {
2147         case 0:
2148           signalReal += sineLevel;
2149           break;
2150         case 1:
2151           if (freqInvFlag)
2152             signalImag -= sineLevel;
2153           else
2154             signalImag += sineLevel;
2155           break;
2156         case 2:
2157           signalReal -= sineLevel;
2158           break;
2159         case 3:
2160           if (freqInvFlag)
2161             signalImag += sineLevel;
2162           else
2163             signalImag -= sineLevel;
2164           break;
2165         }
2166       }
2167       else
2168       {
2169         if (noNoiseFlag == 0)
2170         {
2171           /* Add noisefloor to the amplified signal */
2172           smoothedNoise = noiseLevel[k];
2173           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2174           noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2175           noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2176           signalReal += noiseReal<<4;
2177           signalImag += noiseImag<<4;
2178         }
2179       }
2180       *ptrReal++ = signalReal;
2181       *ptrImag++ = signalImag;
2182 
2183       freqInvFlag ^= 1;
2184     }
2185   }
2186 }
2187 
2188 
2189 /*!
2190   \brief   Reset limiter bands.
2191 
2192   Build frequency band table for the gain limiter dependent on
2193   the previously generated transposer patch areas.
2194 
2195   \return  SBRDEC_OK if ok,  SBRDEC_UNSUPPORTED_CONFIG on error
2196 */
2197 SBR_ERROR
ResetLimiterBands(UCHAR * limiterBandTable,UCHAR * noLimiterBands,UCHAR * freqBandTable,int noFreqBands,const PATCH_PARAM * patchParam,int noPatches,int limiterBands)2198 ResetLimiterBands ( UCHAR *limiterBandTable,   /*!< Resulting band borders in QMF channels */
2199                     UCHAR *noLimiterBands,     /*!< Resulting number of limiter band */
2200                     UCHAR *freqBandTable,      /*!< Table with possible band borders */
2201                     int noFreqBands,                   /*!< Number of bands in freqBandTable */
2202                     const PATCH_PARAM *patchParam,     /*!< Transposer patch parameters */
2203                     int noPatches,                     /*!< Number of transposer patches */
2204                     int limiterBands)                  /*!< Selected 'band density' from bitstream */
2205 {
2206   int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
2207   UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
2208   int patchBorders[MAX_NUM_PATCHES + 1];
2209   int kx, k2;
2210 
2211   int lowSubband = freqBandTable[0];
2212   int highSubband = freqBandTable[noFreqBands];
2213 
2214   /* 1 limiter band. */
2215   if(limiterBands == 0) {
2216     limiterBandTable[0] = 0;
2217     limiterBandTable[1] = highSubband - lowSubband;
2218     nBands = 1;
2219   } else {
2220     for (i = 0; i < noPatches; i++) {
2221       patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
2222     }
2223     patchBorders[i] = highSubband - lowSubband;
2224 
2225     /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
2226     for (k = 0; k <= noFreqBands; k++) {
2227       workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
2228     }
2229     for (k = 1; k < noPatches; k++) {
2230       workLimiterBandTable[noFreqBands + k] = patchBorders[k];
2231     }
2232 
2233     tempNoLim = nBands = noFreqBands + noPatches - 1;
2234     shellsort(workLimiterBandTable, tempNoLim + 1);
2235 
2236     loLimIndex = 0;
2237     hiLimIndex = 1;
2238 
2239 
2240     while (hiLimIndex <= tempNoLim) {
2241       FIXP_DBL div_m, oct_m, temp;
2242       INT div_e  = 0, oct_e  = 0, temp_e = 0;
2243 
2244       k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
2245       kx = workLimiterBandTable[loLimIndex] + lowSubband;
2246 
2247       div_m  = fDivNorm(k2, kx, &div_e);
2248 
2249       /* calculate number of octaves */
2250       oct_m  = fLog2(div_m, div_e, &oct_e);
2251 
2252       /* multiply with limiterbands per octave    */
2253       /* values 1, 1.2, 2, 3 -> scale factor of 2 */
2254       temp = fMultNorm(oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], &temp_e);
2255 
2256       /* overall scale factor of temp ist addition of scalefactors from log2 calculation,
2257          limiter bands scalefactor (2) and limiter bands multiplication */
2258       temp_e += oct_e + 2;
2259 
2260       /*    div can be a maximum of 64 (k2 = 64 and kx = 1)
2261          -> oct can be a maximum of 6
2262          -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum factor of 3)
2263          -> we need a scale factor of 5 for comparisson
2264       */
2265       if (temp >> (5 - temp_e) < FL2FXCONST_DBL (0.49f) >> 5) {
2266 
2267         if (workLimiterBandTable[hiLimIndex] == workLimiterBandTable[loLimIndex]) {
2268           workLimiterBandTable[hiLimIndex] = highSubband;
2269           nBands--;
2270           hiLimIndex++;
2271           continue;
2272         }
2273         isPatchBorder[0] = isPatchBorder[1] = 0;
2274         for (k = 0; k <= noPatches; k++) {
2275           if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
2276             isPatchBorder[1] = 1;
2277             break;
2278           }
2279         }
2280         if (!isPatchBorder[1]) {
2281           workLimiterBandTable[hiLimIndex] = highSubband;
2282           nBands--;
2283           hiLimIndex++;
2284           continue;
2285         }
2286         for (k = 0; k <= noPatches; k++) {
2287           if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
2288             isPatchBorder[0] = 1;
2289             break;
2290           }
2291         }
2292         if (!isPatchBorder[0]) {
2293           workLimiterBandTable[loLimIndex] = highSubband;
2294           nBands--;
2295         }
2296       }
2297       loLimIndex = hiLimIndex;
2298       hiLimIndex++;
2299 
2300     }
2301     shellsort(workLimiterBandTable, tempNoLim + 1);
2302 
2303     /* Test if algorithm exceeded maximum allowed limiterbands */
2304     if( nBands > MAX_NUM_LIMITERS || nBands <= 0) {
2305       return SBRDEC_UNSUPPORTED_CONFIG;
2306     }
2307 
2308     /* Copy limiterbands from working buffer into final destination */
2309     for (k = 0; k <= nBands; k++) {
2310       limiterBandTable[k] = workLimiterBandTable[k];
2311     }
2312   }
2313   *noLimiterBands = nBands;
2314 
2315   return SBRDEC_OK;
2316 }
2317 
2318