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