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