1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2019 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] >>= -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       if (gain_sf[i] < 0) {
687         gain[i] >>= -gain_sf[i];
688         gain_sf[i] = 0;
689       }
690 
691       /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
692       FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
693                      gain_sf[i]; /* to substract this from gain[i] */
694 
695       /* gamma is actually always 1 according to the table, so skip the
696        * fMultDiv2 */
697       FIXP_DBL mult = (gain[i] - one) >> 1;
698       int mult_sf = gain_sf[i] + gamma_sf;
699 
700       one = FL2FXCONST_DBL(0.5f) >> mult_sf;
701       gain[i] = one + mult;
702       gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */
703 
704       /* set gain to at least 0.2f */
705       /* limit and calculate gain[i]^2 too */
706       FIXP_DBL gain_pow2;
707       int gain_pow2_sf;
708 
709       if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
710         gain[i] = FL2FXCONST_DBL(0.8f);
711         gain_sf[i] = -2;
712         gain_pow2 = FL2FXCONST_DBL(0.64f);
713         gain_pow2_sf = -4;
714       } else {
715         /* this upscaling seems quite important */
716         int r = CountLeadingBits(gain[i]);
717         gain[i] <<= r;
718         gain_sf[i] -= r;
719 
720         gain_pow2 = fPow2(gain[i]);
721         gain_pow2_sf = gain_sf[i] << 1;
722       }
723 
724       int room;
725       subsample_power_high[i] =
726           fMultNorm(subsample_power_high[i], gain_pow2, &room);
727       subsample_power_high_sf[i] =
728           subsample_power_high_sf[i] + gain_pow2_sf + room;
729 
730       int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
731       if (new_summand_sf > total_power_high_after_sf) {
732         total_power_high_after >>=
733             fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
734         total_power_high_after_sf = new_summand_sf;
735       } else if (new_summand_sf < total_power_high_after_sf) {
736         subsample_power_high[i] >>=
737             fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
738       }
739       total_power_high_after += subsample_power_high[i] >> preShift2;
740     }
741 
742     total_power_high_after_sf += preShift2;
743 
744     int sf2 = 0;
745     FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
746     int gain_adj_2_sf = 1;
747 
748     if ((total_power_high != (FIXP_DBL)0) &&
749         (total_power_high_after != (FIXP_DBL)0)) {
750       gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
751       gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
752     }
753 
754     FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
755     int gain_adj_sf = gain_adj_2_sf;
756 
757     for (i = 0; i < nbSubsample; ++i) {
758       gain[i] = fMult(gain[i], gain_adj);
759       gain_sf[i] += gain_adj_sf;
760 
761       /* limit gain */
762       if (gain_sf[i] > INTER_TES_SF_CHANGE) {
763         gain[i] = (FIXP_DBL)MAXVAL_DBL;
764         gain_sf[i] = INTER_TES_SF_CHANGE;
765       }
766     }
767 
768     for (i = 0; i < nbSubsample; ++i) {
769       /* equalize gain[]'s scale factors */
770       gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i];
771 
772       for (j = lowSubband; j < highSubband; j++) {
773         qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]);
774         qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]);
775       }
776     }
777   } else { /* gamma_idx == 0 */
778     /* Inter-TES is not active. Still perform the scale change to have a
779      * consistent scaling for all envelopes of this frame. */
780     for (i = 0; i < nbSubsample; ++i) {
781       for (j = lowSubband; j < highSubband; j++) {
782         qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
783         qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
784       }
785     }
786   }
787   C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
788 }
789 
790 /*!
791   \brief  Apply spectral envelope to subband samples
792 
793   This function is called from sbr_dec.cpp in each frame.
794 
795   To enhance accuracy and due to the usage of tables for squareroots and
796   inverse, some calculations are performed with the operands being split
797   into mantissa and exponent. The variable names in the source code carry
798   the suffixes <em>_m</em> and  <em>_e</em> respectively. The control data
799   in #hFrameData containts envelope data which is represented by this format but
800   stored in single words. (See requantizeEnvelopeData() for details). This data
801   is unpacked within calculateSbrEnvelope() to follow the described suffix
802   convention.
803 
804   The actual value (comparable to the corresponding float-variable in the
805   research-implementation) of a mantissa/exponent-pair can be calculated as
806 
807   \f$ value = value\_m * 2^{value\_e} \f$
808 
809   All energies and noise levels decoded from the bitstream suit for an
810   original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$.
811   Therefore, the scale factor <em>hb_scale</em> passed into this function will
812   be converted to an 'input exponent' (#input_e), which fits the internal
813   representation.
814 
815   Before the actual processing, an exponent #adj_e for resulting adjusted
816   samples is derived from the maximum reference energy.
817 
818   Then, for each envelope, the following steps are performed:
819 
820   \li Calculate energy in the signal to be adjusted. Depending on the the value
821   of #interpolFreq (interpolation mode), this is either done seperately for each
822   QMF-subband or for each SBR-band. The resulting energies are stored in
823   #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgEst_e[#MAX_FREQ_COEFFS]
824   (exponents). \li Calculate gain and noise level for each subband:<br> \f$ gain
825   = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise =
826   \sqrt{ nrgRef \cdot noiseRatio } \f$<br> where <em>noiseRatio</em> and
827   <em>nrgRef</em> are extracted from the bitstream and <em>nrgEst</em> is the
828   subband energy before adjustment. The resulting gains are stored in
829   #nrgGain_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS]
830   (exponents), the noise levels are stored in #noiseLevel_m[#MAX_FREQ_COEFFS]
831   and #noiseLevel_e[#MAX_FREQ_COEFFS] (exponents). The sine levels are stored in
832   #nrgSine_m[#MAX_FREQ_COEFFS] and #nrgSine_e[#MAX_FREQ_COEFFS]. \li Noise
833   limiting: The gain for each subband is limited both absolutely and relatively
834   compared to the total gain over all subbands. \li Boost gain: Calculate and
835   apply boost factor for each limiter band in order to compensate for the energy
836   loss imposed by the limiting. \li Apply gains and add noise: The gains and
837   noise levels are applied to all timeslots of the current envelope. A short
838   FIR-filter (length 4 QMF-timeslots) can be used to smooth the sudden change at
839   the envelope borders. Each complex subband sample of the current timeslot is
840   multiplied by the smoothed gain, then random noise with the calculated level
841   is added.
842 
843   \note
844   To reduce the stack size, some of the local arrays could be located within
845   the time output buffer. Of the 512 samples temporarily available there,
846   about half the size is already used by #SBR_FRAME_DATA. A pointer to the
847   remaining free memory could be supplied by an additional argument to
848   calculateSbrEnvelope() in sbr_dec:
849 
850   \par
851   \code
852     calculateSbrEnvelope (&hSbrDec->sbrScaleFactor,
853                           &hSbrDec->SbrCalculateEnvelope,
854                           hHeaderData,
855                           hFrameData,
856                           QmfBufferReal,
857                           QmfBufferImag,
858                           timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) +
859   1); \endcode
860 
861   \par
862   Within calculateSbrEnvelope(), some pointers could be defined instead of the
863   arrays #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m:
864 
865   \par
866   \code
867     fract*        nrgRef_m = timeOutPtr;
868     SCHAR*        nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS;
869     fract*        nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS;
870     SCHAR*        nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS;
871     fract*        noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS;
872   \endcode
873 
874   <br>
875 */
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)876 void calculateSbrEnvelope(
877     QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */
878     HANDLE_SBR_CALCULATE_ENVELOPE
879         h_sbr_cal_env, /*!< Handle to struct filled by the create-function */
880     HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */
881     HANDLE_SBR_FRAME_DATA hFrameData,   /*!< Control data of current frame */
882     PVC_DYNAMIC_DATA *pPvcDynamicData,
883     FIXP_DBL *
884         *analysBufferReal, /*!< Real part of subband samples to be processed */
885     FIXP_DBL *
886         *analysBufferImag, /*!< Imag part of subband samples to be processed */
887     const int useLP,
888     FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */
889     const UINT flags, const int frameErrorFlag) {
890   int c, i, i_stop, j, envNoise = 0;
891   UCHAR *borders = hFrameData->frameInfo.borders;
892   UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
893   int pvc_mode = pPvcDynamicData->pvc_mode;
894   int first_start =
895       ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
896   FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
897   HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
898   UCHAR **pFreqBandTable = hFreq->freqBandTable;
899   UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
900 
901   int lowSubband = hFreq->lowSubband;
902   int highSubband = hFreq->highSubband;
903   int noSubbands = highSubband - lowSubband;
904 
905   /* old high subband before headerchange
906      we asume no headerchange here        */
907   int ov_highSubband = hFreq->highSubband;
908 
909   int noNoiseBands = hFreq->nNfb;
910   UCHAR *noSubFrameBands = hFreq->nSfb;
911   int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
912 
913   SCHAR sineMapped[MAX_FREQ_COEFFS];
914   SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
915   SCHAR adj_e = 0;
916   SCHAR output_e;
917   SCHAR final_e = 0;
918   /* inter-TES is active in one or more envelopes of the current SBR frame */
919   const int iTES_enable = hFrameData->iTESactive;
920   const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
921   SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
922 
923   UCHAR smooth_length = 0;
924 
925   FIXP_SGL *pIenv = hFrameData->iEnvelope;
926 
927   C_ALLOC_SCRATCH_START(useAliasReduction, UCHAR, 64)
928 
929   /* if values differ we had a headerchange; if old highband is bigger then new
930      one we need to patch overlap-highband-scaling for this frame (see use of
931      ov_highSubband) as overlap contains higher frequency components which would
932      get lost */
933   if (hFreq->highSubband < hFreq->ov_highSubband) {
934     ov_highSubband = hFreq->ov_highSubband;
935   }
936 
937   if (pvc_mode > 0) {
938     if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
939       /* noise envelope of previous frame is trailing into current PVC frame */
940       envNoise = -1;
941       noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
942       noNoiseBands = h_sbr_cal_env->prevNNfb;
943       noSubFrameBands = h_sbr_cal_env->prevNSfb;
944       lowSubband = h_sbr_cal_env->prevLoSubband;
945       highSubband = h_sbr_cal_env->prevHiSubband;
946 
947       noSubbands = highSubband - lowSubband;
948       ov_highSubband = highSubband;
949       if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
950         ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
951       }
952 
953       pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
954       pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
955       pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
956     }
957 
958     mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
959                     h_sbr_cal_env->harmFlagsPrev,
960                     h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
961                     hFrameData->sinusoidal_position,
962                     &h_sbr_cal_env->sinusoidal_positionPrev,
963                     (borders[0] > bordersPvc[0]) ? 1 : 0);
964   } else {
965     /*
966       Extract sine flags for all QMF bands
967     */
968     mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
969                  hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
970                  h_sbr_cal_env->harmFlagsPrevActive,
971                  hFrameData->frameInfo.tranEnv, sineMapped);
972   }
973 
974   /*
975     Scan for maximum in bufferd noise levels.
976     This is needed in case that we had strong noise in the previous frame
977     which is smoothed into the current frame.
978     The resulting exponent is used as start value for the maximum search
979     in reference energies
980   */
981   if (!useLP)
982     adj_e = h_sbr_cal_env->filtBufferNoise_e -
983             getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
984             (INT)MAX_SFB_NRG_HEADROOM;
985 
986   /*
987     Scan for maximum reference energy to be able
988     to select appropriate values for adj_e and final_e.
989   */
990   if (pvc_mode > 0) {
991     INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
992 
993     /* Energy -> magnitude (sqrt halfens exponent) */
994     maxSfbNrg_e =
995         (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
996 
997     /* Some safety margin is needed for 2 reasons:
998        - The signal energy is not equally spread over all subband samples in
999          a specific sfb of an envelope (Nrg could be too high by a factor of
1000          envWidth * sfbWidth)
1001        - Smoothing can smear high gains of the previous envelope into the
1002        current
1003     */
1004     maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
1005 
1006     adj_e = maxSfbNrg_e;
1007     // final_e should not exist for PVC fixfix framing
1008   } else {
1009     for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
1010       INT maxSfbNrg_e =
1011           -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
1012 
1013       /* Fetch frequency resolution for current envelope: */
1014       for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
1015         maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
1016       }
1017       maxSfbNrg_e -= NRG_EXP_OFFSET;
1018 
1019       /* Energy -> magnitude (sqrt halfens exponent) */
1020       maxSfbNrg_e =
1021           (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */
1022 
1023       /* Some safety margin is needed for 2 reasons:
1024          - The signal energy is not equally spread over all subband samples in
1025            a specific sfb of an envelope (Nrg could be too high by a factor of
1026            envWidth * sfbWidth)
1027          - Smoothing can smear high gains of the previous envelope into the
1028          current
1029       */
1030       maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
1031 
1032       if (borders[i] < hHeaderData->numberTimeSlots)
1033         /* This envelope affects timeslots that belong to the output frame */
1034         adj_e = fMax(maxSfbNrg_e, adj_e);
1035 
1036       if (borders[i + 1] > hHeaderData->numberTimeSlots)
1037         /* This envelope affects timeslots after the output frame */
1038         final_e = fMax(maxSfbNrg_e, final_e);
1039     }
1040   }
1041   /*
1042     Calculate adjustment factors and apply them for every envelope.
1043   */
1044   pIenv = hFrameData->iEnvelope;
1045 
1046   if (pvc_mode > 0) {
1047     /* iterate over SBR time slots starting with bordersPvc[i] */
1048     i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
1049                           PVC */
1050     i_stop = PVC_NTIMESLOT;
1051     FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
1052   } else {
1053     /* iterate over SBR envelopes starting with 0 */
1054     i = 0;
1055     i_stop = hFrameData->frameInfo.nEnvelopes;
1056   }
1057   for (; i < i_stop; i++) {
1058     int k, noNoiseFlag;
1059     SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
1060     C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
1061 
1062     /*
1063       Helper variables.
1064     */
1065     int start_pos, stop_pos, freq_res;
1066     if (pvc_mode > 0) {
1067       start_pos =
1068           hHeaderData->timeStep *
1069           i; /* Start-position in time (subband sample) for current envelope. */
1070       stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
1071                                                      (subband sample) for
1072                                                      current envelope. */
1073       freq_res =
1074           hFrameData->frameInfo
1075               .freqRes[0]; /* Frequency resolution for current envelope. */
1076       FDK_ASSERT(
1077           freq_res ==
1078           hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
1079     } else {
1080       start_pos = hHeaderData->timeStep *
1081                   borders[i]; /* Start-position in time (subband sample) for
1082                                  current envelope. */
1083       stop_pos = hHeaderData->timeStep *
1084                  borders[i + 1]; /* Stop-position in time (subband sample) for
1085                                     current envelope. */
1086       freq_res =
1087           hFrameData->frameInfo
1088               .freqRes[i]; /* Frequency resolution for current envelope. */
1089     }
1090 
1091     /* Always fully initialize the temporary energy table. This prevents
1092        negative energies and extreme gain factors in cases where the number of
1093        limiter bands exceeds the number of subbands. The latter can be caused by
1094        undetected bit errors and is tested by some streams from the
1095        certification set. */
1096     FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
1097 
1098     if (pvc_mode > 0) {
1099       /* get predicted energy values from PVC module */
1100       expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
1101                     pNrgs->nrgRef_e);
1102 
1103       if (i == borders[0]) {
1104         mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
1105                      hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
1106                      h_sbr_cal_env->harmFlagsPrevActive,
1107                      hFrameData->sinusoidal_position, sineMapped);
1108       }
1109 
1110       if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1111         if (envNoise >= 0) {
1112           noiseLevels += noNoiseBands; /* The noise floor data is stored in a
1113                                           row [noiseFloor1 noiseFloor2...].*/
1114         } else {
1115           /* leave trailing noise envelope of past frame */
1116           noNoiseBands = hFreq->nNfb;
1117           noSubFrameBands = hFreq->nSfb;
1118           noiseLevels = hFrameData->sbrNoiseFloorLevel;
1119 
1120           lowSubband = hFreq->lowSubband;
1121           highSubband = hFreq->highSubband;
1122 
1123           noSubbands = highSubband - lowSubband;
1124           ov_highSubband = highSubband;
1125           if (highSubband < hFreq->ov_highSubband) {
1126             ov_highSubband = hFreq->ov_highSubband;
1127           }
1128 
1129           pFreqBandTable[0] = hFreq->freqBandTableLo;
1130           pFreqBandTable[1] = hFreq->freqBandTableHi;
1131           pFreqBandTableNoise = hFreq->freqBandTableNoise;
1132         }
1133         envNoise++;
1134       }
1135     } else {
1136       /* If the start-pos of the current envelope equals the stop pos of the
1137          current noise envelope, increase the pointer (i.e. choose the next
1138          noise-floor).*/
1139       if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1140         noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
1141                                         [noiseFloor1 noiseFloor2...].*/
1142         envNoise++;
1143       }
1144     }
1145     if (i == hFrameData->frameInfo.tranEnv ||
1146         i == h_sbr_cal_env->prevTranEnv) /* attack */
1147     {
1148       noNoiseFlag = 1;
1149       if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
1150     } else {
1151       noNoiseFlag = 0;
1152       if (!useLP)
1153         smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
1154                         << 2; /* can become either 0 or 4 */
1155     }
1156 
1157     /*
1158       Energy estimation in transposed highband.
1159     */
1160     if (hHeaderData->bs_data.interpolFreq)
1161       calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1162                         lowSubband, highSubband, start_pos, stop_pos, input_e,
1163                         pNrgs->nrgEst, pNrgs->nrgEst_e);
1164     else
1165       calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1166                     noSubFrameBands[freq_res], pFreqBandTable[freq_res],
1167                     start_pos, stop_pos, input_e, pNrgs->nrgEst,
1168                     pNrgs->nrgEst_e);
1169 
1170     /*
1171       Calculate subband gains
1172     */
1173     {
1174       UCHAR *table = pFreqBandTable[freq_res];
1175       UCHAR *pUiNoise =
1176           &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
1177                                       band. */
1178 
1179       FIXP_SGL *pNoiseLevels = noiseLevels;
1180 
1181       FIXP_DBL tmpNoise =
1182           FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1183       SCHAR tmpNoise_e =
1184           (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1185 
1186       int cc = 0;
1187       c = 0;
1188       if (pvc_mode > 0) {
1189         for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1190           UCHAR sinePresentFlag = 0;
1191           int li = table[j];
1192           int ui = table[j + 1];
1193 
1194           for (k = li; k < ui; k++) {
1195             sinePresentFlag |= (i >= sineMapped[cc]);
1196             cc++;
1197           }
1198 
1199           for (k = li; k < ui; k++) {
1200             FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
1201             SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
1202 
1203             if (k >= *pUiNoise) {
1204               tmpNoise =
1205                   FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1206               tmpNoise_e =
1207                   (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1208 
1209               pUiNoise++;
1210             }
1211 
1212             FDK_ASSERT(k >= lowSubband);
1213 
1214             if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1215 
1216             pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1217             pNrgs->nrgSine_e[c] = 0;
1218 
1219             calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1220                             sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1221 
1222             c++;
1223           }
1224         }
1225       } else {
1226         for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1227           FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
1228           SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
1229 
1230           UCHAR sinePresentFlag = 0;
1231           int li = table[j];
1232           int ui = table[j + 1];
1233 
1234           for (k = li; k < ui; k++) {
1235             sinePresentFlag |= (i >= sineMapped[cc]);
1236             cc++;
1237           }
1238 
1239           for (k = li; k < ui; k++) {
1240             if (k >= *pUiNoise) {
1241               tmpNoise =
1242                   FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1243               tmpNoise_e =
1244                   (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1245 
1246               pUiNoise++;
1247             }
1248 
1249             FDK_ASSERT(k >= lowSubband);
1250 
1251             if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1252 
1253             pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1254             pNrgs->nrgSine_e[c] = 0;
1255 
1256             calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1257                             sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1258 
1259             pNrgs->nrgRef[c] = refNrg;
1260             pNrgs->nrgRef_e[c] = refNrg_e;
1261 
1262             c++;
1263           }
1264           pIenv++;
1265         }
1266       }
1267     }
1268 
1269     /*
1270       Noise limiting
1271     */
1272 
1273     for (c = 0; c < hFreq->noLimiterBands; c++) {
1274       FIXP_DBL sumRef, boostGain, maxGain;
1275       FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1276       SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
1277       int maxGainLimGainSum_e = 0;
1278 
1279       calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
1280                   hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
1281                   &maxGain_e);
1282 
1283       /* Multiply maxGain with limiterGain: */
1284       maxGain = fMult(
1285           maxGain,
1286           FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]);
1287       /* maxGain_e +=
1288        * FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; */
1289       /* The addition of maxGain_e and FDK_sbrDecoder_sbr_limGains_e[3] might
1290          yield values greater than 127 which doesn't fit into an SCHAR! In these
1291          rare situations limit maxGain_e to 127.
1292       */
1293       maxGainLimGainSum_e =
1294           maxGain_e +
1295           FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
1296       maxGain_e =
1297           (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
1298 
1299       /* Scale mantissa of MaxGain into range between 0.5 and 1: */
1300       if (maxGain == FL2FXCONST_DBL(0.0f))
1301         maxGain_e = -FRACT_BITS;
1302       else {
1303         SCHAR charTemp = CountLeadingBits(maxGain);
1304         maxGain_e -= charTemp;
1305         maxGain <<= (int)charTemp;
1306       }
1307 
1308       if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
1309         maxGain = FL2FXCONST_DBL(0.5f);
1310         maxGain_e = maxGainLimit_e;
1311       }
1312 
1313       /* Every subband gain is compared to the scaled "average gain"
1314          and limited if necessary: */
1315       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1316            k++) {
1317         if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
1318             (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
1319           FIXP_DBL noiseAmp;
1320           SCHAR noiseAmp_e;
1321 
1322           FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
1323                              pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
1324           pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
1325           pNrgs->noiseLevel_e[k] += noiseAmp_e;
1326           pNrgs->nrgGain[k] = maxGain;
1327           pNrgs->nrgGain_e[k] = maxGain_e;
1328         }
1329       }
1330 
1331       /* -- Boost gain
1332         Calculate and apply boost factor for each limiter band:
1333         1. Check how much energy would be present when using the limited gain
1334         2. Calculate boost factor by comparison with reference energy
1335         3. Apply boost factor to compensate for the energy loss due to limiting
1336       */
1337       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1338            k++) {
1339         /* 1.a  Add energy of adjusted signal (using preliminary gain) */
1340         FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
1341         SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
1342         FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
1343 
1344         /* 1.b  Add sine energy (if present) */
1345         if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
1346           FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
1347                           &accu, &accu_e);
1348         } else {
1349           /* 1.c  Add noise energy (if present) */
1350           if (noNoiseFlag == 0) {
1351             FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
1352                             accu_e, &accu, &accu_e);
1353           }
1354         }
1355       }
1356 
1357       /* 2.a  Calculate ratio of wanted energy and accumulated energy */
1358       if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
1359         boostGain = FL2FXCONST_DBL(0.6279716f);
1360         boostGain_e = 2;
1361       } else {
1362         INT div_e;
1363         boostGain = fDivNorm(sumRef, accu, &div_e);
1364         boostGain_e = sumRef_e - accu_e + div_e;
1365       }
1366 
1367       /* 2.b Result too high? --> Limit the boost factor to +4 dB */
1368       if ((boostGain_e > 3) ||
1369           (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
1370           (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
1371         boostGain = FL2FXCONST_DBL(0.6279716f);
1372         boostGain_e = 2;
1373       }
1374       /* 3.  Multiply all signal components with the boost factor */
1375       for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1376            k++) {
1377         pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
1378         pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
1379 
1380         pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
1381         pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
1382 
1383         pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
1384         pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
1385       }
1386     }
1387     /* End of noise limiting */
1388 
1389     if (useLP)
1390       aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
1391                         noSubbands);
1392 
1393     /* For the timeslots within the range for the output frame,
1394        use the same scale for the noise levels.
1395        Drawback: If the envelope exceeds the frame border, the noise levels
1396                  will have to be rescaled later to fit final_e of
1397                  the gain-values.
1398     */
1399     noise_e = (start_pos < no_cols) ? adj_e : final_e;
1400 
1401     /*
1402       Convert energies to amplitude levels
1403     */
1404     for (k = 0; k < noSubbands; k++) {
1405       FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
1406       FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
1407                        &pNrgs->nrgGain_e[k]);
1408       FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
1409                        &noise_e);
1410     }
1411 
1412     /*
1413       Apply calculated gains and adaptive noise
1414     */
1415 
1416     /* assembleHfSignals() */
1417     {
1418       int scale_change, sc_change;
1419       FIXP_SGL smooth_ratio;
1420       int filtBufferNoiseShift = 0;
1421 
1422       /* Initialize smoothing buffers with the first valid values */
1423       if (h_sbr_cal_env->startUp) {
1424         if (!useLP) {
1425           h_sbr_cal_env->filtBufferNoise_e = noise_e;
1426 
1427           FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1428                     noSubbands * sizeof(SCHAR));
1429           FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1430                     noSubbands * sizeof(FIXP_DBL));
1431           FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1432                     noSubbands * sizeof(FIXP_DBL));
1433         }
1434         h_sbr_cal_env->startUp = 0;
1435       }
1436 
1437       if (!useLP) {
1438         equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer,   /* buffered */
1439                               h_sbr_cal_env->filtBuffer_e, /* buffered */
1440                               pNrgs->nrgGain,              /* current  */
1441                               pNrgs->nrgGain_e,            /* current  */
1442                               noSubbands);
1443 
1444         /* Adapt exponent of buffered noise levels to the current exponent
1445            so they can easily be smoothed */
1446         if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
1447           int shift = fixMin(DFRACT_BITS - 1,
1448                              (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1449           for (k = 0; k < noSubbands; k++)
1450             h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1451         } else {
1452           int shift =
1453               fixMin(DFRACT_BITS - 1,
1454                      -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1455           for (k = 0; k < noSubbands; k++)
1456             h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1457         }
1458 
1459         h_sbr_cal_env->filtBufferNoise_e = noise_e;
1460       }
1461 
1462       /* find best scaling! */
1463       scale_change = -(DFRACT_BITS - 1);
1464       for (k = 0; k < noSubbands; k++) {
1465         scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
1466       }
1467       sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
1468 
1469       if ((scale_change - sc_change + 1) < 0)
1470         scale_change -= (scale_change - sc_change + 1);
1471 
1472       scale_change = (scale_change - sc_change) + 1;
1473 
1474       for (k = 0; k < noSubbands; k++) {
1475         int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
1476         pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
1477         pNrgs->nrgGain_e[k] += sc;
1478       }
1479 
1480       if (!useLP) {
1481         for (k = 0; k < noSubbands; k++) {
1482           int sc =
1483               scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
1484           h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
1485         }
1486       }
1487 
1488       for (j = start_pos; j < stop_pos; j++) {
1489         /* This timeslot is located within the first part of the processing
1490            buffer and will be fed into the QMF-synthesis for the current frame.
1491                adj_e - input_e
1492            This timeslot will not yet be fed into the QMF so we do not care
1493            about the adj_e.
1494                sc_change = final_e - input_e
1495         */
1496         if ((j == no_cols) && (start_pos < no_cols)) {
1497           int shift = (int)(noise_e - final_e);
1498           if (!useLP)
1499             filtBufferNoiseShift = shift; /* shifting of
1500                                              h_sbr_cal_env->filtBufferNoise[k]
1501                                              will be applied in function
1502                                              adjustTimeSlotHQ() */
1503           if (shift >= 0) {
1504             shift = fixMin(DFRACT_BITS - 1, shift);
1505             for (k = 0; k < noSubbands; k++) {
1506               pNrgs->nrgSine[k] <<= shift;
1507               pNrgs->noiseLevel[k] <<= shift;
1508               /*
1509               if (!useLP)
1510                 h_sbr_cal_env->filtBufferNoise[k]  <<= shift;
1511               */
1512             }
1513           } else {
1514             shift = fixMin(DFRACT_BITS - 1, -shift);
1515             for (k = 0; k < noSubbands; k++) {
1516               pNrgs->nrgSine[k] >>= shift;
1517               pNrgs->noiseLevel[k] >>= shift;
1518               /*
1519               if (!useLP)
1520                 h_sbr_cal_env->filtBufferNoise[k]  >>= shift;
1521               */
1522             }
1523           }
1524 
1525           /* update noise scaling */
1526           noise_e = final_e;
1527           if (!useLP)
1528             h_sbr_cal_env->filtBufferNoise_e =
1529                 noise_e; /* scaling value unused! */
1530 
1531           /* update gain buffer*/
1532           sc_change -= (final_e - input_e);
1533 
1534           if (sc_change < 0) {
1535             for (k = 0; k < noSubbands; k++) {
1536               pNrgs->nrgGain[k] >>= -sc_change;
1537               pNrgs->nrgGain_e[k] += -sc_change;
1538             }
1539             if (!useLP) {
1540               for (k = 0; k < noSubbands; k++) {
1541                 h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
1542               }
1543             }
1544           } else {
1545             scale_change += sc_change;
1546           }
1547 
1548         } /* if */
1549 
1550         if (!useLP) {
1551           /* Prevent the smoothing filter from running on constant levels */
1552           if (j - start_pos < smooth_length)
1553             smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
1554           else
1555             smooth_ratio = FL2FXCONST_SGL(0.0f);
1556 
1557           if (iTES_enable) {
1558             /* adjustTimeSlotHQ() without adding of additional harmonics */
1559             adjustTimeSlotHQ_GainAndNoise(
1560                 &analysBufferReal[j][lowSubband],
1561                 &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1562                 lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1),
1563                 smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
1564           } else {
1565             adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1566                              &analysBufferImag[j][lowSubband], h_sbr_cal_env,
1567                              pNrgs, lowSubband, noSubbands,
1568                              fMin(scale_change, DFRACT_BITS - 1), smooth_ratio,
1569                              noNoiseFlag, filtBufferNoiseShift);
1570           }
1571         } else {
1572           FDK_ASSERT(!iTES_enable); /* not supported */
1573           if (flags & SBRDEC_ELD_GRID) {
1574             /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
1575             adjustTimeSlot_EldGrid(
1576                 &analysBufferReal[j][lowSubband], pNrgs,
1577                 &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1578                 fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1579                 &h_sbr_cal_env->phaseIndex,
1580                 fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
1581                      -(DFRACT_BITS - 1)));
1582           } else {
1583             adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
1584                              &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1585                              fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1586                              &h_sbr_cal_env->phaseIndex);
1587           }
1588         }
1589         /* In case the envelope spans accross the no_cols border both exponents
1590          * are needed. */
1591         /* nrgGain_e[0...(noSubbands-1)] are equalized by
1592          * equalizeFiltBufferExp() */
1593         pNrgs->exponent[(j < no_cols) ? 0 : 1] =
1594             (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
1595                     scale_change);
1596       } /* for */
1597 
1598       if (iTES_enable) {
1599         apply_inter_tes(
1600             analysBufferReal, /* pABufR, */
1601             analysBufferImag, /* pABufI, */
1602             sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
1603             stop_pos, lowSubband, noSubbands,
1604             hFrameData
1605                 ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
1606         );
1607 
1608         /* add additional harmonics */
1609         for (j = start_pos; j < stop_pos; j++) {
1610           /* match exponent of additional harmonics to scale change of QMF data
1611            * caused by apply_inter_tes() */
1612           scale_change = 0;
1613 
1614           if ((start_pos <= no_cols) && (stop_pos > no_cols)) {
1615             /* Scaling of analysBuffers was potentially changed within this
1616                envelope. The pNrgs->nrgSine_e match the second part of the
1617                envelope. For (j<=no_cols) the exponent of the sine energies has
1618                to be adapted. */
1619             scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
1620           }
1621 
1622           adjustTimeSlotHQ_AddHarmonics(
1623               &analysBufferReal[j][lowSubband],
1624               &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1625               lowSubband, noSubbands,
1626               -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
1627         }
1628       }
1629 
1630       if (!useLP) {
1631         /* Update time-smoothing-buffers for gains and noise levels
1632            The gains and the noise values of the current envelope are copied
1633            into the buffer. This has to be done at the end of each envelope as
1634            the values are required for a smooth transition to the next envelope.
1635          */
1636         FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1637                   noSubbands * sizeof(FIXP_DBL));
1638         FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1639                   noSubbands * sizeof(SCHAR));
1640         FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1641                   noSubbands * sizeof(FIXP_DBL));
1642       }
1643     }
1644     C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1645   }
1646 
1647   /* adapt adj_e to the scale change caused by apply_inter_tes() */
1648   adj_e += iTES_scale_change;
1649 
1650   /* Rescale output samples */
1651   {
1652     FIXP_DBL maxVal;
1653     int ov_reserve, reserve;
1654 
1655     /* Determine headroom in old adjusted samples */
1656     maxVal =
1657         maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1658                          lowSubband, ov_highSubband, 0, first_start);
1659 
1660     ov_reserve = fNorm(maxVal);
1661 
1662     /* Determine headroom in new adjusted samples */
1663     maxVal =
1664         maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1665                          lowSubband, highSubband, first_start, no_cols);
1666 
1667     reserve = fNorm(maxVal);
1668 
1669     /* Determine common output exponent */
1670     output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
1671 
1672     /* Rescale old samples */
1673     rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1674                           lowSubband, ov_highSubband, 0, first_start,
1675                           ov_adj_e - output_e);
1676 
1677     /* Rescale new samples */
1678     rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1679                           lowSubband, highSubband, first_start, no_cols,
1680                           adj_e - output_e);
1681   }
1682 
1683   /* Update hb_scale */
1684   sbrScaleFactor->hb_scale = EXP2SCALE(output_e);
1685 
1686   /* Save the current final exponent for the next frame: */
1687   /* adapt final_e to the scale change caused by apply_inter_tes() */
1688   sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e + iTES_scale_change);
1689 
1690   /* We need to remember to the next frame that the transient
1691      will occur in the first envelope (if tranEnv == nEnvelopes). */
1692   if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1693     h_sbr_cal_env->prevTranEnv = 0;
1694   else
1695     h_sbr_cal_env->prevTranEnv = -1;
1696 
1697   if (pvc_mode > 0) {
1698     /* Not more than just the last noise envelope reaches into the next PVC
1699        frame! This should be true because bs_noise_position is <= 15 */
1700     FDK_ASSERT(hFrameData->frameInfo
1701                    .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
1702                PVC_NTIMESLOT);
1703     if (hFrameData->frameInfo
1704             .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
1705         PVC_NTIMESLOT) {
1706       FDK_ASSERT(noiseLevels ==
1707                  (hFrameData->sbrNoiseFloorLevel +
1708                   (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
1709       h_sbr_cal_env->prevNNfb = noNoiseBands;
1710 
1711       h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
1712       h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
1713 
1714       h_sbr_cal_env->prevLoSubband = lowSubband;
1715       h_sbr_cal_env->prevHiSubband = highSubband;
1716       h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
1717 
1718       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
1719                 noSubFrameBands[0] + 1);
1720       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
1721                 noSubFrameBands[1] + 1);
1722       FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
1723                 hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
1724 
1725       FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
1726                 MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
1727     }
1728   }
1729 
1730   C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
1731 }
1732 
1733 /*!
1734   \brief   Create envelope instance
1735 
1736   Must be called once for each channel before calculateSbrEnvelope() can be
1737   used.
1738 
1739   \return  errorCode, 0 if successful
1740 */
1741 SBR_ERROR
createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs,HANDLE_SBR_HEADER_DATA hHeaderData,const int chan,const UINT flags)1742 createSbrEnvelopeCalc(
1743     HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */
1744     HANDLE_SBR_HEADER_DATA
1745         hHeaderData, /*!< static SBR control data, initialized with defaults */
1746     const int chan,  /*!< Channel for which to assign buffers */
1747     const UINT flags) {
1748   SBR_ERROR err = SBRDEC_OK;
1749   int i;
1750 
1751   /* Clear previous missing harmonics flags */
1752   for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
1753     hs->harmFlagsPrev[i] = 0;
1754     hs->harmFlagsPrevActive[i] = 0;
1755   }
1756   hs->harmIndex = 0;
1757 
1758   FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
1759   hs->prevNNfb = 0;
1760   FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
1761   hs->sinusoidal_positionPrev = 0;
1762 
1763   /*
1764     Setup pointers for time smoothing.
1765     The buffer itself will be initialized later triggered by the startUp-flag.
1766   */
1767   hs->prevTranEnv = -1;
1768 
1769   /* initialization */
1770   resetSbrEnvelopeCalc(hs);
1771 
1772   if (chan == 0) { /* do this only once */
1773     err = resetFreqBandTables(hHeaderData, flags);
1774   }
1775 
1776   return err;
1777 }
1778 
1779 /*!
1780   \brief   Create envelope instance
1781 
1782   Must be called once for each channel before calculateSbrEnvelope() can be
1783   used.
1784 
1785   \return  errorCode, 0 if successful
1786 */
deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs)1787 int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs) { return 0; }
1788 
1789 /*!
1790   \brief   Reset envelope instance
1791 
1792   This function must be called for each channel on a change of configuration.
1793   Note that resetFreqBandTables should also be called in this case.
1794 
1795   \return  errorCode, 0 if successful
1796 */
resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv)1797 void resetSbrEnvelopeCalc(
1798     HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */
1799 {
1800   hCalEnv->phaseIndex = 0;
1801 
1802   /* Noise exponent needs to be reset because the output exponent for the next
1803    * frame depends on it */
1804   hCalEnv->filtBufferNoise_e = 0;
1805 
1806   hCalEnv->startUp = 1;
1807 }
1808 
1809 /*!
1810   \brief  Equalize exponents of the buffered gain values and the new ones
1811 
1812   After equalization of exponents, the FIR-filter addition for smoothing
1813   can be performed.
1814   This function is called once for each envelope before adjusting.
1815 */
equalizeFiltBufferExp(FIXP_DBL * filtBuffer,SCHAR * filtBuffer_e,FIXP_DBL * nrgGain,SCHAR * nrgGain_e,int subbands)1816 static void equalizeFiltBufferExp(
1817     FIXP_DBL *filtBuffer, /*!< bufferd gains */
1818     SCHAR *filtBuffer_e,  /*!< exponents of bufferd gains */
1819     FIXP_DBL *nrgGain,    /*!< gains for current envelope */
1820     SCHAR *nrgGain_e,     /*!< exponents of gains for current envelope */
1821     int subbands)         /*!< Number of QMF subbands */
1822 {
1823   int band;
1824   int diff;
1825 
1826   for (band = 0; band < subbands; band++) {
1827     diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
1828     if (diff > 0) {
1829       filtBuffer[band] >>=
1830           fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
1831                                           shifting the mantissa. */
1832       filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1833     } else if (diff < 0) {
1834       /* The buffered gains seem to be larger, but maybe there
1835          are some unused bits left in the mantissa */
1836 
1837       int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
1838 
1839       if ((-diff) <= reserve) {
1840         /* There is enough space in the buffered mantissa so
1841            that we can take the new exponent as common.
1842         */
1843         filtBuffer[band] <<= (-diff);
1844         filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1845       } else {
1846         filtBuffer[band] <<=
1847             reserve; /* Shift the mantissa as far as possible: */
1848         filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1849 
1850         /* For the remaining difference, change the new gain value */
1851         diff = -(reserve + diff);
1852         nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
1853         nrgGain_e[band] += diff;
1854       }
1855     }
1856   }
1857 }
1858 
1859 /*!
1860   \brief  Shift left the mantissas of all subband samples
1861           in the giventime and frequency range by the specified number of bits.
1862 
1863   This function is used to rescale the audio data in the overlap buffer
1864   which has already been envelope adjusted with the last frame.
1865 */
rescaleSubbandSamples(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos,int shift)1866 void rescaleSubbandSamples(
1867     FIXP_DBL **re,   /*!< Real part of input and output subband samples */
1868     FIXP_DBL **im,   /*!< Imaginary part of input and output subband samples */
1869     int lowSubband,  /*!< Begin of frequency range to process */
1870     int highSubband, /*!< End of frequency range to process */
1871     int start_pos,   /*!< Begin of time rage (QMF-timeslot) */
1872     int next_pos,    /*!< End of time rage (QMF-timeslot) */
1873     int shift)       /*!< number of bits to shift */
1874 {
1875   int width = highSubband - lowSubband;
1876 
1877   if ((width > 0) && (shift != 0)) {
1878     if (im != NULL) {
1879       for (int l = start_pos; l < next_pos; l++) {
1880         scaleValues(&re[l][lowSubband], width, shift);
1881         scaleValues(&im[l][lowSubband], width, shift);
1882       }
1883     } else {
1884       for (int l = start_pos; l < next_pos; l++) {
1885         scaleValues(&re[l][lowSubband], width, shift);
1886       }
1887     }
1888   }
1889 }
1890 
FDK_get_maxval_real(FIXP_DBL maxVal,FIXP_DBL * reTmp,INT width)1891 static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
1892                                            INT width) {
1893   maxVal = (FIXP_DBL)0;
1894   while (width-- != 0) {
1895     FIXP_DBL tmp = *(reTmp++);
1896     maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
1897   }
1898 
1899   return maxVal;
1900 }
1901 
1902 /*!
1903   \brief   Determine headroom for shifting
1904 
1905   Determine by how much the spectrum can be shifted left
1906   for better accuracy in later processing.
1907 
1908   \return  Number of free bits in the biggest spectral value
1909 */
1910 
maxSubbandSample(FIXP_DBL ** re,FIXP_DBL ** im,int lowSubband,int highSubband,int start_pos,int next_pos)1911 FIXP_DBL maxSubbandSample(
1912     FIXP_DBL **re,   /*!< Real part of input and output subband samples */
1913     FIXP_DBL **im,   /*!< Real part of input and output subband samples */
1914     int lowSubband,  /*!< Begin of frequency range to process */
1915     int highSubband, /*!< Number of QMF bands to process */
1916     int start_pos,   /*!< Begin of time rage (QMF-timeslot) */
1917     int next_pos     /*!< End of time rage (QMF-timeslot) */
1918 ) {
1919   FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1920   unsigned int width = highSubband - lowSubband;
1921 
1922   FDK_ASSERT(width <= (64));
1923 
1924   if (width > 0) {
1925     if (im != NULL) {
1926       for (int l = start_pos; l < next_pos; l++) {
1927         int k = width;
1928         FIXP_DBL *reTmp = &re[l][lowSubband];
1929         FIXP_DBL *imTmp = &im[l][lowSubband];
1930         do {
1931           FIXP_DBL tmp1 = *(reTmp++);
1932           FIXP_DBL tmp2 = *(imTmp++);
1933           maxVal |=
1934               (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
1935           maxVal |=
1936               (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
1937         } while (--k != 0);
1938       }
1939     } else {
1940       for (int l = start_pos; l < next_pos; l++) {
1941         maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
1942       }
1943     }
1944   }
1945 
1946   if (maxVal > (FIXP_DBL)0) {
1947     /* For negative input values, maxVal is too small by 1. Add 1 only when
1948      * necessary: if maxVal is a power of 2 */
1949     FIXP_DBL lowerPow2 =
1950         (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
1951     if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
1952   }
1953 
1954   return (maxVal);
1955 }
1956 
1957 /* #define SHIFT_BEFORE_SQUARE (3) */ /* (7/2) */
1958 /* Avoid assertion failures triggerd by overflows which occured in robustness
1959    tests. Setting the SHIFT_BEFORE_SQUARE to 4 has negligible effect on (USAC)
1960    conformance results. */
1961 #define SHIFT_BEFORE_SQUARE (4) /* ((8 - 0) / 2) */
1962 
1963 /*!<
1964   If the accumulator does not provide enough overflow bits or
1965   does not provide a high dynamic range, the below energy calculation
1966   requires an additional shift operation for each sample.
1967   On the other hand, doing the shift allows using a single-precision
1968   multiplication for the square (at least 16bit x 16bit).
1969   For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic
1970   is required for the energy accumulation.
1971   Theoretically, the sample-squares can sum up to a value of 76,
1972   requiring 7 overflow bits. However since such situations are *very*
1973   rare, accu can be limited to 64.
1974   In case native saturated arithmetic is not available, overflows
1975   can be prevented by replacing the above #define by
1976     #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2)
1977   which will result in slightly reduced accuracy.
1978 */
1979 
1980 /*!
1981   \brief  Estimates the mean energy of each filter-bank channel for the
1982           duration of the current envelope
1983 
1984   This function is used when interpolFreq is true.
1985 */
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)1986 static void calcNrgPerSubband(
1987     FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
1988     FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
1989     int lowSubband,              /*!< Begin of the SBR frequency range */
1990     int highSubband,             /*!< High end of the SBR frequency range */
1991     int start_pos,               /*!< First QMF-slot of current envelope */
1992     int next_pos,                /*!< Last QMF-slot of current envelope + 1 */
1993     SCHAR frameExp,              /*!< Common exponent for all input samples */
1994     FIXP_DBL *nrgEst,            /*!< resulting Energy (0..1) */
1995     SCHAR *nrgEst_e)             /*!< Exponent of resulting Energy */
1996 {
1997   FIXP_SGL invWidth;
1998   SCHAR preShift;
1999   SCHAR shift;
2000   FIXP_DBL sum;
2001   int k;
2002 
2003   /* Divide by width of envelope later: */
2004   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2005   /* The common exponent needs to be doubled because all mantissas are squared:
2006    */
2007   frameExp = frameExp << 1;
2008 
2009   for (k = lowSubband; k < highSubband; k++) {
2010     FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2011     FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2012     FIXP_DBL maxVal;
2013 
2014     if (analysBufferImag != NULL) {
2015       int l;
2016       maxVal = FL2FX_DBL(0.0f);
2017       for (l = start_pos; l < next_pos; l++) {
2018         bufferImag[l] = analysBufferImag[l][k];
2019         maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
2020                              ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
2021         bufferReal[l] = analysBufferReal[l][k];
2022         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2023                              ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2024       }
2025     } else {
2026       int l;
2027       maxVal = FL2FX_DBL(0.0f);
2028       for (l = start_pos; l < next_pos; l++) {
2029         bufferReal[l] = analysBufferReal[l][k];
2030         maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2031                              ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2032       }
2033     }
2034 
2035     if (maxVal != FL2FXCONST_DBL(0.f)) {
2036       /* If the accu does not provide enough overflow bits, we cannot
2037          shift the samples up to the limit.
2038          Instead, keep up to 3 free bits in each sample, i.e. up to
2039          6 bits after calculation of square.
2040          Please note the comment on saturated arithmetic above!
2041       */
2042       FIXP_DBL accu;
2043       preShift = CntLeadingZeros(maxVal) - 1;
2044       preShift -= SHIFT_BEFORE_SQUARE;
2045 
2046       /* Limit preShift to a maximum value to prevent accumulator overflow in
2047          exceptional situations where the signal in the analysis-buffer is very
2048          small (small maxVal).
2049       */
2050       preShift = fMin(preShift, (SCHAR)25);
2051 
2052       accu = FL2FXCONST_DBL(0.0f);
2053       if (preShift >= 0) {
2054         int l;
2055         if (analysBufferImag != NULL) {
2056           for (l = start_pos; l < next_pos; l++) {
2057             FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
2058             FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
2059             accu = fPow2AddDiv2(accu, temp1);
2060             accu = fPow2AddDiv2(accu, temp2);
2061           }
2062         } else {
2063           for (l = start_pos; l < next_pos; l++) {
2064             FIXP_DBL temp = bufferReal[l] << (int)preShift;
2065             accu = fPow2AddDiv2(accu, temp);
2066           }
2067         }
2068       } else { /* if negative shift value */
2069         int l;
2070         int negpreShift = -preShift;
2071         if (analysBufferImag != NULL) {
2072           for (l = start_pos; l < next_pos; l++) {
2073             FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
2074             FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
2075             accu = fPow2AddDiv2(accu, temp1);
2076             accu = fPow2AddDiv2(accu, temp2);
2077           }
2078         } else {
2079           for (l = start_pos; l < next_pos; l++) {
2080             FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
2081             accu = fPow2AddDiv2(accu, temp);
2082           }
2083         }
2084       }
2085       accu <<= 1;
2086 
2087       /* Convert double precision to Mantissa/Exponent: */
2088       shift = fNorm(accu);
2089       sum = accu << (int)shift;
2090 
2091       /* Divide by width of envelope and apply frame scale: */
2092       *nrgEst++ = fMult(sum, invWidth);
2093       shift += 2 * preShift;
2094       if (analysBufferImag != NULL)
2095         *nrgEst_e++ = frameExp - shift;
2096       else
2097         *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
2098     }                                       /* maxVal!=0 */
2099     else {
2100       /* Prevent a zero-mantissa-number from being misinterpreted
2101          due to its exponent. */
2102       *nrgEst++ = FL2FXCONST_DBL(0.0f);
2103       *nrgEst_e++ = 0;
2104     }
2105   }
2106 }
2107 
2108 /*!
2109   \brief   Estimates the mean energy of each Scale factor band for the
2110            duration of the current envelope.
2111 
2112   This function is used when interpolFreq is false.
2113 */
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)2114 static void calcNrgPerSfb(
2115     FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */
2116     FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */
2117     int nSfb,                    /*!< Number of scale factor bands */
2118     UCHAR *freqBandTable,        /*!< First Subband for each Sfb */
2119     int start_pos,               /*!< First QMF-slot of current envelope */
2120     int next_pos,                /*!< Last QMF-slot of current envelope + 1 */
2121     SCHAR input_e,               /*!< Common exponent for all input samples */
2122     FIXP_DBL *nrgEst,            /*!< resulting Energy (0..1) */
2123     SCHAR *nrgEst_e)             /*!< Exponent of resulting Energy */
2124 {
2125   FIXP_SGL invWidth;
2126   FIXP_DBL temp;
2127   SCHAR preShift;
2128   SCHAR shift, sum_e;
2129   FIXP_DBL sum;
2130 
2131   int j, k, l, li, ui;
2132   FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient,
2133                              but overflow bits are required for accumulation */
2134 
2135   /* Divide by width of envelope later: */
2136   invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2137   /* The common exponent needs to be doubled because all mantissas are squared:
2138    */
2139   input_e = input_e << 1;
2140 
2141   for (j = 0; j < nSfb; j++) {
2142     li = freqBandTable[j];
2143     ui = freqBandTable[j + 1];
2144 
2145     FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
2146                                        ui, start_pos, next_pos);
2147 
2148     if (maxVal != FL2FXCONST_DBL(0.f)) {
2149       preShift = CntLeadingZeros(maxVal) - 1;
2150 
2151       /* If the accu does not provide enough overflow bits, we cannot
2152          shift the samples up to the limit.
2153          Instead, keep up to 3 free bits in each sample, i.e. up to
2154          6 bits after calculation of square.
2155          Please note the comment on saturated arithmetic above!
2156       */
2157       preShift -= SHIFT_BEFORE_SQUARE;
2158 
2159       sumAll = FL2FXCONST_DBL(0.0f);
2160 
2161       for (k = li; k < ui; k++) {
2162         sumLine = FL2FXCONST_DBL(0.0f);
2163 
2164         if (analysBufferImag != NULL) {
2165           if (preShift >= 0) {
2166             for (l = start_pos; l < next_pos; l++) {
2167               temp = analysBufferReal[l][k] << (int)preShift;
2168               sumLine += fPow2Div2(temp);
2169               temp = analysBufferImag[l][k] << (int)preShift;
2170               sumLine += fPow2Div2(temp);
2171             }
2172           } else {
2173             for (l = start_pos; l < next_pos; l++) {
2174               temp = analysBufferReal[l][k] >> -(int)preShift;
2175               sumLine += fPow2Div2(temp);
2176               temp = analysBufferImag[l][k] >> -(int)preShift;
2177               sumLine += fPow2Div2(temp);
2178             }
2179           }
2180         } else {
2181           if (preShift >= 0) {
2182             for (l = start_pos; l < next_pos; l++) {
2183               temp = analysBufferReal[l][k] << (int)preShift;
2184               sumLine += fPow2Div2(temp);
2185             }
2186           } else {
2187             for (l = start_pos; l < next_pos; l++) {
2188               temp = analysBufferReal[l][k] >> -(int)preShift;
2189               sumLine += fPow2Div2(temp);
2190             }
2191           }
2192         }
2193 
2194         /* The number of QMF-channels per SBR bands may be up to 15.
2195            Shift right to avoid overflows in sum over all channels. */
2196         sumLine = sumLine >> (4 - 1);
2197         sumAll += sumLine;
2198       }
2199 
2200       /* Convert double precision to Mantissa/Exponent: */
2201       shift = fNorm(sumAll);
2202       sum = sumAll << (int)shift;
2203 
2204       /* Divide by width of envelope: */
2205       sum = fMult(sum, invWidth);
2206 
2207       /* Divide by width of Sfb: */
2208       sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
2209 
2210       /* Set all Subband energies in the Sfb to the average energy: */
2211       if (analysBufferImag != NULL)
2212         sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
2213       else
2214         sum_e = input_e + 4 + 1 -
2215                 shift; /* -4 to compensate right-shift; +1 due to missing
2216                           imag. part */
2217 
2218       sum_e -= 2 * preShift;
2219     } /* maxVal!=0 */
2220     else {
2221       /* Prevent a zero-mantissa-number from being misinterpreted
2222          due to its exponent. */
2223       sum = FL2FXCONST_DBL(0.0f);
2224       sum_e = 0;
2225     }
2226 
2227     for (k = li; k < ui; k++) {
2228       *nrgEst++ = sum;
2229       *nrgEst_e++ = sum_e;
2230     }
2231   }
2232 }
2233 
2234 /*!
2235   \brief  Calculate gain, noise, and additional sine level for one subband.
2236 
2237   The resulting energy gain is given by mantissa and exponent.
2238 */
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)2239 static void calcSubbandGain(
2240     FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */
2241     SCHAR
2242         nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */
2243     ENV_CALC_NRGS *nrgs, int i, FIXP_DBL tmpNoise, /*!< Relative noise level */
2244     SCHAR tmpNoise_e,      /*!< Relative noise level (exponent) */
2245     UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */
2246     UCHAR sineMapped,      /*!< Indicates if sine must be added */
2247     int noNoiseFlag)       /*!< Flag to suppress noise addition */
2248 {
2249   FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
2250   SCHAR nrgEst_e =
2251       nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
2252   FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
2253   SCHAR *ptrNrgGain_e =
2254       &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
2255   FIXP_DBL *ptrNoiseLevel =
2256       &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
2257   SCHAR *ptrNoiseLevel_e =
2258       &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
2259   FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
2260   SCHAR *ptrNrgSine_e =
2261       &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
2262 
2263   FIXP_DBL a, b, c;
2264   SCHAR a_e, b_e, c_e;
2265 
2266   /*
2267      This addition of 1 prevents divisions by zero in the reference code.
2268      For very small energies in nrgEst, it prevents the gains from becoming
2269      very high which could cause some trouble due to the smoothing.
2270   */
2271   b_e = (int)(nrgEst_e - 1);
2272   if (b_e >= 0) {
2273     nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2274              (nrgEst >> 1);
2275     nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
2276 
2277   } else {
2278     nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2279              (FL2FXCONST_DBL(0.5f) >> 1);
2280     nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
2281   }
2282 
2283   /*  A = NrgRef * TmpNoise */
2284   a = fMult(nrgRef, tmpNoise);
2285   a_e = nrgRef_e + tmpNoise_e;
2286 
2287   /*  B = 1 + TmpNoise */
2288   b_e = (int)(tmpNoise_e - 1);
2289   if (b_e >= 0) {
2290     b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2291         (tmpNoise >> 1);
2292     b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
2293   } else {
2294     b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2295         (FL2FXCONST_DBL(0.5f) >> 1);
2296     b_e = 2; /* shift by 1 bit to avoid overflow */
2297   }
2298 
2299   /*  noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
2300   FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
2301 
2302   if (sinePresentFlag) {
2303     /*  C = (1 + TmpNoise) * NrgEst */
2304     c = fMult(b, nrgEst);
2305     c_e = b_e + nrgEst_e;
2306 
2307     /*  gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
2308     FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
2309 
2310     if (sineMapped) {
2311       /*  sineLevel = nrgRef/ (1 + TmpNoise) */
2312       FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
2313     }
2314   } else {
2315     if (noNoiseFlag) {
2316       /*  B = NrgEst */
2317       b = nrgEst;
2318       b_e = nrgEst_e;
2319     } else {
2320       /*  B = NrgEst * (1 + TmpNoise) */
2321       b = fMult(b, nrgEst);
2322       b_e = b_e + nrgEst_e;
2323     }
2324 
2325     /*  gain = nrgRef / B */
2326     INT result_exp = 0;
2327     *ptrNrgGain = fDivNorm(nrgRef, b, &result_exp);
2328     *ptrNrgGain_e = (SCHAR)result_exp + (nrgRef_e - b_e);
2329 
2330     /* There could be a one bit diffs. This is important to compensate,
2331        because later in the code values are compared by exponent only. */
2332     int headroom = CountLeadingBits(*ptrNrgGain);
2333     *ptrNrgGain <<= headroom;
2334     *ptrNrgGain_e -= headroom;
2335   }
2336 }
2337 
2338 /*!
2339   \brief  Calculate "average gain" for the specified subband range.
2340 
2341   This is rather a gain of the average magnitude than the average
2342   of gains!
2343   The result is used as a relative limit for all gains within the
2344   current "limiter band" (a certain frequency range).
2345 */
calcAvgGain(ENV_CALC_NRGS * nrgs,int lowSubband,int highSubband,FIXP_DBL * ptrSumRef,SCHAR * ptrSumRef_e,FIXP_DBL * ptrAvgGain,SCHAR * ptrAvgGain_e)2346 static void calcAvgGain(
2347     ENV_CALC_NRGS *nrgs, int lowSubband, /*!< Begin of the limiter band */
2348     int highSubband,                     /*!< High end of the limiter band */
2349     FIXP_DBL *ptrSumRef, SCHAR *ptrSumRef_e,
2350     FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */
2351     SCHAR *ptrAvgGain_e)  /*!< Resulting overall gain (exponent) */
2352 {
2353   FIXP_DBL *nrgRef =
2354       nrgs->nrgRef; /*!< Reference Energy according to envelope data */
2355   SCHAR *nrgRef_e =
2356       nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
2357                          (exponent) */
2358   FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
2359   SCHAR *nrgEst_e =
2360       nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
2361 
2362   FIXP_DBL sumRef = 1;
2363   FIXP_DBL sumEst = 1;
2364   SCHAR sumRef_e = -FRACT_BITS;
2365   SCHAR sumEst_e = -FRACT_BITS;
2366   int k;
2367 
2368   for (k = lowSubband; k < highSubband; k++) {
2369     /* Add nrgRef[k] to sumRef: */
2370     FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
2371                     &sumRef_e);
2372 
2373     /* Add nrgEst[k] to sumEst: */
2374     FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
2375                     &sumEst_e);
2376   }
2377 
2378   FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
2379                      ptrAvgGain_e);
2380 
2381   *ptrSumRef = sumRef;
2382   *ptrSumRef_e = sumRef_e;
2383 }
2384 
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)2385 static void adjustTimeSlot_EldGrid(
2386     FIXP_DBL *RESTRICT
2387         ptrReal, /*!< Subband samples to be adjusted, real part */
2388     ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2389     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2390     int noSubbands, /*!< Number of QMF subbands */
2391     int scale_change,   /*!< Number of bits to shift adjusted samples */
2392     int noNoiseFlag,    /*!< Flag to suppress noise addition */
2393     int *ptrPhaseIndex, /*!< Start index to random number array */
2394     int scale_diff_low) /*!<  */
2395 
2396 {
2397   int k;
2398   FIXP_DBL signalReal, sbNoise;
2399   int tone_count = 0;
2400 
2401   FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2402   FIXP_DBL *RESTRICT pNoiseLevel =
2403       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2404   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2405 
2406   int phaseIndex = *ptrPhaseIndex;
2407   UCHAR harmIndex = *ptrHarmIndex;
2408 
2409   static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2410 
2411   static const FIXP_DBL harmonicPhaseX[4][2] = {
2412       {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
2413        FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
2414       {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
2415        FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
2416       {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
2417        FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
2418       {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
2419        FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
2420 
2421   const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
2422   const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
2423 
2424   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2425   const FIXP_DBL min_val = -max_val;
2426 
2427   *(ptrReal - 1) = fAddSaturate(
2428       *(ptrReal - 1),
2429       SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
2430                      scale_diff_low, DFRACT_BITS));
2431   FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
2432 
2433   int idx_k = lowSubband & 1;
2434 
2435   for (k = 0; k < noSubbands; k++) {
2436     FIXP_DBL sineLevel_curr = *pSineLevel++;
2437     phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2438 
2439     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2440                  << scale_change;
2441     sbNoise = *pNoiseLevel++;
2442     if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2443       signalReal +=
2444           fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2445     }
2446     signalReal += sineLevel_curr * p_harmonicPhase[0];
2447     signalReal =
2448         fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2449     pSineLevel_prev = sineLevel_curr;
2450     idx_k = !idx_k;
2451     if (k < noSubbands - 1) {
2452       signalReal =
2453           fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
2454     } else /* (k == noSubbands - 1)  */
2455     {
2456       if (k + lowSubband + 1 < 63) {
2457         *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2458       }
2459     }
2460     *ptrReal++ = signalReal;
2461 
2462     if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
2463       if (++tone_count == 16) {
2464         k++;
2465         break;
2466       }
2467     }
2468   }
2469   /* Run again, if previous loop got breaked with tone_count = 16 */
2470   for (; k < noSubbands; k++) {
2471     FIXP_DBL sineLevel_curr = *pSineLevel++;
2472     phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2473 
2474     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2475                  << scale_change;
2476     sbNoise = *pNoiseLevel++;
2477     if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2478       signalReal +=
2479           fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2480     }
2481     signalReal += sineLevel_curr * p_harmonicPhase[0];
2482     *ptrReal++ = signalReal;
2483   }
2484 
2485   *ptrHarmIndex = (harmIndex + 1) & 3;
2486   *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
2487 }
2488 
2489 /*!
2490   \brief   Amplify one timeslot of the signal with the calculated gains
2491            and add the noisefloor.
2492 */
2493 
adjustTimeSlotLC(FIXP_DBL * ptrReal,ENV_CALC_NRGS * nrgs,UCHAR * ptrHarmIndex,int lowSubband,int noSubbands,int scale_change,int noNoiseFlag,int * ptrPhaseIndex)2494 static void adjustTimeSlotLC(
2495     FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */
2496     ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */
2497     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2498     int noSubbands, /*!< Number of QMF subbands */
2499     int scale_change,   /*!< Number of bits to shift adjusted samples */
2500     int noNoiseFlag,    /*!< Flag to suppress noise addition */
2501     int *ptrPhaseIndex) /*!< Start index to random number array */
2502 {
2503   FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2504   FIXP_DBL *pNoiseLevel =
2505       nrgs->noiseLevel;                 /*!< Noise levels of current envelope */
2506   FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2507 
2508   int k;
2509   int index = *ptrPhaseIndex;
2510   UCHAR harmIndex = *ptrHarmIndex;
2511   UCHAR freqInvFlag = (lowSubband & 1);
2512   FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
2513   int tone_count = 0;
2514   int sineSign = 1;
2515   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2516   const FIXP_DBL min_val = -max_val;
2517 
2518 #define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
2519 #define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f))
2520 
2521   /*
2522     First pass for k=0 pulled out of the loop:
2523   */
2524 
2525   index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2526 
2527   /*
2528     The next multiplication constitutes the actual envelope adjustment
2529     of the signal and should be carried out with full accuracy
2530     (supplying #FRACT_BITS valid bits).
2531   */
2532   signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2533                << scale_change;
2534   sineLevel = *pSineLevel++;
2535   sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
2536 
2537   if (sineLevel != FL2FXCONST_DBL(0.0f))
2538     tone_count++;
2539   else if (!noNoiseFlag)
2540     /* Add noisefloor to the amplified signal */
2541     signalReal +=
2542         fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2543 
2544   {
2545     if (!(harmIndex & 0x1)) {
2546       /* harmIndex 0,2 */
2547       signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel;
2548       *ptrReal++ = signalReal;
2549     } else {
2550       /* harmIndex 1,3 in combination with freqInvFlag */
2551       int shift = (int)(scale_change + 1);
2552       shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift)
2553                            : fixMax(-(DFRACT_BITS - 1), shift);
2554 
2555       FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
2556                                    : (fMultDiv2(C1, sineLevel) << (-shift));
2557       FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
2558 
2559       /* save switch and compare operations and reduce to XOR statement */
2560       if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
2561         *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
2562         signalReal -= tmp2;
2563       } else {
2564         *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
2565         signalReal += tmp2;
2566       }
2567       *ptrReal++ = signalReal;
2568       freqInvFlag = !freqInvFlag;
2569     }
2570   }
2571 
2572   pNoiseLevel++;
2573 
2574   if (noSubbands > 2) {
2575     if (!(harmIndex & 0x1)) {
2576       /* harmIndex 0,2 */
2577       if (!harmIndex) {
2578         sineSign = 0;
2579       }
2580 
2581       for (k = noSubbands - 2; k != 0; k--) {
2582         FIXP_DBL sinelevel = *pSineLevel++;
2583         index++;
2584         if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
2585              FL2FXCONST_DBL(0.0f)) &&
2586             !noNoiseFlag) {
2587           /* Add noisefloor to the amplified signal */
2588           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2589           signalReal +=
2590               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2591         }
2592 
2593         /* The next multiplication constitutes the actual envelope adjustment of
2594          * the signal. */
2595         signalReal +=
2596             fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2597             << scale_change;
2598 
2599         pNoiseLevel++;
2600         *ptrReal++ = signalReal;
2601       } /* for ... */
2602     } else {
2603       /* harmIndex 1,3 in combination with freqInvFlag */
2604       if (harmIndex == 1) freqInvFlag = !freqInvFlag;
2605 
2606       for (k = noSubbands - 2; k != 0; k--) {
2607         index++;
2608         /* The next multiplication constitutes the actual envelope adjustment of
2609          * the signal. */
2610         signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2611                      << scale_change;
2612 
2613         if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
2614           tone_count++;
2615         else if (!noNoiseFlag) {
2616           /* Add noisefloor to the amplified signal */
2617           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2618           signalReal +=
2619               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2620         }
2621 
2622         pNoiseLevel++;
2623 
2624         if (tone_count <= 16) {
2625           FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
2626           signalReal += (freqInvFlag) ? (-addSine) : (addSine);
2627         }
2628 
2629         *ptrReal++ = signalReal;
2630         freqInvFlag = !freqInvFlag;
2631       } /* for ... */
2632     }
2633   }
2634 
2635   if (noSubbands > -1) {
2636     index++;
2637     /* The next multiplication constitutes the actual envelope adjustment of the
2638      * signal. */
2639     signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
2640                  << scale_change;
2641     sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
2642     sineLevel = pSineLevel[0];
2643 
2644     if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
2645       tone_count++;
2646     else if (!noNoiseFlag) {
2647       /* Add noisefloor to the amplified signal */
2648       index &= (SBR_NF_NO_RANDOM_VAL - 1);
2649       signalReal = signalReal + fMult(FDK_sbrDecoder_sbr_randomPhase[index][0],
2650                                       pNoiseLevel[0]);
2651     }
2652 
2653     if (!(harmIndex & 0x1)) {
2654       /* harmIndex 0,2 */
2655       *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
2656     } else {
2657       /* harmIndex 1,3 in combination with freqInvFlag */
2658       if (tone_count <= 16) {
2659         if (freqInvFlag) {
2660           *ptrReal++ = signalReal - sineLevelPrev;
2661           if (noSubbands + lowSubband < 63)
2662             *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
2663         } else {
2664           *ptrReal++ = signalReal + sineLevelPrev;
2665           if (noSubbands + lowSubband < 63)
2666             *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
2667         }
2668       } else
2669         *ptrReal = signalReal;
2670     }
2671   }
2672   *ptrHarmIndex = (harmIndex + 1) & 3;
2673   *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2674 }
2675 
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)2676 static void adjustTimeSlotHQ_GainAndNoise(
2677     FIXP_DBL *RESTRICT
2678         ptrReal, /*!< Subband samples to be adjusted, real part */
2679     FIXP_DBL *RESTRICT
2680         ptrImag, /*!< Subband samples to be adjusted, imag part */
2681     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2682     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2683     int noSubbands, /*!< Number of QMF subbands */
2684     int scale_change,         /*!< Number of bits to shift adjusted samples */
2685     FIXP_SGL smooth_ratio,    /*!< Impact of last envelope */
2686     int noNoiseFlag,          /*!< Start index to random number array */
2687     int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2688 {
2689   FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2690   FIXP_DBL *RESTRICT noiseLevel =
2691       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2692   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2693 
2694   FIXP_DBL *RESTRICT filtBuffer =
2695       h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2696   FIXP_DBL *RESTRICT filtBufferNoise =
2697       h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2698   int *RESTRICT ptrPhaseIndex =
2699       &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2700 
2701   int k;
2702   FIXP_DBL signalReal, signalImag;
2703   FIXP_DBL noiseReal, noiseImag;
2704   FIXP_DBL smoothedGain, smoothedNoise;
2705   FIXP_SGL direct_ratio =
2706       /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2707   int index = *ptrPhaseIndex;
2708   int shift;
2709   FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2710   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2711   const FIXP_DBL min_val = -max_val;
2712 
2713   *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2714 
2715   filtBufferNoiseShift +=
2716       1; /* due to later use of fMultDiv2 instead of fMult */
2717   if (filtBufferNoiseShift < 0) {
2718     shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2719   } else {
2720     shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2721     max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2722     min_val_noise = -max_val_noise;
2723   }
2724 
2725   if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2726     for (k = 0; k < noSubbands; k++) {
2727       /*
2728         Smoothing: The old envelope has been bufferd and a certain ratio
2729         of the old gains and noise levels is used.
2730       */
2731       smoothedGain =
2732           fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2733 
2734       if (filtBufferNoiseShift < 0) {
2735         smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2736                         fMult(direct_ratio, noiseLevel[k]);
2737       } else {
2738         smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2739         smoothedNoise =
2740             (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2741             fMult(direct_ratio, noiseLevel[k]);
2742       }
2743 
2744       /*
2745         The next 2 multiplications constitute the actual envelope adjustment
2746         of the signal and should be carried out with full accuracy
2747         (supplying #DFRACT_BITS valid bits).
2748       */
2749       signalReal =
2750           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2751           << scale_change;
2752       signalImag =
2753           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2754           << scale_change;
2755 
2756       index++;
2757 
2758       if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
2759         /* Just the amplified signal is saved */
2760         *ptrReal++ = signalReal;
2761         *ptrImag++ = signalImag;
2762       } else {
2763         /* Add noisefloor to the amplified signal */
2764         index &= (SBR_NF_NO_RANDOM_VAL - 1);
2765         noiseReal =
2766             fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2767         noiseImag =
2768             fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2769         *ptrReal++ = (signalReal + noiseReal);
2770         *ptrImag++ = (signalImag + noiseImag);
2771       }
2772     }
2773   } else {
2774     for (k = 0; k < noSubbands; k++) {
2775       smoothedGain = gain[k];
2776       signalReal =
2777           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2778           << scale_change;
2779       signalImag =
2780           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2781           << scale_change;
2782 
2783       index++;
2784 
2785       if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
2786         /* Add noisefloor to the amplified signal */
2787         smoothedNoise = noiseLevel[k];
2788         index &= (SBR_NF_NO_RANDOM_VAL - 1);
2789         noiseReal =
2790             fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2791         noiseImag =
2792             fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2793 
2794         signalReal += noiseReal;
2795         signalImag += noiseImag;
2796       }
2797       *ptrReal++ = signalReal;
2798       *ptrImag++ = signalImag;
2799     }
2800   }
2801 }
2802 
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)2803 static void adjustTimeSlotHQ_AddHarmonics(
2804     FIXP_DBL *RESTRICT
2805         ptrReal, /*!< Subband samples to be adjusted, real part */
2806     FIXP_DBL *RESTRICT
2807         ptrImag, /*!< Subband samples to be adjusted, imag part */
2808     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2809     int lowSubband,  /*!< Lowest QMF-channel in the currently used SBR range. */
2810     int noSubbands,  /*!< Number of QMF subbands */
2811     int scale_change /*!< Scale mismatch between QMF input and sineLevel
2812                         exponent. */
2813 ) {
2814   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2815   UCHAR *RESTRICT ptrHarmIndex =
2816       &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2817 
2818   int k;
2819   FIXP_DBL signalReal, signalImag;
2820   UCHAR harmIndex = *ptrHarmIndex;
2821   int freqInvFlag = (lowSubband & 1);
2822   FIXP_DBL sineLevel;
2823 
2824   *ptrHarmIndex = (harmIndex + 1) & 3;
2825 
2826   for (k = 0; k < noSubbands; k++) {
2827     sineLevel = pSineLevel[k];
2828     freqInvFlag ^= 1;
2829     if (sineLevel != FL2FXCONST_DBL(0.f)) {
2830       signalReal = ptrReal[k];
2831       signalImag = ptrImag[k];
2832       sineLevel = scaleValue(sineLevel, scale_change);
2833       if (harmIndex & 2) {
2834         /* case 2,3 */
2835         sineLevel = -sineLevel;
2836       }
2837       if (!(harmIndex & 1)) {
2838         /* case 0,2: */
2839         ptrReal[k] = signalReal + sineLevel;
2840       } else {
2841         /* case 1,3 */
2842         if (!freqInvFlag) sineLevel = -sineLevel;
2843         ptrImag[k] = signalImag + sineLevel;
2844       }
2845     }
2846   }
2847 }
2848 
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)2849 static void adjustTimeSlotHQ(
2850     FIXP_DBL *RESTRICT
2851         ptrReal, /*!< Subband samples to be adjusted, real part */
2852     FIXP_DBL *RESTRICT
2853         ptrImag, /*!< Subband samples to be adjusted, imag part */
2854     HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs,
2855     int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */
2856     int noSubbands, /*!< Number of QMF subbands */
2857     int scale_change,         /*!< Number of bits to shift adjusted samples */
2858     FIXP_SGL smooth_ratio,    /*!< Impact of last envelope */
2859     int noNoiseFlag,          /*!< Start index to random number array */
2860     int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */
2861 {
2862   FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2863   FIXP_DBL *RESTRICT noiseLevel =
2864       nrgs->noiseLevel; /*!< Noise levels of current envelope */
2865   FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2866 
2867   FIXP_DBL *RESTRICT filtBuffer =
2868       h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2869   FIXP_DBL *RESTRICT filtBufferNoise =
2870       h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2871   UCHAR *RESTRICT ptrHarmIndex =
2872       &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2873   int *RESTRICT ptrPhaseIndex =
2874       &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2875 
2876   int k;
2877   FIXP_DBL signalReal, signalImag;
2878   FIXP_DBL noiseReal, noiseImag;
2879   FIXP_DBL smoothedGain, smoothedNoise;
2880   FIXP_SGL direct_ratio =
2881       /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2882   int index = *ptrPhaseIndex;
2883   UCHAR harmIndex = *ptrHarmIndex;
2884   int freqInvFlag = (lowSubband & 1);
2885   FIXP_DBL sineLevel;
2886   int shift;
2887   FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2888   const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2889   const FIXP_DBL min_val = -max_val;
2890 
2891   *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2892   *ptrHarmIndex = (harmIndex + 1) & 3;
2893 
2894   /*
2895     Possible optimization:
2896     smooth_ratio and harmIndex stay constant during the loop.
2897     It might be faster to include a separate loop in each path.
2898 
2899     the check for smooth_ratio is now outside the loop and the workload
2900     of the whole function decreased by about 20 %
2901   */
2902 
2903   filtBufferNoiseShift +=
2904       1; /* due to later use of fMultDiv2 instead of fMult */
2905   if (filtBufferNoiseShift < 0) {
2906     shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2907   } else {
2908     shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2909     max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2910     min_val_noise = -max_val_noise;
2911   }
2912 
2913   if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2914     for (k = 0; k < noSubbands; k++) {
2915       /*
2916         Smoothing: The old envelope has been bufferd and a certain ratio
2917         of the old gains and noise levels is used.
2918       */
2919 
2920       smoothedGain =
2921           fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2922 
2923       if (filtBufferNoiseShift < 0) {
2924         smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2925                         fMult(direct_ratio, noiseLevel[k]);
2926       } else {
2927         smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2928         smoothedNoise =
2929             (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2930             fMult(direct_ratio, noiseLevel[k]);
2931       }
2932 
2933       /*
2934         The next 2 multiplications constitute the actual envelope adjustment
2935         of the signal and should be carried out with full accuracy
2936         (supplying #DFRACT_BITS valid bits).
2937       */
2938       signalReal =
2939           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2940           << scale_change;
2941       signalImag =
2942           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2943           << scale_change;
2944 
2945       index++;
2946 
2947       if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2948         sineLevel = pSineLevel[k];
2949 
2950         switch (harmIndex) {
2951           case 0:
2952             *ptrReal++ = (signalReal + sineLevel);
2953             *ptrImag++ = (signalImag);
2954             break;
2955           case 2:
2956             *ptrReal++ = (signalReal - sineLevel);
2957             *ptrImag++ = (signalImag);
2958             break;
2959           case 1:
2960             *ptrReal++ = (signalReal);
2961             if (freqInvFlag)
2962               *ptrImag++ = (signalImag - sineLevel);
2963             else
2964               *ptrImag++ = (signalImag + sineLevel);
2965             break;
2966           case 3:
2967             *ptrReal++ = signalReal;
2968             if (freqInvFlag)
2969               *ptrImag++ = (signalImag + sineLevel);
2970             else
2971               *ptrImag++ = (signalImag - sineLevel);
2972             break;
2973         }
2974       } else {
2975         if (noNoiseFlag) {
2976           /* Just the amplified signal is saved */
2977           *ptrReal++ = (signalReal);
2978           *ptrImag++ = (signalImag);
2979         } else {
2980           /* Add noisefloor to the amplified signal */
2981           index &= (SBR_NF_NO_RANDOM_VAL - 1);
2982           noiseReal =
2983               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2984           noiseImag =
2985               fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2986           *ptrReal++ = (signalReal + noiseReal);
2987           *ptrImag++ = (signalImag + noiseImag);
2988         }
2989       }
2990       freqInvFlag ^= 1;
2991     }
2992 
2993   } else {
2994     for (k = 0; k < noSubbands; k++) {
2995       smoothedGain = gain[k];
2996       signalReal =
2997           fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2998           << scale_change;
2999       signalImag =
3000           fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
3001           << scale_change;
3002 
3003       index++;
3004 
3005       if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
3006         switch (harmIndex) {
3007           case 0:
3008             signalReal += sineLevel;
3009             break;
3010           case 1:
3011             if (freqInvFlag)
3012               signalImag -= sineLevel;
3013             else
3014               signalImag += sineLevel;
3015             break;
3016           case 2:
3017             signalReal -= sineLevel;
3018             break;
3019           case 3:
3020             if (freqInvFlag)
3021               signalImag += sineLevel;
3022             else
3023               signalImag -= sineLevel;
3024             break;
3025         }
3026       } else {
3027         if (noNoiseFlag == 0) {
3028           /* Add noisefloor to the amplified signal */
3029           smoothedNoise = noiseLevel[k];
3030           index &= (SBR_NF_NO_RANDOM_VAL - 1);
3031           noiseReal =
3032               fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
3033           noiseImag =
3034               fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
3035 
3036           signalReal += noiseReal;
3037           signalImag += noiseImag;
3038         }
3039       }
3040       *ptrReal++ = signalReal;
3041       *ptrImag++ = signalImag;
3042 
3043       freqInvFlag ^= 1;
3044     }
3045   }
3046 }
3047 
3048 /*!
3049   \brief   Reset limiter bands.
3050 
3051   Build frequency band table for the gain limiter dependent on
3052   the previously generated transposer patch areas.
3053 
3054   \return  SBRDEC_OK if ok,  SBRDEC_UNSUPPORTED_CONFIG on error
3055 */
3056 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)3057 ResetLimiterBands(
3058     UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */
3059     UCHAR *noLimiterBands,   /*!< Resulting number of limiter band */
3060     UCHAR *freqBandTable,    /*!< Table with possible band borders */
3061     int noFreqBands,         /*!< Number of bands in freqBandTable */
3062     const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */
3063     int noPatches,                 /*!< Number of transposer patches */
3064     int limiterBands, /*!< Selected 'band density' from bitstream */
3065     UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
3066   int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
3067   UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
3068   int patchBorders[MAX_NUM_PATCHES + 1];
3069   int kx, k2;
3070 
3071   int lowSubband = freqBandTable[0];
3072   int highSubband = freqBandTable[noFreqBands];
3073 
3074   /* 1 limiter band. */
3075   if (limiterBands == 0) {
3076     limiterBandTable[0] = 0;
3077     limiterBandTable[1] = highSubband - lowSubband;
3078     nBands = 1;
3079   } else {
3080     if (!sbrPatchingMode && xOverQmf != NULL) {
3081       noPatches = 0;
3082 
3083       if (b41Sbr == 1) {
3084         for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
3085           if (xOverQmf[i] != 0) noPatches++;
3086       } else {
3087         for (i = 1; i < MAX_STRETCH_HBE; i++)
3088           if (xOverQmf[i] != 0) noPatches++;
3089       }
3090       for (i = 0; i < noPatches; i++) {
3091         patchBorders[i] = xOverQmf[i] - lowSubband;
3092       }
3093     } else {
3094       for (i = 0; i < noPatches; i++) {
3095         patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
3096       }
3097     }
3098     patchBorders[i] = highSubband - lowSubband;
3099 
3100     /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
3101     for (k = 0; k <= noFreqBands; k++) {
3102       workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
3103     }
3104     for (k = 1; k < noPatches; k++) {
3105       workLimiterBandTable[noFreqBands + k] = patchBorders[k];
3106     }
3107 
3108     tempNoLim = nBands = noFreqBands + noPatches - 1;
3109     shellsort(workLimiterBandTable, tempNoLim + 1);
3110 
3111     loLimIndex = 0;
3112     hiLimIndex = 1;
3113 
3114     while (hiLimIndex <= tempNoLim) {
3115       FIXP_DBL div_m, oct_m, temp;
3116       INT div_e = 0, oct_e = 0, temp_e = 0;
3117 
3118       k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
3119       kx = workLimiterBandTable[loLimIndex] + lowSubband;
3120 
3121       div_m = fDivNorm(k2, kx, &div_e);
3122 
3123       /* calculate number of octaves */
3124       oct_m = fLog2(div_m, div_e, &oct_e);
3125 
3126       /* multiply with limiterbands per octave    */
3127       /* values 1, 1.2, 2, 3 -> scale factor of 2 */
3128       temp = fMultNorm(
3129           oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands],
3130           &temp_e);
3131 
3132       /* overall scale factor of temp ist addition of scalefactors from log2
3133          calculation, limiter bands scalefactor (2) and limiter bands
3134          multiplication */
3135       temp_e += oct_e + 2;
3136 
3137       /*    div can be a maximum of 64 (k2 = 64 and kx = 1)
3138          -> oct can be a maximum of 6
3139          -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum
3140          factor of 3)
3141          -> we need a scale factor of 5 for comparisson
3142       */
3143       if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) {
3144         if (workLimiterBandTable[hiLimIndex] ==
3145             workLimiterBandTable[loLimIndex]) {
3146           workLimiterBandTable[hiLimIndex] = highSubband;
3147           nBands--;
3148           hiLimIndex++;
3149           continue;
3150         }
3151         isPatchBorder[0] = isPatchBorder[1] = 0;
3152         for (k = 0; k <= noPatches; k++) {
3153           if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
3154             isPatchBorder[1] = 1;
3155             break;
3156           }
3157         }
3158         if (!isPatchBorder[1]) {
3159           workLimiterBandTable[hiLimIndex] = highSubband;
3160           nBands--;
3161           hiLimIndex++;
3162           continue;
3163         }
3164         for (k = 0; k <= noPatches; k++) {
3165           if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
3166             isPatchBorder[0] = 1;
3167             break;
3168           }
3169         }
3170         if (!isPatchBorder[0]) {
3171           workLimiterBandTable[loLimIndex] = highSubband;
3172           nBands--;
3173         }
3174       }
3175       loLimIndex = hiLimIndex;
3176       hiLimIndex++;
3177     }
3178     shellsort(workLimiterBandTable, tempNoLim + 1);
3179 
3180     /* Test if algorithm exceeded maximum allowed limiterbands */
3181     if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
3182       return SBRDEC_UNSUPPORTED_CONFIG;
3183     }
3184 
3185     /* Restrict maximum value of limiter band table */
3186     if (workLimiterBandTable[tempNoLim] > highSubband) {
3187       return SBRDEC_UNSUPPORTED_CONFIG;
3188     }
3189 
3190     /* Copy limiterbands from working buffer into final destination */
3191     for (k = 0; k <= nBands; k++) {
3192       limiterBandTable[k] = workLimiterBandTable[k];
3193     }
3194   }
3195   *noLimiterBands = nBands;
3196 
3197   return SBRDEC_OK;
3198 }
3199