Coverage Report

Created: 2025-08-26 06:50

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