• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6 
7  1.    INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18 
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28 
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33 
34 2.    COPYRIGHT LICENSE
35 
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39 
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42 
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48 
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51 
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54 
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60 
61 3.    NO PATENT LICENSE
62 
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67 
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70 
71 4.    DISCLAIMER
72 
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83 
84 5.    CONTACT INFORMATION
85 
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90 
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94 
95 /**************************** SBR decoder library ******************************
96 
97    Author(s):
98 
99    Description:
100 
101 *******************************************************************************/
102 
103 /*!
104   \file
105   \brief  Envelope calculation
106 
107   The envelope adjustor compares the energies present in the transposed
108   highband to the reference energies conveyed with the bitstream.
109   The highband is amplified (sometimes) or attenuated (mostly) to the
110   desired level.
111 
112   The spectral shape of the reference energies can be changed several times per
113   frame if necessary. Each set of energy values corresponding to a certain range
114   in time will be called an <em>envelope</em> here.
115   The bitstream supports several frequency scales and two resolutions. Normally,
116   one or more QMF-subbands are grouped to one SBR-band. An envelope contains
117   reference energies for each SBR-band.
118   In addition to the energy envelopes, noise envelopes are transmitted that
119   define the ratio of energy which is generated by adding noise instead of
120   transposing the lowband. The noise envelopes are given in a coarser time
121   and frequency resolution.
122   If a signal contains strong tonal components, synthetic sines can be
123   generated in individual SBR bands.
124 
125   An overlap buffer of 6 QMF-timeslots is used to allow a more
126   flexible alignment of the envelopes in time that is not restricted to the
127   core codec's frame borders.
128   Therefore the envelope adjustor has access to the spectral data of the
129   current frame as well as the last 6 QMF-timeslots of the previous frame.
130   However, in average only the data of 1 frame is being processed as
131   the adjustor is called once per frame.
132 
133   Depending on the frequency range set in the bitstream, only QMF-subbands
134   between <em>lowSubband</em> and <em>highSubband</em> are adjusted.
135 
136   Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a
137   special Mantissa-Exponent format ( see  calculateSbrEnvelope() ) are being
138   used. The main entry point for this modules is calculateSbrEnvelope().
139 
140   \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref
141   documentationOverview
142 */
143 
144 #include "env_calc.h"
145 
146 #include "sbrdec_freq_sca.h"
147 #include "env_extr.h"
148 #include "transcendent.h"
149 #include "sbr_ram.h"
150 #include "sbr_rom.h"
151 
152 #include "genericStds.h" /* need FDKpow() for debug outputs */
153 
154 #define MAX_SFB_NRG_HEADROOM (1)
155 #define MAX_VAL_NRG_HEADROOM ((((FIXP_DBL)MAXVAL_DBL) >> MAX_SFB_NRG_HEADROOM))
156 
157 typedef struct {
158   FIXP_DBL nrgRef[MAX_FREQ_COEFFS];
159   FIXP_DBL nrgEst[MAX_FREQ_COEFFS];
160   FIXP_DBL nrgGain[MAX_FREQ_COEFFS];
161   FIXP_DBL noiseLevel[MAX_FREQ_COEFFS];
162   FIXP_DBL nrgSine[MAX_FREQ_COEFFS];
163 
164   SCHAR nrgRef_e[MAX_FREQ_COEFFS];
165   SCHAR nrgEst_e[MAX_FREQ_COEFFS];
166   SCHAR nrgGain_e[MAX_FREQ_COEFFS];
167   SCHAR noiseLevel_e[MAX_FREQ_COEFFS];
168   SCHAR nrgSine_e[MAX_FREQ_COEFFS];
169   /* yet another exponent [0]: for ts < no_cols; [1]: for ts >= no_cols */
170   SCHAR exponent[2];
171 } ENV_CALC_NRGS;
172 
173 static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e,
174                                   FIXP_DBL *NrgGain, SCHAR *NrgGain_e,
175                                   int subbands);
176 
177 static void calcNrgPerSubband(FIXP_DBL **analysBufferReal,
178                               FIXP_DBL **analysBufferImag, int lowSubband,
179                               int highSubband, int start_pos, int next_pos,
180                               SCHAR frameExp, FIXP_DBL *nrgEst,
181                               SCHAR *nrgEst_e);
182 
183 static void calcNrgPerSfb(FIXP_DBL **analysBufferReal,
184                           FIXP_DBL **analysBufferImag, int nSfb,
185                           UCHAR *freqBandTable, int start_pos, int next_pos,
186                           SCHAR input_e, FIXP_DBL *nrg_est, SCHAR *nrg_est_e);
187 
188 static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e,
189                             ENV_CALC_NRGS *nrgs, int c, FIXP_DBL tmpNoise,
190                             SCHAR tmpNoise_e, UCHAR sinePresentFlag,
191                             UCHAR sineMapped, int noNoiseFlag);
192 
193 static void calcAvgGain(ENV_CALC_NRGS *nrgs, int lowSubband, int highSubband,
194                         FIXP_DBL *sumRef_m, SCHAR *sumRef_e,
195                         FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e);
196 
197 static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
198                                    UCHAR *ptrHarmIndex, int lowSubbands,
199                                    int noSubbands, int scale_change,
200                                    int noNoiseFlag, int *ptrPhaseIndex,
201                                    int scale_diff_low);
202 
203 static void adjustTimeSlotLC(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs,
204                              UCHAR *ptrHarmIndex, int lowSubbands,
205                              int noSubbands, int scale_change, int noNoiseFlag,
206                              int *ptrPhaseIndex);
207 
208 /**
209  * \brief Variant of adjustTimeSlotHQ() which only regards gain and noise but no
210  * additional harmonics
211  */
212 static void adjustTimeSlotHQ_GainAndNoise(
213     FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
214     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
215     int lowSubbands, int noSubbands, int scale_change, FIXP_SGL smooth_ratio,
216     int noNoiseFlag, int filtBufferNoiseShift);
217 /**
218  * \brief Variant of adjustTimeSlotHQ() which only adds the additional harmonics
219  */
220 static void adjustTimeSlotHQ_AddHarmonics(
221     FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
222     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
223     int lowSubbands, int noSubbands, int scale_change);
224 
225 static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag,
226                              HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,
227                              ENV_CALC_NRGS *nrgs, int lowSubbands,
228                              int noSubbands, int scale_change,
229                              FIXP_SGL smooth_ratio, int noNoiseFlag,
230                              int filtBufferNoiseShift);
231 
232 /*!
233   \brief     Map sine flags from bitstream to QMF bands
234 
235   The bitstream carries only 1 sine flag per band (Sfb) and frame.
236   This function maps every sine flag from the bitstream to a specific QMF
237   subband and to a specific envelope where the sine shall start. The result is
238   stored in the vector sineMapped which contains one entry per QMF subband. The
239   value of an entry specifies the envelope where a sine shall start. A value of
240   32 indicates that no sine is present in the subband. The missing harmonics
241   flags from the previous frame (harmFlagsPrev) determine if a sine starts at
242   the beginning of the frame or at the transient position. Additionally, the
243   flags in harmFlagsPrev are being updated by this function for the next frame.
244 */
mapSineFlags(UCHAR * freqBandTable,int nSfb,ULONG * addHarmonics,ULONG * harmFlagsPrev,ULONG * harmFlagsPrevActive,int tranEnv,SCHAR * sineMapped)245 static void mapSineFlags(
246     UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */
247     int nSfb,             /*!< Number of bands in the table */
248     ULONG *addHarmonics,  /*!< Packed addHarmonics of current frame (aligned to
249                              the MSB) */
250     ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame (aligned to
251                              the LSB) */
252     ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous frame
253                                    (aligned to the LSB) */
254     int tranEnv,                /*!< Transient position */
255     SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each
256                           QMF band */
257 
258 {
259   int i;
260   int bitcount = 31;
261   ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0};
262   ULONG *curFlags = addHarmonics;
263 
264   /*
265     Format of addHarmonics (aligned to MSB):
266 
267       Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign.
268       first word  = flags for lowest 32 sfb bands in use
269       second word = flags for higest 32 sfb bands (if present)
270 
271     Format of harmFlagsPrev (aligned to LSB):
272 
273       Index is absolute (not relative to lsb) so it is correct even if lsb
274     changes first word  = flags for lowest 32 qmf bands (0...31) second word =
275     flags for next higher 32 qmf bands (32...63)
276 
277   */
278 
279   /* Reset the output vector first */
280   FDKmemset(sineMapped, 32,
281             MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */
282   FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG));
283   for (i = 0; i < nSfb; i++) {
284     ULONG maskSfb =
285         1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */
286 
287     if (*curFlags & maskSfb) {          /* There is a sine in this band */
288       const int lsb = freqBandTable[0]; /* start of sbr range */
289       /* qmf band to which sine should be added */
290       const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1;
291       const int qmfBandDiv32 = qmfBand >> 5;
292       const int maskQmfBand =
293           1 << (qmfBand &
294                 31); /* mask to extract harmonic flag from prevFlags */
295 
296       /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */
297       harmFlagsQmfBands[qmfBandDiv32] |= maskQmfBand;
298 
299       /*
300         If there was a sine in the last frame, let it continue from the first
301         envelope on else start at the transient position. Indexing of sineMapped
302         starts relative to lsb.
303       */
304       sineMapped[qmfBand - lsb] =
305           (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv;
306       if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) {
307         harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand;
308       }
309     }
310 
311     if (bitcount-- == 0) {
312       bitcount = 31;
313       curFlags++;
314     }
315   }
316   FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands,
317             sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
318 }
319 
320 /*!
321   \brief     Restore sineMapped of previous frame
322 
323   For PVC it might happen that the PVC framing (always 0) is out of sync with
324   the SBR framing. The adding of additional harmonics is done based on the SBR
325   framing. If the SBR framing is trailing the PVC framing the sine mapping of
326   the previous SBR frame needs to be used for the overlapping time slots.
327 */
mapSineFlagsPvc(UCHAR * freqBandTable,int nSfb,ULONG * harmFlagsPrev,ULONG * harmFlagsPrevActive,SCHAR * sineMapped,int sinusoidalPos,SCHAR * sinusoidalPosPrev,int trailingSbrFrame)328 /*static*/ void mapSineFlagsPvc(
329     UCHAR *freqBandTable,       /*!< Band borders (there's only 1 flag per
330                                    band) */
331     int nSfb,                   /*!< Number of bands in the table */
332     ULONG *harmFlagsPrev,       /*!< Packed addHarmonics of previous frame
333                                    (aligned to the MSB) */
334     ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous
335                                    frame (aligned to the LSB) */
336     SCHAR *sineMapped,          /*!< Resulting vector of sine start positions
337                                    for each QMF band */
338     int sinusoidalPos,          /*!< sinusoidal position */
339     SCHAR *sinusoidalPosPrev,   /*!< sinusoidal position of previous
340                                    frame */
341     int trailingSbrFrame)       /*!< indication if the SBR framing is
342                                    trailing the PVC framing */
343 {
344   /* Reset the output vector first */
345   FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */
346 
347   if (trailingSbrFrame) {
348     /* restore sineMapped[] of previous frame */
349     int i;
350     const int lsb = freqBandTable[0];
351     const int usb = freqBandTable[nSfb];
352     for (i = lsb; i < usb; i++) {
353       const int qmfBandDiv32 = i >> 5;
354       const int maskQmfBand =
355           1 << (i & 31); /* mask to extract harmonic flag from prevFlags */
356 
357       /* Two cases need to be distinguished ... */
358       if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) {
359         /* the sine mapping already started last PVC frame -> seamlessly
360          * continue */
361         sineMapped[i - lsb] = 0;
362       } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) {
363         /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts
364          * in this frame */
365         sineMapped[i - lsb] =
366             *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots
367                                                    ahead of last frame now */
368       }
369     }
370   }
371   *sinusoidalPosPrev = sinusoidalPos;
372 }
373 
374 /*!
375   \brief     Reduce gain-adjustment induced aliasing for real valued filterbank.
376 */
aliasingReduction(FIXP_DBL * degreeAlias,ENV_CALC_NRGS * nrgs,UCHAR * useAliasReduction,int noSubbands)377 /*static*/ void aliasingReduction(
378     FIXP_DBL *degreeAlias, /*!< estimated aliasing for each QMF
379                               channel */
380     ENV_CALC_NRGS *nrgs,
381     UCHAR *useAliasReduction, /*!< synthetic sine energy for each
382                                  subband, used as flag */
383     int noSubbands)           /*!< number of QMF channels to process */
384 {
385   FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
386   SCHAR *nrgGain_e =
387       nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
388   FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
389   SCHAR *nrgEst_e =
390       nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
391   int grouping = 0, index = 0, noGroups, k;
392   int groupVector[MAX_FREQ_COEFFS];
393 
394   /* Calculate grouping*/
395   for (k = 0; k < noSubbands - 1; k++) {
396     if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) {
397       if (grouping == 0) {
398         groupVector[index++] = k;
399         grouping = 1;
400       } else {
401         if (groupVector[index - 1] + 3 == k) {
402           groupVector[index++] = k + 1;
403           grouping = 0;
404         }
405       }
406     } else {
407       if (grouping) {
408         if (useAliasReduction[k])
409           groupVector[index++] = k + 1;
410         else
411           groupVector[index++] = k;
412         grouping = 0;
413       }
414     }
415   }
416 
417   if (grouping) {
418     groupVector[index++] = noSubbands;
419   }
420   noGroups = index >> 1;
421 
422   /*Calculate new gain*/
423   for (int group = 0; group < noGroups; group++) {
424     FIXP_DBL nrgOrig = FL2FXCONST_DBL(
425         0.0f); /* Original signal energy in current group of bands */
426     SCHAR nrgOrig_e = 0;
427     FIXP_DBL nrgAmp = FL2FXCONST_DBL(
428         0.0f); /* Amplified signal energy in group (using current gains) */
429     SCHAR nrgAmp_e = 0;
430     FIXP_DBL nrgMod = FL2FXCONST_DBL(
431         0.0f); /* Signal energy in group when applying modified gains */
432     SCHAR nrgMod_e = 0;
433     FIXP_DBL groupGain; /* Total energy gain in group */
434     SCHAR groupGain_e;
435     FIXP_DBL compensation; /* Compensation factor for the energy change when
436                               applying modified gains */
437     SCHAR compensation_e;
438 
439     int startGroup = groupVector[2 * group];
440     int stopGroup = groupVector[2 * group + 1];
441 
442     /* Calculate total energy in group before and after amplification with
443      * current gains: */
444     for (k = startGroup; k < stopGroup; k++) {
445       /* Get original band energy */
446       FIXP_DBL tmp = nrgEst[k];
447       SCHAR tmp_e = nrgEst_e[k];
448 
449       FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
450 
451       /* Multiply band energy with current gain */
452       tmp = fMult(tmp, nrgGain[k]);
453       tmp_e = tmp_e + nrgGain_e[k];
454 
455       FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
456     }
457 
458     /* Calculate total energy gain in group */
459     FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain,
460                        &groupGain_e);
461 
462     for (k = startGroup; k < stopGroup; k++) {
463       FIXP_DBL tmp;
464       SCHAR tmp_e;
465 
466       FIXP_DBL alpha = degreeAlias[k];
467       if (k < noSubbands - 1) {
468         if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1];
469       }
470 
471       /* Modify gain depending on the degree of aliasing */
472       FDK_add_MantExp(
473           fMult(alpha, groupGain), groupGain_e,
474           fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,
475                 nrgGain[k]),
476           nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]);
477 
478       /* Apply modified gain to original energy */
479       tmp = fMult(nrgGain[k], nrgEst[k]);
480       tmp_e = nrgGain_e[k] + nrgEst_e[k];
481 
482       /* Accumulate energy with modified gains applied */
483       FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e);
484     }
485 
486     /* Calculate compensation factor to retain the energy of the amplified
487      * signal */
488     FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation,
489                        &compensation_e);
490 
491     /* Apply compensation factor to all gains of the group */
492     for (k = startGroup; k < stopGroup; k++) {
493       nrgGain[k] = fMult(nrgGain[k], compensation);
494       nrgGain_e[k] = nrgGain_e[k] + compensation_e;
495     }
496   }
497 }
498 
499 #define INTER_TES_SF_CHANGE 4
500 
501 typedef struct {
502   FIXP_DBL subsample_power_low[(((1024) / (32) * (4) / 2) + (3 * (4)))];
503   FIXP_DBL subsample_power_high[(((1024) / (32) * (4) / 2) + (3 * (4)))];
504   FIXP_DBL gain[(((1024) / (32) * (4) / 2) + (3 * (4)))];
505   SCHAR subsample_power_low_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
506   SCHAR subsample_power_high_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
507 } ITES_TEMP;
508 
apply_inter_tes(FIXP_DBL ** qmfReal,FIXP_DBL ** qmfImag,const QMF_SCALE_FACTOR * sbrScaleFactor,const SCHAR exp[2],const int RATE,const int startPos,const int stopPos,const int lowSubband,const int nbSubband,const UCHAR gamma_idx)509 static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag,
510                             const QMF_SCALE_FACTOR *sbrScaleFactor,
511                             const SCHAR exp[2], const int RATE,
512                             const int startPos, const int stopPos,
513                             const int lowSubband, const int nbSubband,
514                             const UCHAR gamma_idx) {
515   int highSubband = lowSubband + nbSubband;
516   FIXP_DBL *subsample_power_high, *subsample_power_low;
517   SCHAR *subsample_power_high_sf, *subsample_power_low_sf;
518   FIXP_DBL total_power_high = (FIXP_DBL)0;
519   FIXP_DBL total_power_low = (FIXP_DBL)0;
520   FIXP_DBL *gain;
521   int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
522 
523   /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */
524   int gamma_sf =
525       (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */
526 
527   int nbSubsample = stopPos - startPos;
528   int i, j;
529 
530   C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1);
531   subsample_power_high = pTmp->subsample_power_high;
532   subsample_power_low = pTmp->subsample_power_low;
533   subsample_power_high_sf = pTmp->subsample_power_high_sf;
534   subsample_power_low_sf = pTmp->subsample_power_low_sf;
535   gain = pTmp->gain;
536 
537   if (gamma_idx > 0) {
538     int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample);
539     int total_power_low_sf = 1 - DFRACT_BITS;
540     int total_power_high_sf = 1 - DFRACT_BITS;
541 
542     for (i = 0; i < nbSubsample; ++i) {
543       FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
544       FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
545       FIXP_DBL maxVal = (FIXP_DBL)0;
546 
547       int ts = startPos + i;
548 
549       int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale
550                                    : sbrScaleFactor->lb_scale;
551       low_sf = 15 - low_sf;
552 
553       for (j = 0; j < lowSubband; ++j) {
554         bufferImag[j] = qmfImag[startPos + i][j];
555         maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
556                              ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
557         bufferReal[j] = qmfReal[startPos + i][j];
558         maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
559                              ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
560       }
561 
562       subsample_power_low[i] = (FIXP_DBL)0;
563       subsample_power_low_sf[i] = 0;
564 
565       if (maxVal != FL2FXCONST_DBL(0.f)) {
566         /* multiply first, then shift for safe summation */
567         int preShift = 1 - CntLeadingZeros(maxVal);
568         int postShift = 32 - fNormz((FIXP_DBL)lowSubband);
569 
570         /* reduce preShift because otherwise we risk to square -1.f */
571         if (preShift != 0) preShift++;
572 
573         subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1;
574 
575         scaleValues(bufferReal, lowSubband, -preShift);
576         scaleValues(bufferImag, lowSubband, -preShift);
577         for (j = 0; j < lowSubband; ++j) {
578           FIXP_DBL addme;
579           addme = fPow2Div2(bufferReal[j]);
580           subsample_power_low[i] += addme >> postShift;
581           addme = fPow2Div2(bufferImag[j]);
582           subsample_power_low[i] += addme >> postShift;
583         }
584       }
585 
586       /* now get high */
587 
588       maxVal = (FIXP_DBL)0;
589 
590       int high_sf = exp[(ts < 16 * RATE) ? 0 : 1];
591 
592       for (j = lowSubband; j < highSubband; ++j) {
593         bufferImag[j] = qmfImag[startPos + i][j];
594         maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
595                              ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
596         bufferReal[j] = qmfReal[startPos + i][j];
597         maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
598                              ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
599       }
600 
601       subsample_power_high[i] = (FIXP_DBL)0;
602       subsample_power_high_sf[i] = 0;
603 
604       if (maxVal != FL2FXCONST_DBL(0.f)) {
605         int preShift = 1 - CntLeadingZeros(maxVal);
606         /* reduce preShift because otherwise we risk to square -1.f */
607         if (preShift != 0) preShift++;
608 
609         int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband));
610         subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1;
611 
612         scaleValues(&bufferReal[lowSubband], highSubband - lowSubband,
613                     -preShift);
614         scaleValues(&bufferImag[lowSubband], highSubband - lowSubband,
615                     -preShift);
616         for (j = lowSubband; j < highSubband; j++) {
617           subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift;
618           subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift;
619         }
620       }
621 
622       /* sum all together */
623       FIXP_DBL new_summand = subsample_power_low[i];
624       int new_summand_sf = subsample_power_low_sf[i];
625 
626       /* make sure the current sum, and the new summand have the same SF */
627       if (new_summand_sf > total_power_low_sf) {
628         int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf);
629         total_power_low >>= diff;
630         total_power_low_sf = new_summand_sf;
631       } else if (new_summand_sf < total_power_low_sf) {
632         new_summand >>=
633             fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf);
634       }
635 
636       total_power_low += (new_summand >> preShift2);
637 
638       new_summand = subsample_power_high[i];
639       new_summand_sf = subsample_power_high_sf[i];
640       if (new_summand_sf > total_power_high_sf) {
641         total_power_high >>=
642             fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf);
643         total_power_high_sf = new_summand_sf;
644       } else if (new_summand_sf < total_power_high_sf) {
645         new_summand >>=
646             fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf);
647       }
648 
649       total_power_high += (new_summand >> preShift2);
650     }
651 
652     total_power_low_sf += preShift2;
653     total_power_high_sf += preShift2;
654 
655     /* gain[i] = e_LOW[i] */
656     for (i = 0; i < nbSubsample; ++i) {
657       int sf2;
658       FIXP_DBL mult =
659           fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2);
660       int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2;
661 
662       if (total_power_low != FIXP_DBL(0)) {
663         gain[i] = fDivNorm(mult, total_power_low, &sf2);
664         gain_sf[i] = mult_sf - total_power_low_sf + sf2;
665         gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
666         if (gain_sf[i] < 0) {
667           gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]);
668           gain_sf[i] = 0;
669         }
670       } else {
671         if (mult == FIXP_DBL(0)) {
672           gain[i] = FIXP_DBL(0);
673           gain_sf[i] = 0;
674         } else {
675           gain[i] = (FIXP_DBL)MAXVAL_DBL;
676           gain_sf[i] = 0;
677         }
678       }
679     }
680 
681     FIXP_DBL total_power_high_after = (FIXP_DBL)0;
682     int total_power_high_after_sf = 1 - DFRACT_BITS;
683 
684     /* gain[i] = g_inter[i] */
685     for (i = 0; i < nbSubsample; ++i) {
686       /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
687       FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
688                      gain_sf[i]; /* to substract this from gain[i] */
689 
690       /* gamma is actually always 1 according to the table, so skip the
691        * fMultDiv2 */
692       FIXP_DBL mult = (gain[i] - one) >> 1;
693       int mult_sf = gain_sf[i] + gamma_sf;
694 
695       one = FL2FXCONST_DBL(0.5f) >> mult_sf;
696       gain[i] = one + mult;
697       gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
698 
699       /* set gain to at least 0.2f */
700       /* limit and calculate gain[i]^2 too */
701       FIXP_DBL gain_pow2;
702       int gain_pow2_sf;
703 
704       if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
705         gain[i] = FL2FXCONST_DBL(0.8f);
706         gain_sf[i] = -2;
707         gain_pow2 = FL2FXCONST_DBL(0.64f);
708         gain_pow2_sf = -4;
709       } else {
710         /* this upscaling seems quite important */
711         int r = CountLeadingBits(gain[i]);
712         gain[i] <<= r;
713         gain_sf[i] -= r;
714 
715         gain_pow2 = fPow2(gain[i]);
716         gain_pow2_sf = gain_sf[i] << 1;
717       }
718 
719       int room;
720       subsample_power_high[i] =
721           fMultNorm(subsample_power_high[i], gain_pow2, &room);
722       subsample_power_high_sf[i] =
723           subsample_power_high_sf[i] + gain_pow2_sf + room;
724 
725       int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
726       if (new_summand_sf > total_power_high_after_sf) {
727         total_power_high_after >>=
728             fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
729         total_power_high_after_sf = new_summand_sf;
730       } else if (new_summand_sf < total_power_high_after_sf) {
731         subsample_power_high[i] >>=
732             fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
733       }
734       total_power_high_after += subsample_power_high[i] >> preShift2;
735     }
736 
737     total_power_high_after_sf += preShift2;
738 
739     int sf2 = 0;
740     FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
741     int gain_adj_2_sf = 1;
742 
743     if ((total_power_high != (FIXP_DBL)0) &&
744         (total_power_high_after != (FIXP_DBL)0)) {
745       gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
746       gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
747     }
748 
749     FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
750     int gain_adj_sf = gain_adj_2_sf;
751 
752     for (i = 0; i < nbSubsample; ++i) {
753       int gain_e = fMax(
754           fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1),
755           -(DFRACT_BITS - 1));
756       FIXP_DBL gain_final = fMult(gain[i], gain_adj);
757       gain_final = scaleValueSaturate(gain_final, gain_e);
758 
759       for (j = lowSubband; j < highSubband; j++) {
760         qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final);
761         qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final);
762       }
763     }
764   } else { /* gamma_idx == 0 */
765     /* Inter-TES is not active. Still perform the scale change to have a
766      * consistent scaling for all envelopes of this frame. */
767     for (i = 0; i < nbSubsample; ++i) {
768       for (j = lowSubband; j < highSubband; j++) {
769         qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
770         qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
771       }
772     }
773   }
774   C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
775 }
776 
777 /*!
778   \brief  Apply spectral envelope to subband samples
779 
780   This function is called from sbr_dec.cpp in each frame.
781 
782   To enhance accuracy and due to the usage of tables for squareroots and
783   inverse, some calculations are performed with the operands being split
784   into mantissa and exponent. The variable names in the source code carry
785   the suffixes <em>_m</em> and  <em>_e</em> respectively. The control data
786   in #hFrameData containts envelope data which is represented by this format but
787   stored in single words. (See requantizeEnvelopeData() for details). This data
788   is unpacked within calculateSbrEnvelope() to follow the described suffix
789   convention.
790 
791   The actual value (comparable to the corresponding float-variable in the
792   research-implementation) of a mantissa/exponent-pair can be calculated as
793 
794   \f$ value = value\_m * 2^{value\_e} \f$
795 
796   All energies and noise levels decoded from the bitstream suit for an
797   original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$.
798   Therefore, the scale factor <em>hb_scale</em> passed into this function will
799   be converted to an 'input exponent' (#input_e), which fits the internal
800   representation.
801 
802   Before the actual processing, an exponent #adj_e for resulting adjusted
803   samples is derived from the maximum reference energy.
804 
805   Then, for each envelope, the following steps are performed:
806 
807   \li Calculate energy in the signal to be adjusted. Depending on the the value
808   of #interpolFreq (interpolation mode), this is either done seperately for each
809   QMF-subband or for each SBR-band. The resulting energies are stored in
810   #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgEst_e[#MAX_FREQ_COEFFS]
811   (exponents). \li Calculate gain and noise level for each subband:<br> \f$ gain
812   = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise =
813   \sqrt{ nrgRef \cdot noiseRatio } \f$<br> where <em>noiseRatio</em> and
814   <em>nrgRef</em> are extracted from the bitstream and <em>nrgEst</em> is the
815   subband energy before adjustment. The resulting gains are stored in
816   #nrgGain_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS]
817   (exponents), the noise levels are stored in #noiseLevel_m[#MAX_FREQ_COEFFS]
818   and #noiseLevel_e[#MAX_FREQ_COEFFS] (exponents). The sine levels are stored in
819   #nrgSine_m[#MAX_FREQ_COEFFS] and #nrgSine_e[#MAX_FREQ_COEFFS]. \li Noise
820   limiting: The gain for each subband is limited both absolutely and relatively
821   compared to the total gain over all subbands. \li Boost gain: Calculate and
822   apply boost factor for each limiter band in order to compensate for the energy
823   loss imposed by the limiting. \li Apply gains and add noise: The gains and
824   noise levels are applied to all timeslots of the current envelope. A short
825   FIR-filter (length 4 QMF-timeslots) can be used to smooth the sudden change at
826   the envelope borders. Each complex subband sample of the current timeslot is
827   multiplied by the smoothed gain, then random noise with the calculated level
828   is added.
829 
830   \note
831   To reduce the stack size, some of the local arrays could be located within
832   the time output buffer. Of the 512 samples temporarily available there,
833   about half the size is already used by #SBR_FRAME_DATA. A pointer to the
834   remaining free memory could be supplied by an additional argument to
835   calculateSbrEnvelope() in sbr_dec:
836 
837   \par
838   \code
839     calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
840                           &hSbrDec->SbrCalculateEnvelope,
841                           hHeaderData,
842                           hFrameData,
843                           QmfBufferReal,
844                           QmfBufferImag,
845                           timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) +
846   1); \endcode
847 
848   \par
849   Within calculateSbrEnvelope(), some pointers could be defined instead of the
850   arrays #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
851 
852   \par
853   \code
854     fract*        nrgRef_m = timeOutPtr;
855     SCHAR*        nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
856     fract*        nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
857     SCHAR*        nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
858     fract*        noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
859   \endcode
860 
861   <br>
862 */
calculateSbrEnvelope(QMF_SCALE_FACTOR * sbrScaleFactor,HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env,HANDLE_SBR_HEADER_DATA hHeaderData,HANDLE_SBR_FRAME_DATA hFrameData,PVC_DYNAMIC_DATA * pPvcDynamicData,FIXP_DBL ** analysBufferReal,FIXP_DBL ** analysBufferImag,const int useLP,FIXP_DBL * degreeAlias,const UINT flags,const int frameErrorFlag)863 void calculateSbrEnvelope(
864     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
865     HANDLE_SBR_CALCULATE_ENVELOPE
866         h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
867     HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
868     HANDLE_SBR_FRAME_DATA hFrameData,   /*!< Control data of current frame */
869     PVC_DYNAMIC_DATA *pPvcDynamicData,
870     FIXP_DBL *
871         *analysBufferReal, /*!< Real part of subband samples to be processed */
872     FIXP_DBL *
873         *analysBufferImag, /*!< Imag part of subband samples to be processed */
874     const int useLP,
875     FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
876     const UINT flags, const int frameErrorFlag) {
877   int c, i, i_stop, j, envNoise = 0;
878   UCHAR *borders = hFrameData->frameInfo.borders;
879   UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
880   int pvc_mode = pPvcDynamicData->pvc_mode;
881   int first_start =
882       ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
883   FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
884   HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
885   UCHAR **pFreqBandTable = hFreq->freqBandTable;
886   UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
887 
888   int lowSubband = hFreq->lowSubband;
889   int highSubband = hFreq->highSubband;
890   int noSubbands = highSubband - lowSubband;
891 
892   /* old high subband before headerchange
893      we asume no headerchange here        */
894   int ov_highSubband = hFreq->highSubband;
895 
896   int noNoiseBands = hFreq->nNfb;
897   UCHAR *noSubFrameBands = hFreq->nSfb;
898   int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
899 
900   SCHAR sineMapped[MAX_FREQ_COEFFS];
901   SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
902   SCHAR adj_e = 0;
903   SCHAR output_e;
904   SCHAR final_e = 0;
905   /* inter-TES is active in one or more envelopes of the current SBR frame */
906   const int iTES_enable = hFrameData->iTESactive;
907   const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
908   SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
909 
910   UCHAR smooth_length = 0;
911 
912   FIXP_SGL *pIenv = hFrameData->iEnvelope;
913 
914   C_ALLOC_SCRATCH_START(useAliasReduction, UCHAR, 64)
915 
916   /* if values differ we had a headerchange; if old highband is bigger then new
917      one we need to patch overlap-highband-scaling for this frame (see use of
918      ov_highSubband) as overlap contains higher frequency components which would
919      get lost */
920   if (hFreq->highSubband < hFreq->ov_highSubband) {
921     ov_highSubband = hFreq->ov_highSubband;
922   }
923 
924   if (pvc_mode > 0) {
925     if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
926       /* noise envelope of previous frame is trailing into current PVC frame */
927       envNoise = -1;
928       noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
929       noNoiseBands = h_sbr_cal_env->prevNNfb;
930       noSubFrameBands = h_sbr_cal_env->prevNSfb;
931       lowSubband = h_sbr_cal_env->prevLoSubband;
932       highSubband = h_sbr_cal_env->prevHiSubband;
933 
934       noSubbands = highSubband - lowSubband;
935       ov_highSubband = highSubband;
936       if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
937         ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
938       }
939 
940       pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
941       pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
942       pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
943     }
944 
945     mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
946                     h_sbr_cal_env->harmFlagsPrev,
947                     h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
948                     hFrameData->sinusoidal_position,
949                     &h_sbr_cal_env->sinusoidal_positionPrev,
950                     (borders[0] > bordersPvc[0]) ? 1 : 0);
951   } else {
952     /*
953       Extract sine flags for all QMF bands
954     */
955     mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
956                  hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
957                  h_sbr_cal_env->harmFlagsPrevActive,
958                  hFrameData->frameInfo.tranEnv, sineMapped);
959   }
960 
961   /*
962     Scan for maximum in bufferd noise levels.
963     This is needed in case that we had strong noise in the previous frame
964     which is smoothed into the current frame.
965     The resulting exponent is used as start value for the maximum search
966     in reference energies
967   */
968   if (!useLP)
969     adj_e = h_sbr_cal_env->filtBufferNoise_e -
970             getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
971             (INT)MAX_SFB_NRG_HEADROOM;
972 
973   /*
974     Scan for maximum reference energy to be able
975     to select appropriate values for adj_e and final_e.
976   */
977   if (pvc_mode > 0) {
978     INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
979 
980     /* Energy -> magnitude (sqrt halfens exponent) */
981     maxSfbNrg_e =
982         (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
983 
984     /* Some safety margin is needed for 2 reasons:
985        - The signal energy is not equally spread over all subband samples in
986          a specific sfb of an envelope (Nrg could be too high by a factor of
987          envWidth * sfbWidth)
988        - Smoothing can smear high gains of the previous envelope into the
989        current
990     */
991     maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
992 
993     adj_e = maxSfbNrg_e;
994     // final_e should not exist for PVC fixfix framing
995   } else {
996     for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
997       INT maxSfbNrg_e =
998           -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
999 
1000       /* Fetch frequency resolution for current envelope: */
1001       for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
1002         maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
1003       }
1004       maxSfbNrg_e -= NRG_EXP_OFFSET;
1005 
1006       /* Energy -> magnitude (sqrt halfens exponent) */
1007       maxSfbNrg_e =
1008           (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
1009 
1010       /* Some safety margin is needed for 2 reasons:
1011          - The signal energy is not equally spread over all subband samples in
1012            a specific sfb of an envelope (Nrg could be too high by a factor of
1013            envWidth * sfbWidth)
1014          - Smoothing can smear high gains of the previous envelope into the
1015          current
1016       */
1017       maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
1018 
1019       if (borders[i] < hHeaderData->numberTimeSlots)
1020         /* This envelope affects timeslots that belong to the output frame */
1021         adj_e = fMax(maxSfbNrg_e, adj_e);
1022 
1023       if (borders[i + 1] > hHeaderData->numberTimeSlots)
1024         /* This envelope affects timeslots after the output frame */
1025         final_e = fMax(maxSfbNrg_e, final_e);
1026     }
1027   }
1028   /*
1029     Calculate adjustment factors and apply them for every envelope.
1030   */
1031   pIenv = hFrameData->iEnvelope;
1032 
1033   if (pvc_mode > 0) {
1034     /* iterate over SBR time slots starting with bordersPvc[i] */
1035     i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
1036                           PVC */
1037     i_stop = PVC_NTIMESLOT;
1038     FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
1039   } else {
1040     /* iterate over SBR envelopes starting with 0 */
1041     i = 0;
1042     i_stop = hFrameData->frameInfo.nEnvelopes;
1043   }
1044   for (; i < i_stop; i++) {
1045     int k, noNoiseFlag;
1046     SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
1047     C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
1048 
1049     /*
1050       Helper variables.
1051     */
1052     int start_pos, stop_pos, freq_res;
1053     if (pvc_mode > 0) {
1054       start_pos =
1055           hHeaderData->timeStep *
1056           i; /* Start-position in time (subband sample) for current envelope. */
1057       stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
1058                                                      (subband sample) for
1059                                                      current envelope. */
1060       freq_res =
1061           hFrameData->frameInfo
1062               .freqRes[0]; /* Frequency resolution for current envelope. */
1063       FDK_ASSERT(
1064           freq_res ==
1065           hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
1066     } else {
1067       start_pos = hHeaderData->timeStep *
1068                   borders[i]; /* Start-position in time (subband sample) for
1069                                  current envelope. */
1070       stop_pos = hHeaderData->timeStep *
1071                  borders[i + 1]; /* Stop-position in time (subband sample) for
1072                                     current envelope. */
1073       freq_res =
1074           hFrameData->frameInfo
1075               .freqRes[i]; /* Frequency resolution for current envelope. */
1076     }
1077 
1078     /* Always fully initialize the temporary energy table. This prevents
1079        negative energies and extreme gain factors in cases where the number of
1080        limiter bands exceeds the number of subbands. The latter can be caused by
1081        undetected bit errors and is tested by some streams from the
1082        certification set. */
1083     FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
1084 
1085     if (pvc_mode > 0) {
1086       /* get predicted energy values from PVC module */
1087       expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
1088                     pNrgs->nrgRef_e);
1089 
1090       if (i == borders[0]) {
1091         mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
1092                      hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
1093                      h_sbr_cal_env->harmFlagsPrevActive,
1094                      hFrameData->sinusoidal_position, sineMapped);
1095       }
1096 
1097       if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1098         if (envNoise >= 0) {
1099           noiseLevels += noNoiseBands; /* The noise floor data is stored in a
1100                                           row [noiseFloor1 noiseFloor2...].*/
1101         } else {
1102           /* leave trailing noise envelope of past frame */
1103           noNoiseBands = hFreq->nNfb;
1104           noSubFrameBands = hFreq->nSfb;
1105           noiseLevels = hFrameData->sbrNoiseFloorLevel;
1106 
1107           lowSubband = hFreq->lowSubband;
1108           highSubband = hFreq->highSubband;
1109 
1110           noSubbands = highSubband - lowSubband;
1111           ov_highSubband = highSubband;
1112           if (highSubband < hFreq->ov_highSubband) {
1113             ov_highSubband = hFreq->ov_highSubband;
1114           }
1115 
1116           pFreqBandTable[0] = hFreq->freqBandTableLo;
1117           pFreqBandTable[1] = hFreq->freqBandTableHi;
1118           pFreqBandTableNoise = hFreq->freqBandTableNoise;
1119         }
1120         envNoise++;
1121       }
1122     } else {
1123       /* If the start-pos of the current envelope equals the stop pos of the
1124          current noise envelope, increase the pointer (i.e. choose the next
1125          noise-floor).*/
1126       if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1127         noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
1128                                         [noiseFloor1 noiseFloor2...].*/
1129         envNoise++;
1130       }
1131     }
1132     if (i == hFrameData->frameInfo.tranEnv ||
1133         i == h_sbr_cal_env->prevTranEnv) /* attack */
1134     {
1135       noNoiseFlag = 1;
1136       if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
1137     } else {
1138       noNoiseFlag = 0;
1139       if (!useLP)
1140         smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
1141                         << 2; /* can become either 0 or 4 */
1142     }
1143 
1144     /*
1145       Energy estimation in transposed highband.
1146     */
1147     if (hHeaderData->bs_data.interpolFreq)
1148       calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1149                         lowSubband, highSubband, start_pos, stop_pos, input_e,
1150                         pNrgs->nrgEst, pNrgs->nrgEst_e);
1151     else
1152       calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1153                     noSubFrameBands[freq_res], pFreqBandTable[freq_res],
1154                     start_pos, stop_pos, input_e, pNrgs->nrgEst,
1155                     pNrgs->nrgEst_e);
1156 
1157     /*
1158       Calculate subband gains
1159     */
1160     {
1161       UCHAR *table = pFreqBandTable[freq_res];
1162       UCHAR *pUiNoise =
1163           &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
1164                                       band. */
1165 
1166       FIXP_SGL *pNoiseLevels = noiseLevels;
1167 
1168       FIXP_DBL tmpNoise =
1169           FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1170       SCHAR tmpNoise_e =
1171           (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1172 
1173       int cc = 0;
1174       c = 0;
1175       if (pvc_mode > 0) {
1176         for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1177           UCHAR sinePresentFlag = 0;
1178           int li = table[j];
1179           int ui = table[j + 1];
1180 
1181           for (k = li; k < ui; k++) {
1182             sinePresentFlag |= (i >= sineMapped[cc]);
1183             cc++;
1184           }
1185 
1186           for (k = li; k < ui; k++) {
1187             FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
1188             SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
1189 
1190             if (k >= *pUiNoise) {
1191               tmpNoise =
1192                   FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1193               tmpNoise_e =
1194                   (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1195 
1196               pUiNoise++;
1197             }
1198 
1199             FDK_ASSERT(k >= lowSubband);
1200 
1201             if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1202 
1203             pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1204             pNrgs->nrgSine_e[c] = 0;
1205 
1206             calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1207                             sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1208 
1209             c++;
1210           }
1211         }
1212       } else {
1213         for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1214           FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
1215           SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
1216 
1217           UCHAR sinePresentFlag = 0;
1218           int li = table[j];
1219           int ui = table[j + 1];
1220 
1221           for (k = li; k < ui; k++) {
1222             sinePresentFlag |= (i >= sineMapped[cc]);
1223             cc++;
1224           }
1225 
1226           for (k = li; k < ui; k++) {
1227             if (k >= *pUiNoise) {
1228               tmpNoise =
1229                   FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1230               tmpNoise_e =
1231                   (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1232 
1233               pUiNoise++;
1234             }
1235 
1236             FDK_ASSERT(k >= lowSubband);
1237 
1238             if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1239 
1240             pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1241             pNrgs->nrgSine_e[c] = 0;
1242 
1243             calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1244                             sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1245 
1246             pNrgs->nrgRef[c] = refNrg;
1247             pNrgs->nrgRef_e[c] = refNrg_e;
1248 
1249             c++;
1250           }
1251           pIenv++;
1252         }
1253       }
1254     }
1255 
1256     /*
1257       Noise limiting
1258     */
1259 
1260     for (c = 0; c < hFreq->noLimiterBands; c++) {
1261       FIXP_DBL sumRef, boostGain, maxGain;
1262       FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1263       SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
1264       int maxGainLimGainSum_e = 0;
1265 
1266       calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
1267                   hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
1268                   &maxGain_e);
1269 
1270       /* Multiply maxGain with limiterGain: */
1271       maxGain = fMult(
1272           maxGain,
1273           FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
1274       /* maxGain_e +=
1275        * FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; */
1276       /* The addition of maxGain_e and FDK_sbrDecoder_sbr_limGains_e[3] might
1277          yield values greater than 127 which doesn't fit into an SCHAR! In these
1278          rare situations limit maxGain_e to 127.
1279       */
1280       maxGainLimGainSum_e =
1281           maxGain_e +
1282           FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
1283       maxGain_e =
1284           (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
1285 
1286       /* Scale mantissa of MaxGain into range between 0.5 and 1: */
1287       if (maxGain == FL2FXCONST_DBL(0.0f))
1288         maxGain_e = -FRACT_BITS;
1289       else {
1290         SCHAR charTemp = CountLeadingBits(maxGain);
1291         maxGain_e -= charTemp;
1292         maxGain <<= (int)charTemp;
1293       }
1294 
1295       if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
1296         maxGain = FL2FXCONST_DBL(0.5f);
1297         maxGain_e = maxGainLimit_e;
1298       }
1299 
1300       /* Every subband gain is compared to the scaled "average gain"
1301          and limited if necessary: */
1302       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1303            k++) {
1304         if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
1305             (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
1306           FIXP_DBL noiseAmp;
1307           SCHAR noiseAmp_e;
1308 
1309           FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
1310                              pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
1311           pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
1312           pNrgs->noiseLevel_e[k] += noiseAmp_e;
1313           pNrgs->nrgGain[k] = maxGain;
1314           pNrgs->nrgGain_e[k] = maxGain_e;
1315         }
1316       }
1317 
1318       /* -- Boost gain
1319         Calculate and apply boost factor for each limiter band:
1320         1. Check how much energy would be present when using the limited gain
1321         2. Calculate boost factor by comparison with reference energy
1322         3. Apply boost factor to compensate for the energy loss due to limiting
1323       */
1324       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1325            k++) {
1326         /* 1.a  Add energy of adjusted signal (using preliminary gain) */
1327         FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
1328         SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
1329         FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
1330 
1331         /* 1.b  Add sine energy (if present) */
1332         if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
1333           FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
1334                           &accu, &accu_e);
1335         } else {
1336           /* 1.c  Add noise energy (if present) */
1337           if (noNoiseFlag == 0) {
1338             FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
1339                             accu_e, &accu, &accu_e);
1340           }
1341         }
1342       }
1343 
1344       /* 2.a  Calculate ratio of wanted energy and accumulated energy */
1345       if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
1346         boostGain = FL2FXCONST_DBL(0.6279716f);
1347         boostGain_e = 2;
1348       } else {
1349         INT div_e;
1350         boostGain = fDivNorm(sumRef, accu, &div_e);
1351         boostGain_e = sumRef_e - accu_e + div_e;
1352       }
1353 
1354       /* 2.b Result too high? --> Limit the boost factor to +4 dB */
1355       if ((boostGain_e > 3) ||
1356           (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
1357           (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
1358         boostGain = FL2FXCONST_DBL(0.6279716f);
1359         boostGain_e = 2;
1360       }
1361       /* 3.  Multiply all signal components with the boost factor */
1362       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1363            k++) {
1364         pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
1365         pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
1366 
1367         pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
1368         pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
1369 
1370         pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
1371         pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
1372       }
1373     }
1374     /* End of noise limiting */
1375 
1376     if (useLP)
1377       aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
1378                         noSubbands);
1379 
1380     /* For the timeslots within the range for the output frame,
1381        use the same scale for the noise levels.
1382        Drawback: If the envelope exceeds the frame border, the noise levels
1383                  will have to be rescaled later to fit final_e of
1384                  the gain-values.
1385     */
1386     noise_e = (start_pos < no_cols) ? adj_e : final_e;
1387 
1388     if (start_pos >= no_cols) {
1389       int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e;
1390       if (diff > 0) {
1391         int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
1392         if (diff > s) {
1393           final_e += diff - s;
1394           noise_e = final_e;
1395         }
1396       }
1397     }
1398 
1399     /*
1400       Convert energies to amplitude levels
1401     */
1402     for (k = 0; k < noSubbands; k++) {
1403       FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
1404       FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
1405                        &pNrgs->nrgGain_e[k]);
1406       FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
1407                        &noise_e);
1408     }
1409 
1410     /*
1411       Apply calculated gains and adaptive noise
1412     */
1413 
1414     /* assembleHfSignals() */
1415     {
1416       int scale_change, sc_change;
1417       FIXP_SGL smooth_ratio;
1418       int filtBufferNoiseShift = 0;
1419 
1420       /* Initialize smoothing buffers with the first valid values */
1421       if (h_sbr_cal_env->startUp) {
1422         if (!useLP) {
1423           h_sbr_cal_env->filtBufferNoise_e = noise_e;
1424 
1425           FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1426                     noSubbands * sizeof(SCHAR));
1427           FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1428                     noSubbands * sizeof(FIXP_DBL));
1429           FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1430                     noSubbands * sizeof(FIXP_DBL));
1431         }
1432         h_sbr_cal_env->startUp = 0;
1433       }
1434 
1435       if (!useLP) {
1436         equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer,   /* buffered */
1437                               h_sbr_cal_env->filtBuffer_e, /* buffered */
1438                               pNrgs->nrgGain,              /* current  */
1439                               pNrgs->nrgGain_e,            /* current  */
1440                               noSubbands);
1441 
1442         /* Adapt exponent of buffered noise levels to the current exponent
1443            so they can easily be smoothed */
1444         if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
1445           int shift = fixMin(DFRACT_BITS - 1,
1446                              (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1447           for (k = 0; k < noSubbands; k++)
1448             h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1449         } else {
1450           int shift =
1451               fixMin(DFRACT_BITS - 1,
1452                      -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1453           for (k = 0; k < noSubbands; k++)
1454             h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1455         }
1456 
1457         h_sbr_cal_env->filtBufferNoise_e = noise_e;
1458       }
1459 
1460       /* find best scaling! */
1461       scale_change = -(DFRACT_BITS - 1);
1462       for (k = 0; k < noSubbands; k++) {
1463         scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
1464       }
1465       sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
1466 
1467       if ((scale_change - sc_change + 1) < 0)
1468         scale_change -= (scale_change - sc_change + 1);
1469 
1470       scale_change = (scale_change - sc_change) + 1;
1471 
1472       for (k = 0; k < noSubbands; k++) {
1473         int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
1474         pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
1475         pNrgs->nrgGain_e[k] += sc;
1476       }
1477 
1478       if (!useLP) {
1479         for (k = 0; k < noSubbands; k++) {
1480           int sc =
1481               scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
1482           h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
1483         }
1484       }
1485 
1486       for (j = start_pos; j < stop_pos; j++) {
1487         /* This timeslot is located within the first part of the processing
1488            buffer and will be fed into the QMF-synthesis for the current frame.
1489                adj_e - input_e
1490            This timeslot will not yet be fed into the QMF so we do not care
1491            about the adj_e.
1492                sc_change = final_e - input_e
1493         */
1494         if ((j == no_cols) && (start_pos < no_cols)) {
1495           int shift = (int)(noise_e - final_e);
1496           if (!useLP)
1497             filtBufferNoiseShift = shift; /* shifting of
1498                                              h_sbr_cal_env->filtBufferNoise[k]
1499                                              will be applied in function
1500                                              adjustTimeSlotHQ() */
1501           if (shift >= 0) {
1502             shift = fixMin(DFRACT_BITS - 1, shift);
1503             for (k = 0; k < noSubbands; k++) {
1504               pNrgs->nrgSine[k] <<= shift;
1505               pNrgs->noiseLevel[k] <<= shift;
1506               /*
1507               if (!useLP)
1508                 h_sbr_cal_env->filtBufferNoise[k]  <<= shift;
1509               */
1510             }
1511           } else {
1512             shift = fixMin(DFRACT_BITS - 1, -shift);
1513             for (k = 0; k < noSubbands; k++) {
1514               pNrgs->nrgSine[k] >>= shift;
1515               pNrgs->noiseLevel[k] >>= shift;
1516               /*
1517               if (!useLP)
1518                 h_sbr_cal_env->filtBufferNoise[k]  >>= shift;
1519               */
1520             }
1521           }
1522 
1523           /* update noise scaling */
1524           noise_e = final_e;
1525           if (!useLP)
1526             h_sbr_cal_env->filtBufferNoise_e =
1527                 noise_e; /* scaling value unused! */
1528 
1529           /* update gain buffer*/
1530           sc_change -= (final_e - input_e);
1531 
1532           if (sc_change < 0) {
1533             for (k = 0; k < noSubbands; k++) {
1534               pNrgs->nrgGain[k] >>= -sc_change;
1535               pNrgs->nrgGain_e[k] += -sc_change;
1536             }
1537             if (!useLP) {
1538               for (k = 0; k < noSubbands; k++) {
1539                 h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
1540               }
1541             }
1542           } else {
1543             scale_change += sc_change;
1544           }
1545 
1546         } /* if */
1547 
1548         if (!useLP) {
1549           /* Prevent the smoothing filter from running on constant levels */
1550           if (j - start_pos < smooth_length)
1551             smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
1552           else
1553             smooth_ratio = FL2FXCONST_SGL(0.0f);
1554 
1555           if (iTES_enable) {
1556             /* adjustTimeSlotHQ() without adding of additional harmonics */
1557             adjustTimeSlotHQ_GainAndNoise(
1558                 &analysBufferReal[j][lowSubband],
1559                 &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1560                 lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1),
1561                 smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
1562           } else {
1563             adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1564                              &analysBufferImag[j][lowSubband], h_sbr_cal_env,
1565                              pNrgs, lowSubband, noSubbands,
1566                              fMin(scale_change, DFRACT_BITS - 1), smooth_ratio,
1567                              noNoiseFlag, filtBufferNoiseShift);
1568           }
1569         } else {
1570           FDK_ASSERT(!iTES_enable); /* not supported */
1571           if (flags & SBRDEC_ELD_GRID) {
1572             /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
1573             adjustTimeSlot_EldGrid(
1574                 &analysBufferReal[j][lowSubband], pNrgs,
1575                 &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1576                 fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1577                 &h_sbr_cal_env->phaseIndex,
1578                 fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
1579                      -(DFRACT_BITS - 1)));
1580           } else {
1581             adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
1582                              &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1583                              fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1584                              &h_sbr_cal_env->phaseIndex);
1585           }
1586         }
1587         /* In case the envelope spans accross the no_cols border both exponents
1588          * are needed. */
1589         /* nrgGain_e[0...(noSubbands-1)] are equalized by
1590          * equalizeFiltBufferExp() */
1591         pNrgs->exponent[(j < no_cols) ? 0 : 1] =
1592             (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
1593                     scale_change);
1594       } /* for */
1595 
1596       if (iTES_enable) {
1597         apply_inter_tes(
1598             analysBufferReal, /* pABufR, */
1599             analysBufferImag, /* pABufI, */
1600             sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
1601             stop_pos, lowSubband, noSubbands,
1602             hFrameData
1603                 ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
1604         );
1605 
1606         /* add additional harmonics */
1607         for (j = start_pos; j < stop_pos; j++) {
1608           /* match exponent of additional harmonics to scale change of QMF data
1609            * caused by apply_inter_tes() */
1610           scale_change = 0;
1611 
1612           if ((start_pos <= no_cols) && (stop_pos > no_cols)) {
1613             /* Scaling of analysBuffers was potentially changed within this
1614                envelope. The pNrgs->nrgSine_e match the second part of the
1615                envelope. For (j<=no_cols) the exponent of the sine energies has
1616                to be adapted. */
1617             scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
1618           }
1619 
1620           adjustTimeSlotHQ_AddHarmonics(
1621               &analysBufferReal[j][lowSubband],
1622               &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1623               lowSubband, noSubbands,
1624               -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
1625         }
1626       }
1627 
1628       if (!useLP) {
1629         /* Update time-smoothing-buffers for gains and noise levels
1630            The gains and the noise values of the current envelope are copied
1631            into the buffer. This has to be done at the end of each envelope as
1632            the values are required for a smooth transition to the next envelope.
1633          */
1634         FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1635                   noSubbands * sizeof(FIXP_DBL));
1636         FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1637                   noSubbands * sizeof(SCHAR));
1638         FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1639                   noSubbands * sizeof(FIXP_DBL));
1640       }
1641     }
1642     C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1643   }
1644 
1645   /* adapt adj_e to the scale change caused by apply_inter_tes() */
1646   adj_e += iTES_scale_change;
1647 
1648   /* Rescale output samples */
1649   {
1650     FIXP_DBL maxVal;
1651     int ov_reserve, reserve;
1652 
1653     /* Determine headroom in old adjusted samples */
1654     maxVal =
1655         maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1656                          lowSubband, ov_highSubband, 0, first_start);
1657 
1658     ov_reserve = fNorm(maxVal);
1659 
1660     /* Determine headroom in new adjusted samples */
1661     maxVal =
1662         maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1663                          lowSubband, highSubband, first_start, no_cols);
1664 
1665     reserve = fNorm(maxVal);
1666 
1667     /* Determine common output exponent */
1668     output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
1669 
1670     /* Rescale old samples */
1671     rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1672                           lowSubband, ov_highSubband, 0, first_start,
1673                           ov_adj_e - output_e);
1674 
1675     /* Rescale new samples */
1676     rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1677                           lowSubband, highSubband, first_start, no_cols,
1678                           adj_e - output_e);
1679   }
1680 
1681   /* Update hb_scale */
1682   sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
1683 
1684   /* Save the current final exponent for the next frame: */
1685   /* adapt final_e to the scale change caused by apply_inter_tes() */
1686   sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e + iTES_scale_change);
1687 
1688   /* We need to remember to the next frame that the transient
1689      will occur in the first envelope (if tranEnv == nEnvelopes). */
1690   if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1691     h_sbr_cal_env->prevTranEnv = 0;
1692   else
1693     h_sbr_cal_env->prevTranEnv = -1;
1694 
1695   if (pvc_mode > 0) {
1696     /* Not more than just the last noise envelope reaches into the next PVC
1697        frame! This should be true because bs_noise_position is <= 15 */
1698     FDK_ASSERT(hFrameData->frameInfo
1699                    .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
1700                PVC_NTIMESLOT);
1701     if (hFrameData->frameInfo
1702             .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
1703         PVC_NTIMESLOT) {
1704       FDK_ASSERT(noiseLevels ==
1705                  (hFrameData->sbrNoiseFloorLevel +
1706                   (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
1707       h_sbr_cal_env->prevNNfb = noNoiseBands;
1708 
1709       h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
1710       h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
1711 
1712       h_sbr_cal_env->prevLoSubband = lowSubband;
1713       h_sbr_cal_env->prevHiSubband = highSubband;
1714       h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
1715 
1716       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
1717                 noSubFrameBands[0] + 1);
1718       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
1719                 noSubFrameBands[1] + 1);
1720       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
1721                 hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
1722 
1723       FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
1724                 MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
1725     }
1726   }
1727 
1728   C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
1729 }
1730 
1731 /*!
1732   \brief   Create envelope instance
1733 
1734   Must be called once for each channel before calculateSbrEnvelope() can be
1735   used.
1736 
1737   \return  errorCode, 0 if successful
1738 */
1739 SBR_ERROR
createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs,HANDLE_SBR_HEADER_DATA hHeaderData,const int chan,const UINT flags)1740 createSbrEnvelopeCalc(
1741     HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
1742     HANDLE_SBR_HEADER_DATA
1743         hHeaderData, /*!< static SBR control data, initialized with defaults */
1744     const int chan,  /*!< Channel for which to assign buffers */
1745     const UINT flags) {
1746   SBR_ERROR err = SBRDEC_OK;
1747   int i;
1748 
1749   /* Clear previous missing harmonics flags */
1750   for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
1751     hs->harmFlagsPrev[i] = 0;
1752     hs->harmFlagsPrevActive[i] = 0;
1753   }
1754   hs->harmIndex = 0;
1755 
1756   FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
1757   hs->prevNNfb = 0;
1758   FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
1759   hs->sinusoidal_positionPrev = 0;
1760 
1761   /*
1762     Setup pointers for time smoothing.
1763     The buffer itself will be initialized later triggered by the startUp-flag.
1764   */
1765   hs->prevTranEnv = -1;
1766 
1767   /* initialization */
1768   resetSbrEnvelopeCalc(hs);
1769 
1770   if (chan == 0) { /* do this only once */
1771     err = resetFreqBandTables(hHeaderData, flags);
1772   }
1773 
1774   return err;
1775 }
1776 
1777 /*!
1778   \brief   Create envelope instance
1779 
1780   Must be called once for each channel before calculateSbrEnvelope() can be
1781   used.
1782 
1783   \return  errorCode, 0 if successful
1784 */
deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs)1785 int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs) { return 0; }
1786 
1787 /*!
1788   \brief   Reset envelope instance
1789 
1790   This function must be called for each channel on a change of configuration.
1791   Note that resetFreqBandTables should also be called in this case.
1792 
1793   \return  errorCode, 0 if successful
1794 */
resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv)1795 void resetSbrEnvelopeCalc(
1796     HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
1797 {
1798   hCalEnv->phaseIndex = 0;
1799 
1800   /* Noise exponent needs to be reset because the output exponent for the next
1801    * frame depends on it */
1802   hCalEnv->filtBufferNoise_e = 0;
1803 
1804   hCalEnv->startUp = 1;
1805 }
1806 
1807 /*!
1808   \brief  Equalize exponents of the buffered gain values and the new ones
1809 
1810   After equalization of exponents, the FIR-filter addition for smoothing
1811   can be performed.
1812   This function is called once for each envelope before adjusting.
1813 */
equalizeFiltBufferExp(FIXP_DBL * filtBuffer,SCHAR * filtBuffer_e,FIXP_DBL * nrgGain,SCHAR * nrgGain_e,int subbands)1814 static void equalizeFiltBufferExp(
1815     FIXP_DBL *filtBuffer, /*!< bufferd gains */
1816     SCHAR *filtBuffer_e,  /*!< exponents of bufferd gains */
1817     FIXP_DBL *nrgGain,    /*!< gains for current envelope */
1818     SCHAR *nrgGain_e,     /*!< exponents of gains for current envelope */
1819     int subbands)         /*!< Number of QMF subbands */
1820 {
1821   int band;
1822   int diff;
1823 
1824   for (band = 0; band < subbands; band++) {
1825     diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
1826     if (diff > 0) {
1827       filtBuffer[band] >>=
1828           fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
1829                                           shifting the mantissa. */
1830       filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1831     } else if (diff < 0) {
1832       /* The buffered gains seem to be larger, but maybe there
1833          are some unused bits left in the mantissa */
1834 
1835       int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
1836 
1837       if ((-diff) <= reserve) {
1838         /* There is enough space in the buffered mantissa so
1839            that we can take the new exponent as common.
1840         */
1841         filtBuffer[band] <<= (-diff);
1842         filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1843       } else {
1844         filtBuffer[band] <<=
1845             reserve; /* Shift the mantissa as far as possible: */
1846         filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1847 
1848         /* For the remaining difference, change the new gain value */
1849         diff = -(reserve + diff);
1850         nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
1851         nrgGain_e[band] += diff;
1852       }
1853     }
1854   }
1855 }
1856 
1857 /*!
1858   \brief  Shift left the mantissas of all subband samples
1859           in the giventime and frequency range by the specified number of bits.
1860 
1861   This function is used to rescale the audio data in the overlap buffer
1862   which has already been envelope adjusted with the last frame.
1863 */
rescaleSubbandSamples(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos,int shift)1864 void rescaleSubbandSamples(
1865     FIXP_DBL **re,   /*!< Real part of input and output subband samples */
1866     FIXP_DBL **im,   /*!< Imaginary part of input and output subband samples */
1867     int lowSubband,  /*!< Begin of frequency range to process */
1868     int highSubband, /*!< End of frequency range to process */
1869     int start_pos,   /*!< Begin of time rage (QMF-timeslot) */
1870     int next_pos,    /*!< End of time rage (QMF-timeslot) */
1871     int shift)       /*!< number of bits to shift */
1872 {
1873   int width = highSubband - lowSubband;
1874 
1875   if ((width > 0) && (shift != 0)) {
1876     if (im != NULL) {
1877       for (int l = start_pos; l < next_pos; l++) {
1878         scaleValues(&re[l][lowSubband], width, shift);
1879         scaleValues(&im[l][lowSubband], width, shift);
1880       }
1881     } else {
1882       for (int l = start_pos; l < next_pos; l++) {
1883         scaleValues(&re[l][lowSubband], width, shift);
1884       }
1885     }
1886   }
1887 }
1888 
FDK_get_maxval_real(FIXP_DBL maxVal,FIXP_DBL * reTmp,INT width)1889 static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
1890                                            INT width) {
1891   maxVal = (FIXP_DBL)0;
1892   while (width-- != 0) {
1893     FIXP_DBL tmp = *(reTmp++);
1894     maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
1895   }
1896 
1897   return maxVal;
1898 }
1899 
1900 /*!
1901   \brief   Determine headroom for shifting
1902 
1903   Determine by how much the spectrum can be shifted left
1904   for better accuracy in later processing.
1905 
1906   \return  Number of free bits in the biggest spectral value
1907 */
1908 
maxSubbandSample(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos)1909 FIXP_DBL maxSubbandSample(
1910     FIXP_DBL **re,   /*!< Real part of input and output subband samples */
1911     FIXP_DBL **im,   /*!< Real part of input and output subband samples */
1912     int lowSubband,  /*!< Begin of frequency range to process */
1913     int highSubband, /*!< Number of QMF bands to process */
1914     int start_pos,   /*!< Begin of time rage (QMF-timeslot) */
1915     int next_pos     /*!< End of time rage (QMF-timeslot) */
1916 ) {
1917   FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1918   unsigned int width = highSubband - lowSubband;
1919 
1920   FDK_ASSERT(width <= (64));
1921 
1922   if (width > 0) {
1923     if (im != NULL) {
1924       for (int l = start_pos; l < next_pos; l++) {
1925         int k = width;
1926         FIXP_DBL *reTmp = &re[l][lowSubband];
1927         FIXP_DBL *imTmp = &im[l][lowSubband];
1928         do {
1929           FIXP_DBL tmp1 = *(reTmp++);
1930           FIXP_DBL tmp2 = *(imTmp++);
1931           maxVal |=
1932               (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
1933           maxVal |=
1934               (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
1935         } while (--k != 0);
1936       }
1937     } else {
1938       for (int l = start_pos; l < next_pos; l++) {
1939         maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
1940       }
1941     }
1942   }
1943 
1944   if (maxVal > (FIXP_DBL)0) {
1945     /* For negative input values, maxVal is too small by 1. Add 1 only when
1946      * necessary: if maxVal is a power of 2 */
1947     FIXP_DBL lowerPow2 =
1948         (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
1949     if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
1950   }
1951 
1952   return (maxVal);
1953 }
1954 
1955 /* #define SHIFT_BEFORE_SQUARE (3) */ /* (7/2) */
1956 /* Avoid assertion failures triggerd by overflows which occured in robustness
1957    tests. Setting the SHIFT_BEFORE_SQUARE to 4 has negligible effect on (USAC)
1958    conformance results. */
1959 #define SHIFT_BEFORE_SQUARE (4) /* ((8 - 0) / 2) */
1960 
1961 /*!<
1962   If the accumulator does not provide enough overflow bits or
1963   does not provide a high dynamic range, the below energy calculation
1964   requires an additional shift operation for each sample.
1965   On the other hand, doing the shift allows using a single-precision
1966   multiplication for the square (at least 16bit x 16bit).
1967   For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1968   is required for the energy accumulation.
1969   Theoretically, the sample-squares can sum up to a value of 76,
1970   requiring 7 overflow bits. However since such situations are *very*
1971   rare, accu can be limited to 64.
1972   In case native saturated arithmetic is not available, overflows
1973   can be prevented by replacing the above #define by
1974     #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1975   which will result in slightly reduced accuracy.
1976 */
1977 
1978 /*!
1979   \brief  Estimates the mean energy of each filter-bank channel for the
1980           duration of the current envelope
1981 
1982   This function is used when interpolFreq is true.
1983 */
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)1984 static void calcNrgPerSubband(
1985     FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
1986     FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
1987     int lowSubband,              /*!< Begin of the SBR frequency range */
1988     int highSubband,             /*!< High end of the SBR frequency range */
1989     int start_pos,               /*!< First QMF-slot of current envelope */
1990     int next_pos,                /*!< Last QMF-slot of current envelope + 1 */
1991     SCHAR frameExp,              /*!< Common exponent for all input samples */
1992     FIXP_DBL *nrgEst,            /*!< resulting Energy (0..1) */
1993     SCHAR *nrgEst_e)             /*!< Exponent of resulting Energy */
1994 {
1995   FIXP_SGL invWidth;
1996   SCHAR preShift;
1997   SCHAR shift;
1998   FIXP_DBL sum;
1999   int k;
2000 
2001   /* Divide by width of envelope later: */
2002   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2003   /* The common exponent needs to be doubled because all mantissas are squared:
2004    */
2005   frameExp = frameExp << 1;
2006 
2007   for (k = lowSubband; k < highSubband; k++) {
2008     FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2009     FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2010     FIXP_DBL maxVal;
2011 
2012     if (analysBufferImag != NULL) {
2013       int l;
2014       maxVal = FL2FX_DBL(0.0f);
2015       for (l = start_pos; l < next_pos; l++) {
2016         bufferImag[l] = analysBufferImag[l][k];
2017         maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
2018                              ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
2019         bufferReal[l] = analysBufferReal[l][k];
2020         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2021                              ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2022       }
2023     } else {
2024       int l;
2025       maxVal = FL2FX_DBL(0.0f);
2026       for (l = start_pos; l < next_pos; l++) {
2027         bufferReal[l] = analysBufferReal[l][k];
2028         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2029                              ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2030       }
2031     }
2032 
2033     if (maxVal != FL2FXCONST_DBL(0.f)) {
2034       /* If the accu does not provide enough overflow bits, we cannot
2035          shift the samples up to the limit.
2036          Instead, keep up to 3 free bits in each sample, i.e. up to
2037          6 bits after calculation of square.
2038          Please note the comment on saturated arithmetic above!
2039       */
2040       FIXP_DBL accu;
2041       preShift = CntLeadingZeros(maxVal) - 1;
2042       preShift -= SHIFT_BEFORE_SQUARE;
2043 
2044       /* Limit preShift to a maximum value to prevent accumulator overflow in
2045          exceptional situations where the signal in the analysis-buffer is very
2046          small (small maxVal).
2047       */
2048       preShift = fMin(preShift, (SCHAR)25);
2049 
2050       accu = FL2FXCONST_DBL(0.0f);
2051       if (preShift >= 0) {
2052         int l;
2053         if (analysBufferImag != NULL) {
2054           for (l = start_pos; l < next_pos; l++) {
2055             FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
2056             FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
2057             accu = fPow2AddDiv2(accu, temp1);
2058             accu = fPow2AddDiv2(accu, temp2);
2059           }
2060         } else {
2061           for (l = start_pos; l < next_pos; l++) {
2062             FIXP_DBL temp = bufferReal[l] << (int)preShift;
2063             accu = fPow2AddDiv2(accu, temp);
2064           }
2065         }
2066       } else { /* if negative shift value */
2067         int l;
2068         int negpreShift = -preShift;
2069         if (analysBufferImag != NULL) {
2070           for (l = start_pos; l < next_pos; l++) {
2071             FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
2072             FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
2073             accu = fPow2AddDiv2(accu, temp1);
2074             accu = fPow2AddDiv2(accu, temp2);
2075           }
2076         } else {
2077           for (l = start_pos; l < next_pos; l++) {
2078             FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
2079             accu = fPow2AddDiv2(accu, temp);
2080           }
2081         }
2082       }
2083       accu <<= 1;
2084 
2085       /* Convert double precision to Mantissa/Exponent: */
2086       shift = fNorm(accu);
2087       sum = accu << (int)shift;
2088 
2089       /* Divide by width of envelope and apply frame scale: */
2090       *nrgEst++ = fMult(sum, invWidth);
2091       shift += 2 * preShift;
2092       if (analysBufferImag != NULL)
2093         *nrgEst_e++ = frameExp - shift;
2094       else
2095         *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
2096     }                                       /* maxVal!=0 */
2097     else {
2098       /* Prevent a zero-mantissa-number from being misinterpreted
2099          due to its exponent. */
2100       *nrgEst++ = FL2FXCONST_DBL(0.0f);
2101       *nrgEst_e++ = 0;
2102     }
2103   }
2104 }
2105 
2106 /*!
2107   \brief   Estimates the mean energy of each Scale factor band for the
2108            duration of the current envelope.
2109 
2110   This function is used when interpolFreq is false.
2111 */
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)2112 static void calcNrgPerSfb(
2113     FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
2114     FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
2115     int nSfb,                    /*!< Number of scale factor bands */
2116     UCHAR *freqBandTable,        /*!< First Subband for each Sfb */
2117     int start_pos,               /*!< First QMF-slot of current envelope */
2118     int next_pos,                /*!< Last QMF-slot of current envelope + 1 */
2119     SCHAR input_e,               /*!< Common exponent for all input samples */
2120     FIXP_DBL *nrgEst,            /*!< resulting Energy (0..1) */
2121     SCHAR *nrgEst_e)             /*!< Exponent of resulting Energy */
2122 {
2123   FIXP_SGL invWidth;
2124   FIXP_DBL temp;
2125   SCHAR preShift;
2126   SCHAR shift, sum_e;
2127   FIXP_DBL sum;
2128 
2129   int j, k, l, li, ui;
2130   FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
2131                              but overflow bits are required for accumulation */
2132 
2133   /* Divide by width of envelope later: */
2134   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2135   /* The common exponent needs to be doubled because all mantissas are squared:
2136    */
2137   input_e = input_e << 1;
2138 
2139   for (j = 0; j < nSfb; j++) {
2140     li = freqBandTable[j];
2141     ui = freqBandTable[j + 1];
2142 
2143     FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
2144                                        ui, start_pos, next_pos);
2145 
2146     if (maxVal != FL2FXCONST_DBL(0.f)) {
2147       preShift = CntLeadingZeros(maxVal) - 1;
2148 
2149       /* If the accu does not provide enough overflow bits, we cannot
2150          shift the samples up to the limit.
2151          Instead, keep up to 3 free bits in each sample, i.e. up to
2152          6 bits after calculation of square.
2153          Please note the comment on saturated arithmetic above!
2154       */
2155       preShift -= SHIFT_BEFORE_SQUARE;
2156 
2157       sumAll = FL2FXCONST_DBL(0.0f);
2158 
2159       for (k = li; k < ui; k++) {
2160         sumLine = FL2FXCONST_DBL(0.0f);
2161 
2162         if (analysBufferImag != NULL) {
2163           if (preShift >= 0) {
2164             for (l = start_pos; l < next_pos; l++) {
2165               temp = analysBufferReal[l][k] << (int)preShift;
2166               sumLine += fPow2Div2(temp);
2167               temp = analysBufferImag[l][k] << (int)preShift;
2168               sumLine += fPow2Div2(temp);
2169             }
2170           } else {
2171             for (l = start_pos; l < next_pos; l++) {
2172               temp = analysBufferReal[l][k] >> -(int)preShift;
2173               sumLine += fPow2Div2(temp);
2174               temp = analysBufferImag[l][k] >> -(int)preShift;
2175               sumLine += fPow2Div2(temp);
2176             }
2177           }
2178         } else {
2179           if (preShift >= 0) {
2180             for (l = start_pos; l < next_pos; l++) {
2181               temp = analysBufferReal[l][k] << (int)preShift;
2182               sumLine += fPow2Div2(temp);
2183             }
2184           } else {
2185             for (l = start_pos; l < next_pos; l++) {
2186               temp = analysBufferReal[l][k] >> -(int)preShift;
2187               sumLine += fPow2Div2(temp);
2188             }
2189           }
2190         }
2191 
2192         /* The number of QMF-channels per SBR bands may be up to 15.
2193            Shift right to avoid overflows in sum over all channels. */
2194         sumLine = sumLine >> (4 - 1);
2195         sumAll += sumLine;
2196       }
2197 
2198       /* Convert double precision to Mantissa/Exponent: */
2199       shift = fNorm(sumAll);
2200       sum = sumAll << (int)shift;
2201 
2202       /* Divide by width of envelope: */
2203       sum = fMult(sum, invWidth);
2204 
2205       /* Divide by width of Sfb: */
2206       sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
2207 
2208       /* Set all Subband energies in the Sfb to the average energy: */
2209       if (analysBufferImag != NULL)
2210         sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
2211       else
2212         sum_e = input_e + 4 + 1 -
2213                 shift; /* -4 to compensate right-shift; +1 due to missing
2214                           imag. part */
2215 
2216       sum_e -= 2 * preShift;
2217     } /* maxVal!=0 */
2218     else {
2219       /* Prevent a zero-mantissa-number from being misinterpreted
2220          due to its exponent. */
2221       sum = FL2FXCONST_DBL(0.0f);
2222       sum_e = 0;
2223     }
2224 
2225     for (k = li; k < ui; k++) {
2226       *nrgEst++ = sum;
2227       *nrgEst_e++ = sum_e;
2228     }
2229   }
2230 }
2231 
2232 /*!
2233   \brief  Calculate gain, noise, and additional sine level for one subband.
2234 
2235   The resulting energy gain is given by mantissa and exponent.
2236 */
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)2237 static void calcSubbandGain(
2238     FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
2239     SCHAR
2240         nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
2241     ENV_CALC_NRGS *nrgs, int i, FIXP_DBL tmpNoise, /*!< Relative noise level */
2242     SCHAR tmpNoise_e,      /*!< Relative noise level (exponent) */
2243     UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
2244     UCHAR sineMapped,      /*!< Indicates if sine must be added */
2245     int noNoiseFlag)       /*!< Flag to suppress noise addition */
2246 {
2247   FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
2248   SCHAR nrgEst_e =
2249       nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
2250   FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
2251   SCHAR *ptrNrgGain_e =
2252       &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
2253   FIXP_DBL *ptrNoiseLevel =
2254       &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
2255   SCHAR *ptrNoiseLevel_e =
2256       &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
2257   FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
2258   SCHAR *ptrNrgSine_e =
2259       &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
2260 
2261   FIXP_DBL a, b, c;
2262   SCHAR a_e, b_e, c_e;
2263 
2264   /*
2265      This addition of 1 prevents divisions by zero in the reference code.
2266      For very small energies in nrgEst, it prevents the gains from becoming
2267      very high which could cause some trouble due to the smoothing.
2268   */
2269   b_e = (int)(nrgEst_e - 1);
2270   if (b_e >= 0) {
2271     nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2272              (nrgEst >> 1);
2273     nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
2274 
2275   } else {
2276     nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2277              (FL2FXCONST_DBL(0.5f) >> 1);
2278     nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
2279   }
2280 
2281   /*  A = NrgRef * TmpNoise */
2282   a = fMult(nrgRef, tmpNoise);
2283   a_e = nrgRef_e + tmpNoise_e;
2284 
2285   /*  B = 1 + TmpNoise */
2286   b_e = (int)(tmpNoise_e - 1);
2287   if (b_e >= 0) {
2288     b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2289         (tmpNoise >> 1);
2290     b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
2291   } else {
2292     b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2293         (FL2FXCONST_DBL(0.5f) >> 1);
2294     b_e = 2; /* shift by 1 bit to avoid overflow */
2295   }
2296 
2297   /*  noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
2298   FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
2299 
2300   if (sinePresentFlag) {
2301     /*  C = (1 + TmpNoise) * NrgEst */
2302     c = fMult(b, nrgEst);
2303     c_e = b_e + nrgEst_e;
2304 
2305     /*  gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
2306     FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
2307 
2308     if (sineMapped) {
2309       /*  sineLevel = nrgRef/ (1 + TmpNoise) */
2310       FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
2311     }
2312   } else {
2313     if (noNoiseFlag) {
2314       /*  B = NrgEst */
2315       b = nrgEst;
2316       b_e = nrgEst_e;
2317     } else {
2318       /*  B = NrgEst * (1 + TmpNoise) */
2319       b = fMult(b, nrgEst);
2320       b_e = b_e + nrgEst_e;
2321     }
2322 
2323     /*  gain = nrgRef / B */
2324     INT result_exp = 0;
2325     *ptrNrgGain = fDivNorm(nrgRef, b, &result_exp);
2326     *ptrNrgGain_e = (SCHAR)result_exp + (nrgRef_e - b_e);
2327 
2328     /* There could be a one bit diffs. This is important to compensate,
2329        because later in the code values are compared by exponent only. */
2330     int headroom = CountLeadingBits(*ptrNrgGain);
2331     *ptrNrgGain <<= headroom;
2332     *ptrNrgGain_e -= headroom;
2333   }
2334 }
2335 
2336 /*!
2337   \brief  Calculate "average gain" for the specified subband range.
2338 
2339   This is rather a gain of the average magnitude than the average
2340   of gains!
2341   The result is used as a relative limit for all gains within the
2342   current "limiter band" (a certain frequency range).
2343 */
calcAvgGain(ENV_CALC_NRGS * nrgs,int lowSubband,int highSubband,FIXP_DBL * ptrSumRef,SCHAR * ptrSumRef_e,FIXP_DBL * ptrAvgGain,SCHAR * ptrAvgGain_e)2344 static void calcAvgGain(
2345     ENV_CALC_NRGS *nrgs, int lowSubband, /*!< Begin of the limiter band */
2346     int highSubband,                     /*!< High end of the limiter band */
2347     FIXP_DBL *ptrSumRef, SCHAR *ptrSumRef_e,
2348     FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
2349     SCHAR *ptrAvgGain_e)  /*!< Resulting overall gain (exponent) */
2350 {
2351   FIXP_DBL *nrgRef =
2352       nrgs->nrgRef; /*!< Reference Energy according to envelope data */
2353   SCHAR *nrgRef_e =
2354       nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
2355                          (exponent) */
2356   FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
2357   SCHAR *nrgEst_e =
2358       nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
2359 
2360   FIXP_DBL sumRef = 1;
2361   FIXP_DBL sumEst = 1;
2362   SCHAR sumRef_e = -FRACT_BITS;
2363   SCHAR sumEst_e = -FRACT_BITS;
2364   int k;
2365 
2366   for (k = lowSubband; k < highSubband; k++) {
2367     /* Add nrgRef[k] to sumRef: */
2368     FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
2369                     &sumRef_e);
2370 
2371     /* Add nrgEst[k] to sumEst: */
2372     FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
2373                     &sumEst_e);
2374   }
2375 
2376   FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
2377                      ptrAvgGain_e);
2378 
2379   *ptrSumRef = sumRef;
2380   *ptrSumRef_e = sumRef_e;
2381 }
2382 
adjustTimeSlot_EldGrid(FIXP_DBL * RESTRICT ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex,int scale_diff_low)2383 static void adjustTimeSlot_EldGrid(
2384     FIXP_DBL *RESTRICT
2385         ptrReal, /*!< Subband samples to be adjusted, real part */
2386     ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2387     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2388     int noSubbands, /*!< Number of QMF subbands */
2389     int scale_change,   /*!< Number of bits to shift adjusted samples */
2390     int noNoiseFlag,    /*!< Flag to suppress noise addition */
2391     int *ptrPhaseIndex, /*!< Start index to random number array */
2392     int scale_diff_low) /*!<  */
2393 
2394 {
2395   int k;
2396   FIXP_DBL signalReal, sbNoise;
2397   int tone_count = 0;
2398 
2399   FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2400   FIXP_DBL *RESTRICT pNoiseLevel =
2401       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2402   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2403 
2404   int phaseIndex = *ptrPhaseIndex;
2405   UCHAR harmIndex = *ptrHarmIndex;
2406 
2407   static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2408 
2409   static const FIXP_DBL harmonicPhaseX[4][2] = {
2410       {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
2411        FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
2412       {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
2413        FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
2414       {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
2415        FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
2416       {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
2417        FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
2418 
2419   const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
2420   const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
2421 
2422   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2423   const FIXP_DBL min_val = -max_val;
2424 
2425   *(ptrReal - 1) = fAddSaturate(
2426       *(ptrReal - 1),
2427       SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
2428                      scale_diff_low, DFRACT_BITS));
2429   FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
2430 
2431   int idx_k = lowSubband & 1;
2432 
2433   for (k = 0; k < noSubbands; k++) {
2434     FIXP_DBL sineLevel_curr = *pSineLevel++;
2435     phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2436 
2437     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2438                  << scale_change;
2439     sbNoise = *pNoiseLevel++;
2440     if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2441       signalReal +=
2442           fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2443     }
2444     signalReal += sineLevel_curr * p_harmonicPhase[0];
2445     signalReal =
2446         fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2447     pSineLevel_prev = sineLevel_curr;
2448     idx_k = !idx_k;
2449     if (k < noSubbands - 1) {
2450       signalReal =
2451           fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
2452     } else /* (k == noSubbands - 1)  */
2453     {
2454       if (k + lowSubband + 1 < 63) {
2455         *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2456       }
2457     }
2458     *ptrReal++ = signalReal;
2459 
2460     if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
2461       if (++tone_count == 16) {
2462         k++;
2463         break;
2464       }
2465     }
2466   }
2467   /* Run again, if previous loop got breaked with tone_count = 16 */
2468   for (; k < noSubbands; k++) {
2469     FIXP_DBL sineLevel_curr = *pSineLevel++;
2470     phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2471 
2472     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2473                  << scale_change;
2474     sbNoise = *pNoiseLevel++;
2475     if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2476       signalReal +=
2477           fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2478     }
2479     signalReal += sineLevel_curr * p_harmonicPhase[0];
2480     *ptrReal++ = signalReal;
2481   }
2482 
2483   *ptrHarmIndex = (harmIndex + 1) & 3;
2484   *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
2485 }
2486 
2487 /*!
2488   \brief   Amplify one timeslot of the signal with the calculated gains
2489            and add the noisefloor.
2490 */
2491 
adjustTimeSlotLC(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex)2492 static void adjustTimeSlotLC(
2493     FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
2494     ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2495     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2496     int noSubbands, /*!< Number of QMF subbands */
2497     int scale_change,   /*!< Number of bits to shift adjusted samples */
2498     int noNoiseFlag,    /*!< Flag to suppress noise addition */
2499     int *ptrPhaseIndex) /*!< Start index to random number array */
2500 {
2501   FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2502   FIXP_DBL *pNoiseLevel =
2503       nrgs->noiseLevel;                 /*!< Noise levels of current envelope */
2504   FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2505 
2506   int k;
2507   int index = *ptrPhaseIndex;
2508   UCHAR harmIndex = *ptrHarmIndex;
2509   UCHAR freqInvFlag = (lowSubband & 1);
2510   FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
2511   int tone_count = 0;
2512   int sineSign = 1;
2513   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2514   const FIXP_DBL min_val = -max_val;
2515 
2516 #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
2517 #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
2518 
2519   /*
2520     First pass for k=0 pulled out of the loop:
2521   */
2522 
2523   index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2524 
2525   /*
2526     The next multiplication constitutes the actual envelope adjustment
2527     of the signal and should be carried out with full accuracy
2528     (supplying #FRACT_BITS valid bits).
2529   */
2530   signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2531                << scale_change;
2532   sineLevel = *pSineLevel++;
2533   sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
2534 
2535   if (sineLevel != FL2FXCONST_DBL(0.0f))
2536     tone_count++;
2537   else if (!noNoiseFlag)
2538     /* Add noisefloor to the amplified signal */
2539     signalReal +=
2540         fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2541 
2542   {
2543     if (!(harmIndex & 0x1)) {
2544       /* harmIndex 0,2 */
2545       signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel;
2546       *ptrReal++ = signalReal;
2547     } else {
2548       /* harmIndex 1,3 in combination with freqInvFlag */
2549       int shift = (int)(scale_change + 1);
2550       shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift)
2551                            : fixMax(-(DFRACT_BITS - 1), shift);
2552 
2553       FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
2554                                    : (fMultDiv2(C1, sineLevel) << (-shift));
2555       FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
2556 
2557       /* save switch and compare operations and reduce to XOR statement */
2558       if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
2559         *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
2560         signalReal -= tmp2;
2561       } else {
2562         *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
2563         signalReal += tmp2;
2564       }
2565       *ptrReal++ = signalReal;
2566       freqInvFlag = !freqInvFlag;
2567     }
2568   }
2569 
2570   pNoiseLevel++;
2571 
2572   if (noSubbands > 2) {
2573     if (!(harmIndex & 0x1)) {
2574       /* harmIndex 0,2 */
2575       if (!harmIndex) {
2576         sineSign = 0;
2577       }
2578 
2579       for (k = noSubbands - 2; k != 0; k--) {
2580         FIXP_DBL sinelevel = *pSineLevel++;
2581         index++;
2582         if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
2583              FL2FXCONST_DBL(0.0f)) &&
2584             !noNoiseFlag) {
2585           /* Add noisefloor to the amplified signal */
2586           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2587           signalReal +=
2588               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2589         }
2590 
2591         /* The next multiplication constitutes the actual envelope adjustment of
2592          * the signal. */
2593         signalReal +=
2594             fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2595             << scale_change;
2596 
2597         pNoiseLevel++;
2598         *ptrReal++ = signalReal;
2599       } /* for ... */
2600     } else {
2601       /* harmIndex 1,3 in combination with freqInvFlag */
2602       if (harmIndex == 1) freqInvFlag = !freqInvFlag;
2603 
2604       for (k = noSubbands - 2; k != 0; k--) {
2605         index++;
2606         /* The next multiplication constitutes the actual envelope adjustment of
2607          * the signal. */
2608         signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2609                      << scale_change;
2610 
2611         if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
2612           tone_count++;
2613         else if (!noNoiseFlag) {
2614           /* Add noisefloor to the amplified signal */
2615           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2616           signalReal +=
2617               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2618         }
2619 
2620         pNoiseLevel++;
2621 
2622         if (tone_count <= 16) {
2623           FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
2624           signalReal += (freqInvFlag) ? (-addSine) : (addSine);
2625         }
2626 
2627         *ptrReal++ = signalReal;
2628         freqInvFlag = !freqInvFlag;
2629       } /* for ... */
2630     }
2631   }
2632 
2633   if (noSubbands > -1) {
2634     index++;
2635     /* The next multiplication constitutes the actual envelope adjustment of the
2636      * signal. */
2637     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
2638                  << scale_change;
2639     sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
2640     sineLevel = pSineLevel[0];
2641 
2642     if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
2643       tone_count++;
2644     else if (!noNoiseFlag) {
2645       /* Add noisefloor to the amplified signal */
2646       index &= (SBR_NF_NO_RANDOM_VAL - 1);
2647       signalReal = signalReal + fMult(FDK_sbrDecoder_sbr_randomPhase[index][0],
2648                                       pNoiseLevel[0]);
2649     }
2650 
2651     if (!(harmIndex & 0x1)) {
2652       /* harmIndex 0,2 */
2653       *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
2654     } else {
2655       /* harmIndex 1,3 in combination with freqInvFlag */
2656       if (tone_count <= 16) {
2657         if (freqInvFlag) {
2658           *ptrReal++ = signalReal - sineLevelPrev;
2659           if (noSubbands + lowSubband < 63)
2660             *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
2661         } else {
2662           *ptrReal++ = signalReal + sineLevelPrev;
2663           if (noSubbands + lowSubband < 63)
2664             *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
2665         }
2666       } else
2667         *ptrReal = signalReal;
2668     }
2669   }
2670   *ptrHarmIndex = (harmIndex + 1) & 3;
2671   *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2672 }
2673 
adjustTimeSlotHQ_GainAndNoise(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)2674 static void adjustTimeSlotHQ_GainAndNoise(
2675     FIXP_DBL *RESTRICT
2676         ptrReal, /*!< Subband samples to be adjusted, real part */
2677     FIXP_DBL *RESTRICT
2678         ptrImag, /*!< Subband samples to be adjusted, imag part */
2679     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2680     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2681     int noSubbands, /*!< Number of QMF subbands */
2682     int scale_change,         /*!< Number of bits to shift adjusted samples */
2683     FIXP_SGL smooth_ratio,    /*!< Impact of last envelope */
2684     int noNoiseFlag,          /*!< Start index to random number array */
2685     int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2686 {
2687   FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2688   FIXP_DBL *RESTRICT noiseLevel =
2689       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2690   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2691 
2692   FIXP_DBL *RESTRICT filtBuffer =
2693       h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2694   FIXP_DBL *RESTRICT filtBufferNoise =
2695       h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2696   int *RESTRICT ptrPhaseIndex =
2697       &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2698 
2699   int k;
2700   FIXP_DBL signalReal, signalImag;
2701   FIXP_DBL noiseReal, noiseImag;
2702   FIXP_DBL smoothedGain, smoothedNoise;
2703   FIXP_SGL direct_ratio =
2704       /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2705   int index = *ptrPhaseIndex;
2706   int shift;
2707   FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2708   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2709   const FIXP_DBL min_val = -max_val;
2710 
2711   *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2712 
2713   filtBufferNoiseShift +=
2714       1; /* due to later use of fMultDiv2 instead of fMult */
2715   if (filtBufferNoiseShift < 0) {
2716     shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2717   } else {
2718     shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2719     max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2720     min_val_noise = -max_val_noise;
2721   }
2722 
2723   if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2724     for (k = 0; k < noSubbands; k++) {
2725       /*
2726         Smoothing: The old envelope has been bufferd and a certain ratio
2727         of the old gains and noise levels is used.
2728       */
2729       smoothedGain =
2730           fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2731 
2732       if (filtBufferNoiseShift < 0) {
2733         smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2734                         fMult(direct_ratio, noiseLevel[k]);
2735       } else {
2736         smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2737         smoothedNoise =
2738             (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2739             fMult(direct_ratio, noiseLevel[k]);
2740       }
2741 
2742       smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2743                            (FIXP_DBL)(MINVAL_DBL / 2));
2744 
2745       /*
2746         The next 2 multiplications constitute the actual envelope adjustment
2747         of the signal and should be carried out with full accuracy
2748         (supplying #DFRACT_BITS valid bits).
2749       */
2750       signalReal =
2751           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2752           << scale_change;
2753       signalImag =
2754           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2755           << scale_change;
2756 
2757       index++;
2758 
2759       if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
2760         /* Just the amplified signal is saved */
2761         *ptrReal++ = signalReal;
2762         *ptrImag++ = signalImag;
2763       } else {
2764         /* Add noisefloor to the amplified signal */
2765         index &= (SBR_NF_NO_RANDOM_VAL - 1);
2766         noiseReal =
2767             fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2768         noiseImag =
2769             fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2770         *ptrReal++ = (signalReal + noiseReal);
2771         *ptrImag++ = (signalImag + noiseImag);
2772       }
2773     }
2774   } else {
2775     for (k = 0; k < noSubbands; k++) {
2776       smoothedGain = gain[k];
2777       signalReal =
2778           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2779           << scale_change;
2780       signalImag =
2781           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2782           << scale_change;
2783 
2784       index++;
2785 
2786       if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
2787         /* Add noisefloor to the amplified signal */
2788         smoothedNoise = noiseLevel[k];
2789         index &= (SBR_NF_NO_RANDOM_VAL - 1);
2790         noiseReal =
2791             fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2792         noiseImag =
2793             fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2794 
2795         signalReal += noiseReal;
2796         signalImag += noiseImag;
2797       }
2798       *ptrReal++ = signalReal;
2799       *ptrImag++ = signalImag;
2800     }
2801   }
2802 }
2803 
adjustTimeSlotHQ_AddHarmonics(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)2804 static void adjustTimeSlotHQ_AddHarmonics(
2805     FIXP_DBL *RESTRICT
2806         ptrReal, /*!< Subband samples to be adjusted, real part */
2807     FIXP_DBL *RESTRICT
2808         ptrImag, /*!< Subband samples to be adjusted, imag part */
2809     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2810     int lowSubband,  /*!< Lowest QMF-channel in the currently used SBR range. */
2811     int noSubbands,  /*!< Number of QMF subbands */
2812     int scale_change /*!< Scale mismatch between QMF input and sineLevel
2813                         exponent. */
2814 ) {
2815   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2816   UCHAR *RESTRICT ptrHarmIndex =
2817       &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2818 
2819   int k;
2820   FIXP_DBL signalReal, signalImag;
2821   UCHAR harmIndex = *ptrHarmIndex;
2822   int freqInvFlag = (lowSubband & 1);
2823   FIXP_DBL sineLevel;
2824 
2825   *ptrHarmIndex = (harmIndex + 1) & 3;
2826 
2827   for (k = 0; k < noSubbands; k++) {
2828     sineLevel = pSineLevel[k];
2829     freqInvFlag ^= 1;
2830     if (sineLevel != FL2FXCONST_DBL(0.f)) {
2831       signalReal = ptrReal[k];
2832       signalImag = ptrImag[k];
2833       sineLevel = scaleValue(sineLevel, scale_change);
2834       if (harmIndex & 2) {
2835         /* case 2,3 */
2836         sineLevel = -sineLevel;
2837       }
2838       if (!(harmIndex & 1)) {
2839         /* case 0,2: */
2840         ptrReal[k] = signalReal + sineLevel;
2841       } else {
2842         /* case 1,3 */
2843         if (!freqInvFlag) sineLevel = -sineLevel;
2844         ptrImag[k] = signalImag + sineLevel;
2845       }
2846     }
2847   }
2848 }
2849 
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)2850 static void adjustTimeSlotHQ(
2851     FIXP_DBL *RESTRICT
2852         ptrReal, /*!< Subband samples to be adjusted, real part */
2853     FIXP_DBL *RESTRICT
2854         ptrImag, /*!< Subband samples to be adjusted, imag part */
2855     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2856     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2857     int noSubbands, /*!< Number of QMF subbands */
2858     int scale_change,         /*!< Number of bits to shift adjusted samples */
2859     FIXP_SGL smooth_ratio,    /*!< Impact of last envelope */
2860     int noNoiseFlag,          /*!< Start index to random number array */
2861     int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2862 {
2863   FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2864   FIXP_DBL *RESTRICT noiseLevel =
2865       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2866   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2867 
2868   FIXP_DBL *RESTRICT filtBuffer =
2869       h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2870   FIXP_DBL *RESTRICT filtBufferNoise =
2871       h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2872   UCHAR *RESTRICT ptrHarmIndex =
2873       &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2874   int *RESTRICT ptrPhaseIndex =
2875       &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2876 
2877   int k;
2878   FIXP_DBL signalReal, signalImag;
2879   FIXP_DBL noiseReal, noiseImag;
2880   FIXP_DBL smoothedGain, smoothedNoise;
2881   FIXP_SGL direct_ratio =
2882       /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2883   int index = *ptrPhaseIndex;
2884   UCHAR harmIndex = *ptrHarmIndex;
2885   int freqInvFlag = (lowSubband & 1);
2886   FIXP_DBL sineLevel;
2887   int shift;
2888   FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2889   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2890   const FIXP_DBL min_val = -max_val;
2891 
2892   *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2893   *ptrHarmIndex = (harmIndex + 1) & 3;
2894 
2895   /*
2896     Possible optimization:
2897     smooth_ratio and harmIndex stay constant during the loop.
2898     It might be faster to include a separate loop in each path.
2899 
2900     the check for smooth_ratio is now outside the loop and the workload
2901     of the whole function decreased by about 20 %
2902   */
2903 
2904   filtBufferNoiseShift +=
2905       1; /* due to later use of fMultDiv2 instead of fMult */
2906   if (filtBufferNoiseShift < 0) {
2907     shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2908   } else {
2909     shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2910     max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2911     min_val_noise = -max_val_noise;
2912   }
2913 
2914   if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2915     for (k = 0; k < noSubbands; k++) {
2916       /*
2917         Smoothing: The old envelope has been bufferd and a certain ratio
2918         of the old gains and noise levels is used.
2919       */
2920 
2921       smoothedGain =
2922           fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2923 
2924       if (filtBufferNoiseShift < 0) {
2925         smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2926                         fMult(direct_ratio, noiseLevel[k]);
2927       } else {
2928         smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2929         smoothedNoise =
2930             (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2931             fMult(direct_ratio, noiseLevel[k]);
2932       }
2933 
2934       smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2935                            (FIXP_DBL)(MINVAL_DBL / 2));
2936 
2937       /*
2938         The next 2 multiplications constitute the actual envelope adjustment
2939         of the signal and should be carried out with full accuracy
2940         (supplying #DFRACT_BITS valid bits).
2941       */
2942       signalReal =
2943           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2944           << scale_change;
2945       signalImag =
2946           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2947           << scale_change;
2948 
2949       index++;
2950 
2951       if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2952         sineLevel = pSineLevel[k];
2953 
2954         switch (harmIndex) {
2955           case 0:
2956             *ptrReal++ = (signalReal + sineLevel);
2957             *ptrImag++ = (signalImag);
2958             break;
2959           case 2:
2960             *ptrReal++ = (signalReal - sineLevel);
2961             *ptrImag++ = (signalImag);
2962             break;
2963           case 1:
2964             *ptrReal++ = (signalReal);
2965             if (freqInvFlag)
2966               *ptrImag++ = (signalImag - sineLevel);
2967             else
2968               *ptrImag++ = (signalImag + sineLevel);
2969             break;
2970           case 3:
2971             *ptrReal++ = signalReal;
2972             if (freqInvFlag)
2973               *ptrImag++ = (signalImag + sineLevel);
2974             else
2975               *ptrImag++ = (signalImag - sineLevel);
2976             break;
2977         }
2978       } else {
2979         if (noNoiseFlag) {
2980           /* Just the amplified signal is saved */
2981           *ptrReal++ = (signalReal);
2982           *ptrImag++ = (signalImag);
2983         } else {
2984           /* Add noisefloor to the amplified signal */
2985           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2986           noiseReal =
2987               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2988           noiseImag =
2989               fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2990           *ptrReal++ = (signalReal + noiseReal);
2991           *ptrImag++ = (signalImag + noiseImag);
2992         }
2993       }
2994       freqInvFlag ^= 1;
2995     }
2996 
2997   } else {
2998     for (k = 0; k < noSubbands; k++) {
2999       smoothedGain = gain[k];
3000       signalReal =
3001           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
3002           << scale_change;
3003       signalImag =
3004           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
3005           << scale_change;
3006 
3007       index++;
3008 
3009       if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
3010         switch (harmIndex) {
3011           case 0:
3012             signalReal += sineLevel;
3013             break;
3014           case 1:
3015             if (freqInvFlag)
3016               signalImag -= sineLevel;
3017             else
3018               signalImag += sineLevel;
3019             break;
3020           case 2:
3021             signalReal -= sineLevel;
3022             break;
3023           case 3:
3024             if (freqInvFlag)
3025               signalImag += sineLevel;
3026             else
3027               signalImag -= sineLevel;
3028             break;
3029         }
3030       } else {
3031         if (noNoiseFlag == 0) {
3032           /* Add noisefloor to the amplified signal */
3033           smoothedNoise = noiseLevel[k];
3034           index &= (SBR_NF_NO_RANDOM_VAL - 1);
3035           noiseReal =
3036               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
3037           noiseImag =
3038               fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
3039 
3040           signalReal += noiseReal;
3041           signalImag += noiseImag;
3042         }
3043       }
3044       *ptrReal++ = signalReal;
3045       *ptrImag++ = signalImag;
3046 
3047       freqInvFlag ^= 1;
3048     }
3049   }
3050 }
3051 
3052 /*!
3053   \brief   Reset limiter bands.
3054 
3055   Build frequency band table for the gain limiter dependent on
3056   the previously generated transposer patch areas.
3057 
3058   \return  SBRDEC_OK if ok,  SBRDEC_UNSUPPORTED_CONFIG on error
3059 */
3060 SBR_ERROR
ResetLimiterBands(UCHAR * limiterBandTable,UCHAR * noLimiterBands,UCHAR * freqBandTable,int noFreqBands,const PATCH_PARAM * patchParam,int noPatches,int limiterBands,UCHAR sbrPatchingMode,int xOverQmf[MAX_NUM_PATCHES],int b41Sbr)3061 ResetLimiterBands(
3062     UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
3063     UCHAR *noLimiterBands,   /*!< Resulting number of limiter band */
3064     UCHAR *freqBandTable,    /*!< Table with possible band borders */
3065     int noFreqBands,         /*!< Number of bands in freqBandTable */
3066     const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
3067     int noPatches,                 /*!< Number of transposer patches */
3068     int limiterBands, /*!< Selected 'band density' from bitstream */
3069     UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
3070   int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
3071   UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
3072   int patchBorders[MAX_NUM_PATCHES + 1];
3073   int kx, k2;
3074 
3075   int lowSubband = freqBandTable[0];
3076   int highSubband = freqBandTable[noFreqBands];
3077 
3078   /* 1 limiter band. */
3079   if (limiterBands == 0) {
3080     limiterBandTable[0] = 0;
3081     limiterBandTable[1] = highSubband - lowSubband;
3082     nBands = 1;
3083   } else {
3084     if (!sbrPatchingMode && xOverQmf != NULL) {
3085       noPatches = 0;
3086 
3087       if (b41Sbr == 1) {
3088         for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
3089           if (xOverQmf[i] != 0) noPatches++;
3090       } else {
3091         for (i = 1; i < MAX_STRETCH_HBE; i++)
3092           if (xOverQmf[i] != 0) noPatches++;
3093       }
3094       for (i = 0; i < noPatches; i++) {
3095         patchBorders[i] = xOverQmf[i] - lowSubband;
3096       }
3097     } else {
3098       for (i = 0; i < noPatches; i++) {
3099         patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
3100       }
3101     }
3102     patchBorders[i] = highSubband - lowSubband;
3103 
3104     /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
3105     for (k = 0; k <= noFreqBands; k++) {
3106       workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
3107     }
3108     for (k = 1; k < noPatches; k++) {
3109       workLimiterBandTable[noFreqBands + k] = patchBorders[k];
3110     }
3111 
3112     tempNoLim = nBands = noFreqBands + noPatches - 1;
3113     shellsort(workLimiterBandTable, tempNoLim + 1);
3114 
3115     loLimIndex = 0;
3116     hiLimIndex = 1;
3117 
3118     while (hiLimIndex <= tempNoLim) {
3119       FIXP_DBL div_m, oct_m, temp;
3120       INT div_e = 0, oct_e = 0, temp_e = 0;
3121 
3122       k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
3123       kx = workLimiterBandTable[loLimIndex] + lowSubband;
3124 
3125       div_m = fDivNorm(k2, kx, &div_e);
3126 
3127       /* calculate number of octaves */
3128       oct_m = fLog2(div_m, div_e, &oct_e);
3129 
3130       /* multiply with limiterbands per octave    */
3131       /* values 1, 1.2, 2, 3 -> scale factor of 2 */
3132       temp = fMultNorm(
3133           oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands],
3134           &temp_e);
3135 
3136       /* overall scale factor of temp ist addition of scalefactors from log2
3137          calculation, limiter bands scalefactor (2) and limiter bands
3138          multiplication */
3139       temp_e += oct_e + 2;
3140 
3141       /*    div can be a maximum of 64 (k2 = 64 and kx = 1)
3142          -> oct can be a maximum of 6
3143          -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum
3144          factor of 3)
3145          -> we need a scale factor of 5 for comparisson
3146       */
3147       if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) {
3148         if (workLimiterBandTable[hiLimIndex] ==
3149             workLimiterBandTable[loLimIndex]) {
3150           workLimiterBandTable[hiLimIndex] = highSubband;
3151           nBands--;
3152           hiLimIndex++;
3153           continue;
3154         }
3155         isPatchBorder[0] = isPatchBorder[1] = 0;
3156         for (k = 0; k <= noPatches; k++) {
3157           if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
3158             isPatchBorder[1] = 1;
3159             break;
3160           }
3161         }
3162         if (!isPatchBorder[1]) {
3163           workLimiterBandTable[hiLimIndex] = highSubband;
3164           nBands--;
3165           hiLimIndex++;
3166           continue;
3167         }
3168         for (k = 0; k <= noPatches; k++) {
3169           if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
3170             isPatchBorder[0] = 1;
3171             break;
3172           }
3173         }
3174         if (!isPatchBorder[0]) {
3175           workLimiterBandTable[loLimIndex] = highSubband;
3176           nBands--;
3177         }
3178       }
3179       loLimIndex = hiLimIndex;
3180       hiLimIndex++;
3181     }
3182     shellsort(workLimiterBandTable, tempNoLim + 1);
3183 
3184     /* Test if algorithm exceeded maximum allowed limiterbands */
3185     if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
3186       return SBRDEC_UNSUPPORTED_CONFIG;
3187     }
3188 
3189     /* Restrict maximum value of limiter band table */
3190     if (workLimiterBandTable[tempNoLim] > highSubband) {
3191       return SBRDEC_UNSUPPORTED_CONFIG;
3192     }
3193 
3194     /* Copy limiterbands from working buffer into final destination */
3195     for (k = 0; k <= nBands; k++) {
3196       limiterBandTable[k] = workLimiterBandTable[k];
3197     }
3198   }
3199   *noLimiterBands = nBands;
3200 
3201   return SBRDEC_OK;
3202 }
3203