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