Coverage Report

Created: 2025-11-11 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libSBRdec/src/env_calc.cpp
Line
Count
Source
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.6M
#define MAX_SFB_NRG_HEADROOM (1)
155
23.9M
#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
358k
{
259
358k
  int i;
260
358k
  int bitcount = 31;
261
358k
  ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0};
262
358k
  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
358k
  FDKmemset(sineMapped, 32,
281
358k
            MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */
282
358k
  FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG));
283
4.08M
  for (i = 0; i < nSfb; i++) {
284
3.72M
    ULONG maskSfb =
285
3.72M
        1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */
286
287
3.72M
    if (*curFlags & maskSfb) {          /* There is a sine in this band */
288
46.3k
      const int lsb = freqBandTable[0]; /* start of sbr range */
289
      /* qmf band to which sine should be added */
290
46.3k
      const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1;
291
46.3k
      const int qmfBandDiv32 = qmfBand >> 5;
292
46.3k
      const int maskQmfBand =
293
46.3k
          1 << (qmfBand &
294
46.3k
                31); /* mask to extract harmonic flag from prevFlags */
295
296
      /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */
297
46.3k
      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
46.3k
      sineMapped[qmfBand - lsb] =
305
46.3k
          (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv;
306
46.3k
      if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) {
307
38.2k
        harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand;
308
38.2k
      }
309
46.3k
    }
310
311
3.72M
    if (bitcount-- == 0) {
312
8.25k
      bitcount = 31;
313
8.25k
      curFlags++;
314
8.25k
    }
315
3.72M
  }
316
358k
  FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands,
317
358k
            sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
318
358k
}
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
117k
{
344
  /* Reset the output vector first */
345
117k
  FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */
346
347
117k
  if (trailingSbrFrame) {
348
    /* restore sineMapped[] of previous frame */
349
90.9k
    int i;
350
90.9k
    const int lsb = freqBandTable[0];
351
90.9k
    const int usb = freqBandTable[nSfb];
352
2.00M
    for (i = lsb; i < usb; i++) {
353
1.91M
      const int qmfBandDiv32 = i >> 5;
354
1.91M
      const int maskQmfBand =
355
1.91M
          1 << (i & 31); /* mask to extract harmonic flag from prevFlags */
356
357
      /* Two cases need to be distinguished ... */
358
1.91M
      if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) {
359
        /* the sine mapping already started last PVC frame -> seamlessly
360
         * continue */
361
982
        sineMapped[i - lsb] = 0;
362
1.91M
      } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) {
363
        /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts
364
         * in this frame */
365
1.32k
        sineMapped[i - lsb] =
366
1.32k
            *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots
367
                                                   ahead of last frame now */
368
1.32k
      }
369
1.91M
    }
370
90.9k
  }
371
117k
  *sinusoidalPosPrev = sinusoidalPos;
372
117k
}
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
46.5k
{
385
46.5k
  FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
386
46.5k
  SCHAR *nrgGain_e =
387
46.5k
      nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
388
46.5k
  FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
389
46.5k
  SCHAR *nrgEst_e =
390
46.5k
      nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
391
46.5k
  int grouping = 0, index = 0, noGroups, k;
392
46.5k
  int groupVector[MAX_FREQ_COEFFS];
393
394
  /* Calculate grouping*/
395
650k
  for (k = 0; k < noSubbands - 1; k++) {
396
603k
    if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) {
397
61.7k
      if (grouping == 0) {
398
38.5k
        groupVector[index++] = k;
399
38.5k
        grouping = 1;
400
38.5k
      } else {
401
23.2k
        if (groupVector[index - 1] + 3 == k) {
402
0
          groupVector[index++] = k + 1;
403
0
          grouping = 0;
404
0
        }
405
23.2k
      }
406
542k
    } else {
407
542k
      if (grouping) {
408
30.4k
        if (useAliasReduction[k])
409
30.1k
          groupVector[index++] = k + 1;
410
327
        else
411
327
          groupVector[index++] = k;
412
30.4k
        grouping = 0;
413
30.4k
      }
414
542k
    }
415
603k
  }
416
417
46.5k
  if (grouping) {
418
8.09k
    groupVector[index++] = noSubbands;
419
8.09k
  }
420
46.5k
  noGroups = index >> 1;
421
422
  /*Calculate new gain*/
423
85.0k
  for (int group = 0; group < noGroups; group++) {
424
38.5k
    FIXP_DBL nrgOrig = FL2FXCONST_DBL(
425
38.5k
        0.0f); /* Original signal energy in current group of bands */
426
38.5k
    SCHAR nrgOrig_e = 0;
427
38.5k
    FIXP_DBL nrgAmp = FL2FXCONST_DBL(
428
38.5k
        0.0f); /* Amplified signal energy in group (using current gains) */
429
38.5k
    SCHAR nrgAmp_e = 0;
430
38.5k
    FIXP_DBL nrgMod = FL2FXCONST_DBL(
431
38.5k
        0.0f); /* Signal energy in group when applying modified gains */
432
38.5k
    SCHAR nrgMod_e = 0;
433
38.5k
    FIXP_DBL groupGain; /* Total energy gain in group */
434
38.5k
    SCHAR groupGain_e;
435
38.5k
    FIXP_DBL compensation; /* Compensation factor for the energy change when
436
                              applying modified gains */
437
38.5k
    SCHAR compensation_e;
438
439
38.5k
    int startGroup = groupVector[2 * group];
440
38.5k
    int stopGroup = groupVector[2 * group + 1];
441
442
    /* Calculate total energy in group before and after amplification with
443
     * current gains: */
444
138k
    for (k = startGroup; k < stopGroup; k++) {
445
      /* Get original band energy */
446
100k
      FIXP_DBL tmp = nrgEst[k];
447
100k
      SCHAR tmp_e = nrgEst_e[k];
448
449
100k
      FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
450
451
      /* Multiply band energy with current gain */
452
100k
      tmp = fMult(tmp, nrgGain[k]);
453
100k
      tmp_e = tmp_e + nrgGain_e[k];
454
455
100k
      FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
456
100k
    }
457
458
    /* Calculate total energy gain in group */
459
38.5k
    FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain,
460
38.5k
                       &groupGain_e);
461
462
138k
    for (k = startGroup; k < stopGroup; k++) {
463
100k
      FIXP_DBL tmp;
464
100k
      SCHAR tmp_e;
465
466
100k
      FIXP_DBL alpha = degreeAlias[k];
467
100k
      if (k < noSubbands - 1) {
468
91.9k
        if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1];
469
91.9k
      }
470
471
      /* Modify gain depending on the degree of aliasing */
472
100k
      FDK_add_MantExp(
473
100k
          fMult(alpha, groupGain), groupGain_e,
474
100k
          fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,
475
100k
                nrgGain[k]),
476
100k
          nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]);
477
478
      /* Apply modified gain to original energy */
479
100k
      tmp = fMult(nrgGain[k], nrgEst[k]);
480
100k
      tmp_e = nrgGain_e[k] + nrgEst_e[k];
481
482
      /* Accumulate energy with modified gains applied */
483
100k
      FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e);
484
100k
    }
485
486
    /* Calculate compensation factor to retain the energy of the amplified
487
     * signal */
488
38.5k
    FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation,
489
38.5k
                       &compensation_e);
490
491
    /* Apply compensation factor to all gains of the group */
492
138k
    for (k = startGroup; k < stopGroup; k++) {
493
100k
      nrgGain[k] = fMult(nrgGain[k], compensation);
494
100k
      nrgGain_e[k] = nrgGain_e[k] + compensation_e;
495
100k
    }
496
38.5k
  }
497
46.5k
}
498
499
46.7M
#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
42.2k
                            const UCHAR gamma_idx) {
515
42.2k
  int highSubband = lowSubband + nbSubband;
516
42.2k
  FIXP_DBL *subsample_power_high, *subsample_power_low;
517
42.2k
  SCHAR *subsample_power_high_sf, *subsample_power_low_sf;
518
42.2k
  FIXP_DBL total_power_high = (FIXP_DBL)0;
519
42.2k
  FIXP_DBL total_power_low = (FIXP_DBL)0;
520
42.2k
  FIXP_DBL *gain;
521
42.2k
  int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
522
523
  /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */
524
42.2k
  int gamma_sf =
525
42.2k
      (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */
526
527
42.2k
  int nbSubsample = stopPos - startPos;
528
42.2k
  int i, j;
529
530
42.2k
  C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1);
531
42.2k
  subsample_power_high = pTmp->subsample_power_high;
532
42.2k
  subsample_power_low = pTmp->subsample_power_low;
533
42.2k
  subsample_power_high_sf = pTmp->subsample_power_high_sf;
534
42.2k
  subsample_power_low_sf = pTmp->subsample_power_low_sf;
535
42.2k
  gain = pTmp->gain;
536
537
42.2k
  if (gamma_idx > 0) {
538
13.6k
    int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample);
539
13.6k
    int total_power_low_sf = 1 - DFRACT_BITS;
540
13.6k
    int total_power_high_sf = 1 - DFRACT_BITS;
541
542
574k
    for (i = 0; i < nbSubsample; ++i) {
543
561k
      FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
544
561k
      FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
545
561k
      FIXP_DBL maxVal = (FIXP_DBL)0;
546
547
561k
      int ts = startPos + i;
548
549
561k
      int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale
550
561k
                                   : sbrScaleFactor->lb_scale;
551
561k
      low_sf = 15 - low_sf;
552
553
10.0M
      for (j = 0; j < lowSubband; ++j) {
554
9.47M
        bufferImag[j] = qmfImag[startPos + i][j];
555
9.47M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
556
9.47M
                             ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
557
9.47M
        bufferReal[j] = qmfReal[startPos + i][j];
558
9.47M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
559
9.47M
                             ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
560
9.47M
      }
561
562
561k
      subsample_power_low[i] = (FIXP_DBL)0;
563
561k
      subsample_power_low_sf[i] = 0;
564
565
561k
      if (maxVal != FL2FXCONST_DBL(0.f)) {
566
        /* multiply first, then shift for safe summation */
567
343k
        int preShift = 1 - CntLeadingZeros(maxVal);
568
343k
        int postShift = 32 - fNormz((FIXP_DBL)lowSubband);
569
570
        /* reduce preShift because otherwise we risk to square -1.f */
571
343k
        if (preShift != 0) preShift++;
572
573
343k
        subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1;
574
575
343k
        scaleValues(bufferReal, lowSubband, -preShift);
576
343k
        scaleValues(bufferImag, lowSubband, -preShift);
577
6.18M
        for (j = 0; j < lowSubband; ++j) {
578
5.84M
          FIXP_DBL addme;
579
5.84M
          addme = fPow2Div2(bufferReal[j]);
580
5.84M
          subsample_power_low[i] += addme >> postShift;
581
5.84M
          addme = fPow2Div2(bufferImag[j]);
582
5.84M
          subsample_power_low[i] += addme >> postShift;
583
5.84M
        }
584
343k
      }
585
586
      /* now get high */
587
588
561k
      maxVal = (FIXP_DBL)0;
589
590
561k
      int high_sf = exp[(ts < 16 * RATE) ? 0 : 1];
591
592
12.8M
      for (j = lowSubband; j < highSubband; ++j) {
593
12.3M
        bufferImag[j] = qmfImag[startPos + i][j];
594
12.3M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
595
12.3M
                             ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
596
12.3M
        bufferReal[j] = qmfReal[startPos + i][j];
597
12.3M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
598
12.3M
                             ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
599
12.3M
      }
600
601
561k
      subsample_power_high[i] = (FIXP_DBL)0;
602
561k
      subsample_power_high_sf[i] = 0;
603
604
561k
      if (maxVal != FL2FXCONST_DBL(0.f)) {
605
511k
        int preShift = 1 - CntLeadingZeros(maxVal);
606
        /* reduce preShift because otherwise we risk to square -1.f */
607
511k
        if (preShift != 0) preShift++;
608
609
511k
        int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband));
610
511k
        subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1;
611
612
511k
        scaleValues(&bufferReal[lowSubband], highSubband - lowSubband,
613
511k
                    -preShift);
614
511k
        scaleValues(&bufferImag[lowSubband], highSubband - lowSubband,
615
511k
                    -preShift);
616
10.7M
        for (j = lowSubband; j < highSubband; j++) {
617
10.2M
          subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift;
618
10.2M
          subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift;
619
10.2M
        }
620
511k
      }
621
622
      /* sum all together */
623
561k
      FIXP_DBL new_summand = subsample_power_low[i];
624
561k
      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
561k
      if (new_summand_sf > total_power_low_sf) {
628
33.0k
        int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf);
629
33.0k
        total_power_low >>= diff;
630
33.0k
        total_power_low_sf = new_summand_sf;
631
528k
      } else if (new_summand_sf < total_power_low_sf) {
632
165k
        new_summand >>=
633
165k
            fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf);
634
165k
      }
635
636
561k
      total_power_low += (new_summand >> preShift2);
637
638
561k
      new_summand = subsample_power_high[i];
639
561k
      new_summand_sf = subsample_power_high_sf[i];
640
561k
      if (new_summand_sf > total_power_high_sf) {
641
29.6k
        total_power_high >>=
642
29.6k
            fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf);
643
29.6k
        total_power_high_sf = new_summand_sf;
644
531k
      } else if (new_summand_sf < total_power_high_sf) {
645
217k
        new_summand >>=
646
217k
            fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf);
647
217k
      }
648
649
561k
      total_power_high += (new_summand >> preShift2);
650
561k
    }
651
652
13.6k
    total_power_low_sf += preShift2;
653
13.6k
    total_power_high_sf += preShift2;
654
655
    /* gain[i] = e_LOW[i] */
656
574k
    for (i = 0; i < nbSubsample; ++i) {
657
561k
      int sf2;
658
561k
      FIXP_DBL mult =
659
561k
          fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2);
660
561k
      int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2;
661
662
561k
      if (total_power_low != FIXP_DBL(0)) {
663
409k
        gain[i] = fDivNorm(mult, total_power_low, &sf2);
664
409k
        gain_sf[i] = mult_sf - total_power_low_sf + sf2;
665
409k
        gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
666
409k
        if (gain_sf[i] < 0) {
667
137k
          gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]);
668
137k
          gain_sf[i] = 0;
669
137k
        }
670
409k
      } else {
671
152k
        if (mult == FIXP_DBL(0)) {
672
151k
          gain[i] = FIXP_DBL(0);
673
151k
          gain_sf[i] = 0;
674
151k
        } else {
675
912
          gain[i] = (FIXP_DBL)MAXVAL_DBL;
676
912
          gain_sf[i] = 0;
677
912
        }
678
152k
      }
679
561k
    }
680
681
13.6k
    FIXP_DBL total_power_high_after = (FIXP_DBL)0;
682
13.6k
    int total_power_high_after_sf = 1 - DFRACT_BITS;
683
684
    /* gain[i] = g_inter[i] */
685
574k
    for (i = 0; i < nbSubsample; ++i) {
686
      /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
687
561k
      FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
688
561k
                     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
561k
      FIXP_DBL mult = (gain[i] - one) >> 1;
693
561k
      int mult_sf = gain_sf[i] + gamma_sf;
694
695
561k
      one = FL2FXCONST_DBL(0.5f) >> mult_sf;
696
561k
      gain[i] = one + mult;
697
561k
      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
561k
      FIXP_DBL gain_pow2;
702
561k
      int gain_pow2_sf;
703
704
561k
      if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
705
341k
        gain[i] = FL2FXCONST_DBL(0.8f);
706
341k
        gain_sf[i] = -2;
707
341k
        gain_pow2 = FL2FXCONST_DBL(0.64f);
708
341k
        gain_pow2_sf = -4;
709
341k
      } else {
710
        /* this upscaling seems quite important */
711
219k
        int r = CountLeadingBits(gain[i]);
712
219k
        gain[i] <<= r;
713
219k
        gain_sf[i] -= r;
714
715
219k
        gain_pow2 = fPow2(gain[i]);
716
219k
        gain_pow2_sf = gain_sf[i] << 1;
717
219k
      }
718
719
561k
      int room;
720
561k
      subsample_power_high[i] =
721
561k
          fMultNorm(subsample_power_high[i], gain_pow2, &room);
722
561k
      subsample_power_high_sf[i] =
723
561k
          subsample_power_high_sf[i] + gain_pow2_sf + room;
724
725
561k
      int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
726
561k
      if (new_summand_sf > total_power_high_after_sf) {
727
47.7k
        total_power_high_after >>=
728
47.7k
            fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
729
47.7k
        total_power_high_after_sf = new_summand_sf;
730
513k
      } else if (new_summand_sf < total_power_high_after_sf) {
731
338k
        subsample_power_high[i] >>=
732
338k
            fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
733
338k
      }
734
561k
      total_power_high_after += subsample_power_high[i] >> preShift2;
735
561k
    }
736
737
13.6k
    total_power_high_after_sf += preShift2;
738
739
13.6k
    int sf2 = 0;
740
13.6k
    FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
741
13.6k
    int gain_adj_2_sf = 1;
742
743
13.6k
    if ((total_power_high != (FIXP_DBL)0) &&
744
12.2k
        (total_power_high_after != (FIXP_DBL)0)) {
745
12.2k
      gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
746
12.2k
      gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
747
12.2k
    }
748
749
13.6k
    FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
750
13.6k
    int gain_adj_sf = gain_adj_2_sf;
751
752
574k
    for (i = 0; i < nbSubsample; ++i) {
753
561k
      int gain_e = fMax(
754
561k
          fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1),
755
561k
          -(DFRACT_BITS - 1));
756
561k
      FIXP_DBL gain_final = fMult(gain[i], gain_adj);
757
561k
      gain_final = scaleValueSaturate(gain_final, gain_e);
758
759
12.8M
      for (j = lowSubband; j < highSubband; j++) {
760
12.3M
        qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final);
761
12.3M
        qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final);
762
12.3M
      }
763
561k
    }
764
28.6k
  } 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
893k
    for (i = 0; i < nbSubsample; ++i) {
768
23.9M
      for (j = lowSubband; j < highSubband; j++) {
769
23.1M
        qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
770
23.1M
        qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
771
23.1M
      }
772
864k
    }
773
28.6k
  }
774
42.2k
  C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
775
42.2k
}
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
358k
    const UINT flags, const int frameErrorFlag) {
877
358k
  int c, i, i_stop, j, envNoise = 0;
878
358k
  UCHAR *borders = hFrameData->frameInfo.borders;
879
358k
  UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
880
358k
  int pvc_mode = pPvcDynamicData->pvc_mode;
881
358k
  int first_start =
882
358k
      ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
883
358k
  FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
884
358k
  HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
885
358k
  UCHAR **pFreqBandTable = hFreq->freqBandTable;
886
358k
  UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
887
888
358k
  int lowSubband = hFreq->lowSubband;
889
358k
  int highSubband = hFreq->highSubband;
890
358k
  int noSubbands = highSubband - lowSubband;
891
892
  /* old high subband before headerchange
893
     we asume no headerchange here        */
894
358k
  int ov_highSubband = hFreq->highSubband;
895
896
358k
  int noNoiseBands = hFreq->nNfb;
897
358k
  UCHAR *noSubFrameBands = hFreq->nSfb;
898
358k
  int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
899
900
358k
  SCHAR sineMapped[MAX_FREQ_COEFFS];
901
358k
  SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
902
358k
  SCHAR adj_e = 0;
903
358k
  SCHAR output_e;
904
358k
  SCHAR final_e = 0;
905
  /* inter-TES is active in one or more envelopes of the current SBR frame */
906
358k
  const int iTES_enable = hFrameData->iTESactive;
907
358k
  const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
908
358k
  SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
909
910
358k
  UCHAR smooth_length = 0;
911
912
358k
  FIXP_SGL *pIenv = hFrameData->iEnvelope;
913
914
358k
  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
358k
  if (hFreq->highSubband < hFreq->ov_highSubband) {
921
24.3k
    ov_highSubband = hFreq->ov_highSubband;
922
24.3k
  }
923
924
358k
  if (pvc_mode > 0) {
925
117k
    if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
926
      /* noise envelope of previous frame is trailing into current PVC frame */
927
90.9k
      envNoise = -1;
928
90.9k
      noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
929
90.9k
      noNoiseBands = h_sbr_cal_env->prevNNfb;
930
90.9k
      noSubFrameBands = h_sbr_cal_env->prevNSfb;
931
90.9k
      lowSubband = h_sbr_cal_env->prevLoSubband;
932
90.9k
      highSubband = h_sbr_cal_env->prevHiSubband;
933
934
90.9k
      noSubbands = highSubband - lowSubband;
935
90.9k
      ov_highSubband = highSubband;
936
90.9k
      if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
937
3.80k
        ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
938
3.80k
      }
939
940
90.9k
      pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
941
90.9k
      pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
942
90.9k
      pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
943
90.9k
    }
944
945
117k
    mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
946
117k
                    h_sbr_cal_env->harmFlagsPrev,
947
117k
                    h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
948
117k
                    hFrameData->sinusoidal_position,
949
117k
                    &h_sbr_cal_env->sinusoidal_positionPrev,
950
117k
                    (borders[0] > bordersPvc[0]) ? 1 : 0);
951
240k
  } else {
952
    /*
953
      Extract sine flags for all QMF bands
954
    */
955
240k
    mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
956
240k
                 hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
957
240k
                 h_sbr_cal_env->harmFlagsPrevActive,
958
240k
                 hFrameData->frameInfo.tranEnv, sineMapped);
959
240k
  }
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
358k
  if (!useLP)
969
318k
    adj_e = h_sbr_cal_env->filtBufferNoise_e -
970
318k
            getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
971
318k
            (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
358k
  if (pvc_mode > 0) {
978
117k
    INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
979
980
    /* Energy -> magnitude (sqrt halfens exponent) */
981
117k
    maxSfbNrg_e =
982
117k
        (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
117k
    maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
992
993
117k
    adj_e = maxSfbNrg_e;
994
    // final_e should not exist for PVC fixfix framing
995
240k
  } else {
996
535k
    for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
997
294k
      INT maxSfbNrg_e =
998
294k
          -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
999
1000
      /* Fetch frequency resolution for current envelope: */
1001
3.13M
      for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
1002
2.83M
        maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
1003
2.83M
      }
1004
294k
      maxSfbNrg_e -= NRG_EXP_OFFSET;
1005
1006
      /* Energy -> magnitude (sqrt halfens exponent) */
1007
294k
      maxSfbNrg_e =
1008
294k
          (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
294k
      maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
1018
1019
294k
      if (borders[i] < hHeaderData->numberTimeSlots)
1020
        /* This envelope affects timeslots that belong to the output frame */
1021
280k
        adj_e = fMax(maxSfbNrg_e, adj_e);
1022
1023
294k
      if (borders[i + 1] > hHeaderData->numberTimeSlots)
1024
        /* This envelope affects timeslots after the output frame */
1025
24.9k
        final_e = fMax(maxSfbNrg_e, final_e);
1026
294k
    }
1027
240k
  }
1028
  /*
1029
    Calculate adjustment factors and apply them for every envelope.
1030
  */
1031
358k
  pIenv = hFrameData->iEnvelope;
1032
1033
358k
  if (pvc_mode > 0) {
1034
    /* iterate over SBR time slots starting with bordersPvc[i] */
1035
117k
    i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
1036
                          PVC */
1037
117k
    i_stop = PVC_NTIMESLOT;
1038
117k
    FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
1039
240k
  } else {
1040
    /* iterate over SBR envelopes starting with 0 */
1041
240k
    i = 0;
1042
240k
    i_stop = hFrameData->frameInfo.nEnvelopes;
1043
240k
  }
1044
2.53M
  for (; i < i_stop; i++) {
1045
2.17M
    int k, noNoiseFlag;
1046
2.17M
    SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
1047
2.17M
    C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
1048
1049
    /*
1050
      Helper variables.
1051
    */
1052
2.17M
    int start_pos, stop_pos, freq_res;
1053
2.17M
    if (pvc_mode > 0) {
1054
1.88M
      start_pos =
1055
1.88M
          hHeaderData->timeStep *
1056
1.88M
          i; /* Start-position in time (subband sample) for current envelope. */
1057
1.88M
      stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
1058
                                                     (subband sample) for
1059
                                                     current envelope. */
1060
1.88M
      freq_res =
1061
1.88M
          hFrameData->frameInfo
1062
1.88M
              .freqRes[0]; /* Frequency resolution for current envelope. */
1063
1.88M
      FDK_ASSERT(
1064
1.88M
          freq_res ==
1065
1.88M
          hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
1066
1.88M
    } else {
1067
294k
      start_pos = hHeaderData->timeStep *
1068
294k
                  borders[i]; /* Start-position in time (subband sample) for
1069
                                 current envelope. */
1070
294k
      stop_pos = hHeaderData->timeStep *
1071
294k
                 borders[i + 1]; /* Stop-position in time (subband sample) for
1072
                                    current envelope. */
1073
294k
      freq_res =
1074
294k
          hFrameData->frameInfo
1075
294k
              .freqRes[i]; /* Frequency resolution for current envelope. */
1076
294k
    }
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.17M
    FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
1084
1085
2.17M
    if (pvc_mode > 0) {
1086
      /* get predicted energy values from PVC module */
1087
1.88M
      expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
1088
1.88M
                    pNrgs->nrgRef_e);
1089
1090
1.88M
      if (i == borders[0]) {
1091
117k
        mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
1092
117k
                     hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
1093
117k
                     h_sbr_cal_env->harmFlagsPrevActive,
1094
117k
                     hFrameData->sinusoidal_position, sineMapped);
1095
117k
      }
1096
1097
1.88M
      if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1098
191k
        if (envNoise >= 0) {
1099
100k
          noiseLevels += noNoiseBands; /* The noise floor data is stored in a
1100
                                          row [noiseFloor1 noiseFloor2...].*/
1101
100k
        } else {
1102
          /* leave trailing noise envelope of past frame */
1103
90.9k
          noNoiseBands = hFreq->nNfb;
1104
90.9k
          noSubFrameBands = hFreq->nSfb;
1105
90.9k
          noiseLevels = hFrameData->sbrNoiseFloorLevel;
1106
1107
90.9k
          lowSubband = hFreq->lowSubband;
1108
90.9k
          highSubband = hFreq->highSubband;
1109
1110
90.9k
          noSubbands = highSubband - lowSubband;
1111
90.9k
          ov_highSubband = highSubband;
1112
90.9k
          if (highSubband < hFreq->ov_highSubband) {
1113
3.85k
            ov_highSubband = hFreq->ov_highSubband;
1114
3.85k
          }
1115
1116
90.9k
          pFreqBandTable[0] = hFreq->freqBandTableLo;
1117
90.9k
          pFreqBandTable[1] = hFreq->freqBandTableHi;
1118
90.9k
          pFreqBandTableNoise = hFreq->freqBandTableNoise;
1119
90.9k
        }
1120
191k
        envNoise++;
1121
191k
      }
1122
1.88M
    } 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
294k
      if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1127
47.9k
        noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
1128
                                        [noiseFloor1 noiseFloor2...].*/
1129
47.9k
        envNoise++;
1130
47.9k
      }
1131
294k
    }
1132
2.17M
    if (i == hFrameData->frameInfo.tranEnv ||
1133
2.17M
        i == h_sbr_cal_env->prevTranEnv) /* attack */
1134
3.84k
    {
1135
3.84k
      noNoiseFlag = 1;
1136
3.84k
      if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
1137
2.17M
    } else {
1138
2.17M
      noNoiseFlag = 0;
1139
2.17M
      if (!useLP)
1140
2.13M
        smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
1141
2.13M
                        << 2; /* can become either 0 or 4 */
1142
2.17M
    }
1143
1144
    /*
1145
      Energy estimation in transposed highband.
1146
    */
1147
2.17M
    if (hHeaderData->bs_data.interpolFreq)
1148
2.14M
      calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1149
2.14M
                        lowSubband, highSubband, start_pos, stop_pos, input_e,
1150
2.14M
                        pNrgs->nrgEst, pNrgs->nrgEst_e);
1151
36.4k
    else
1152
36.4k
      calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1153
36.4k
                    noSubFrameBands[freq_res], pFreqBandTable[freq_res],
1154
36.4k
                    start_pos, stop_pos, input_e, pNrgs->nrgEst,
1155
36.4k
                    pNrgs->nrgEst_e);
1156
1157
    /*
1158
      Calculate subband gains
1159
    */
1160
2.17M
    {
1161
2.17M
      UCHAR *table = pFreqBandTable[freq_res];
1162
2.17M
      UCHAR *pUiNoise =
1163
2.17M
          &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
1164
                                      band. */
1165
1166
2.17M
      FIXP_SGL *pNoiseLevels = noiseLevels;
1167
1168
2.17M
      FIXP_DBL tmpNoise =
1169
2.17M
          FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1170
2.17M
      SCHAR tmpNoise_e =
1171
2.17M
          (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1172
1173
2.17M
      int cc = 0;
1174
2.17M
      c = 0;
1175
2.17M
      if (pvc_mode > 0) {
1176
9.61M
        for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1177
7.73M
          UCHAR sinePresentFlag = 0;
1178
7.73M
          int li = table[j];
1179
7.73M
          int ui = table[j + 1];
1180
1181
52.6M
          for (k = li; k < ui; k++) {
1182
44.9M
            sinePresentFlag |= (i >= sineMapped[cc]);
1183
44.9M
            cc++;
1184
44.9M
          }
1185
1186
52.6M
          for (k = li; k < ui; k++) {
1187
44.9M
            FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
1188
44.9M
            SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
1189
1190
44.9M
            if (k >= *pUiNoise) {
1191
2.63M
              tmpNoise =
1192
2.63M
                  FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1193
2.63M
              tmpNoise_e =
1194
2.63M
                  (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1195
1196
2.63M
              pUiNoise++;
1197
2.63M
            }
1198
1199
44.9M
            FDK_ASSERT(k >= lowSubband);
1200
1201
44.9M
            if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1202
1203
44.9M
            pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1204
44.9M
            pNrgs->nrgSine_e[c] = 0;
1205
1206
44.9M
            calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1207
44.9M
                            sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1208
1209
44.9M
            c++;
1210
44.9M
          }
1211
7.73M
        }
1212
1.88M
      } else {
1213
3.13M
        for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1214
2.83M
          FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
1215
2.83M
          SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
1216
1217
2.83M
          UCHAR sinePresentFlag = 0;
1218
2.83M
          int li = table[j];
1219
2.83M
          int ui = table[j + 1];
1220
1221
10.4M
          for (k = li; k < ui; k++) {
1222
7.64M
            sinePresentFlag |= (i >= sineMapped[cc]);
1223
7.64M
            cc++;
1224
7.64M
          }
1225
1226
10.4M
          for (k = li; k < ui; k++) {
1227
7.64M
            if (k >= *pUiNoise) {
1228
466k
              tmpNoise =
1229
466k
                  FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1230
466k
              tmpNoise_e =
1231
466k
                  (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1232
1233
466k
              pUiNoise++;
1234
466k
            }
1235
1236
7.64M
            FDK_ASSERT(k >= lowSubband);
1237
1238
7.64M
            if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1239
1240
7.64M
            pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1241
7.64M
            pNrgs->nrgSine_e[c] = 0;
1242
1243
7.64M
            calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1244
7.64M
                            sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1245
1246
7.64M
            pNrgs->nrgRef[c] = refNrg;
1247
7.64M
            pNrgs->nrgRef_e[c] = refNrg_e;
1248
1249
7.64M
            c++;
1250
7.64M
          }
1251
2.83M
          pIenv++;
1252
2.83M
        }
1253
294k
      }
1254
2.17M
    }
1255
1256
    /*
1257
      Noise limiting
1258
    */
1259
1260
9.65M
    for (c = 0; c < hFreq->noLimiterBands; c++) {
1261
7.47M
      FIXP_DBL sumRef, boostGain, maxGain;
1262
7.47M
      FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1263
7.47M
      SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
1264
7.47M
      int maxGainLimGainSum_e = 0;
1265
1266
7.47M
      calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
1267
7.47M
                  hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
1268
7.47M
                  &maxGain_e);
1269
1270
      /* Multiply maxGain with limiterGain: */
1271
7.47M
      maxGain = fMult(
1272
7.47M
          maxGain,
1273
7.47M
          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.47M
      maxGainLimGainSum_e =
1281
7.47M
          maxGain_e +
1282
7.47M
          FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
1283
7.47M
      maxGain_e =
1284
7.47M
          (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
1285
1286
      /* Scale mantissa of MaxGain into range between 0.5 and 1: */
1287
7.47M
      if (maxGain == FL2FXCONST_DBL(0.0f))
1288
134
        maxGain_e = -FRACT_BITS;
1289
7.47M
      else {
1290
7.47M
        SCHAR charTemp = CountLeadingBits(maxGain);
1291
7.47M
        maxGain_e -= charTemp;
1292
7.47M
        maxGain <<= (int)charTemp;
1293
7.47M
      }
1294
1295
7.47M
      if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
1296
1.72M
        maxGain = FL2FXCONST_DBL(0.5f);
1297
1.72M
        maxGain_e = maxGainLimit_e;
1298
1.72M
      }
1299
1300
      /* Every subband gain is compared to the scaled "average gain"
1301
         and limited if necessary: */
1302
60.0M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1303
52.6M
           k++) {
1304
52.6M
        if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
1305
36.8M
            (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
1306
18.7M
          FIXP_DBL noiseAmp;
1307
18.7M
          SCHAR noiseAmp_e;
1308
1309
18.7M
          FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
1310
18.7M
                             pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
1311
18.7M
          pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
1312
18.7M
          pNrgs->noiseLevel_e[k] += noiseAmp_e;
1313
18.7M
          pNrgs->nrgGain[k] = maxGain;
1314
18.7M
          pNrgs->nrgGain_e[k] = maxGain_e;
1315
18.7M
        }
1316
52.6M
      }
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.0M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1325
52.6M
           k++) {
1326
        /* 1.a  Add energy of adjusted signal (using preliminary gain) */
1327
52.6M
        FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
1328
52.6M
        SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
1329
52.6M
        FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
1330
1331
        /* 1.b  Add sine energy (if present) */
1332
52.6M
        if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
1333
94.9k
          FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
1334
94.9k
                          &accu, &accu_e);
1335
52.5M
        } else {
1336
          /* 1.c  Add noise energy (if present) */
1337
52.5M
          if (noNoiseFlag == 0) {
1338
52.4M
            FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
1339
52.4M
                            accu_e, &accu, &accu_e);
1340
52.4M
          }
1341
52.5M
        }
1342
52.6M
      }
1343
1344
      /* 2.a  Calculate ratio of wanted energy and accumulated energy */
1345
7.47M
      if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
1346
59.3k
        boostGain = FL2FXCONST_DBL(0.6279716f);
1347
59.3k
        boostGain_e = 2;
1348
7.41M
      } else {
1349
7.41M
        INT div_e;
1350
7.41M
        boostGain = fDivNorm(sumRef, accu, &div_e);
1351
7.41M
        boostGain_e = sumRef_e - accu_e + div_e;
1352
7.41M
      }
1353
1354
      /* 2.b Result too high? --> Limit the boost factor to +4 dB */
1355
7.47M
      if ((boostGain_e > 3) ||
1356
5.59M
          (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
1357
5.47M
          (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
1358
2.21M
        boostGain = FL2FXCONST_DBL(0.6279716f);
1359
2.21M
        boostGain_e = 2;
1360
2.21M
      }
1361
      /* 3.  Multiply all signal components with the boost factor */
1362
60.0M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1363
52.6M
           k++) {
1364
52.6M
        pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
1365
52.6M
        pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
1366
1367
52.6M
        pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
1368
52.6M
        pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
1369
1370
52.6M
        pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
1371
52.6M
        pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
1372
52.6M
      }
1373
7.47M
    }
1374
    /* End of noise limiting */
1375
1376
2.17M
    if (useLP)
1377
46.5k
      aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
1378
46.5k
                        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.17M
    noise_e = (start_pos < no_cols) ? adj_e : final_e;
1387
1388
2.17M
    if (start_pos >= no_cols) {
1389
14.5k
      int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e;
1390
14.5k
      if (diff > 0) {
1391
4.60k
        int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
1392
4.60k
        if (diff > s) {
1393
140
          final_e += diff - s;
1394
140
          noise_e = final_e;
1395
140
        }
1396
4.60k
      }
1397
14.5k
    }
1398
1399
    /*
1400
      Convert energies to amplitude levels
1401
    */
1402
54.7M
    for (k = 0; k < noSubbands; k++) {
1403
52.5M
      FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
1404
52.5M
      FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
1405
52.5M
                       &pNrgs->nrgGain_e[k]);
1406
52.5M
      FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
1407
52.5M
                       &noise_e);
1408
52.5M
    }
1409
1410
    /*
1411
      Apply calculated gains and adaptive noise
1412
    */
1413
1414
    /* assembleHfSignals() */
1415
2.17M
    {
1416
2.17M
      int scale_change, sc_change;
1417
2.17M
      FIXP_SGL smooth_ratio;
1418
2.17M
      int filtBufferNoiseShift = 0;
1419
1420
      /* Initialize smoothing buffers with the first valid values */
1421
2.17M
      if (h_sbr_cal_env->startUp) {
1422
97.2k
        if (!useLP) {
1423
84.2k
          h_sbr_cal_env->filtBufferNoise_e = noise_e;
1424
1425
84.2k
          FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1426
84.2k
                    noSubbands * sizeof(SCHAR));
1427
84.2k
          FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1428
84.2k
                    noSubbands * sizeof(FIXP_DBL));
1429
84.2k
          FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1430
84.2k
                    noSubbands * sizeof(FIXP_DBL));
1431
84.2k
        }
1432
97.2k
        h_sbr_cal_env->startUp = 0;
1433
97.2k
      }
1434
1435
2.17M
      if (!useLP) {
1436
2.13M
        equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer,   /* buffered */
1437
2.13M
                              h_sbr_cal_env->filtBuffer_e, /* buffered */
1438
2.13M
                              pNrgs->nrgGain,              /* current  */
1439
2.13M
                              pNrgs->nrgGain_e,            /* current  */
1440
2.13M
                              noSubbands);
1441
1442
        /* Adapt exponent of buffered noise levels to the current exponent
1443
           so they can easily be smoothed */
1444
2.13M
        if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
1445
2.09M
          int shift = fixMin(DFRACT_BITS - 1,
1446
2.09M
                             (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1447
53.0M
          for (k = 0; k < noSubbands; k++)
1448
50.9M
            h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1449
2.09M
        } else {
1450
35.6k
          int shift =
1451
35.6k
              fixMin(DFRACT_BITS - 1,
1452
35.6k
                     -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1453
1.05M
          for (k = 0; k < noSubbands; k++)
1454
1.02M
            h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1455
35.6k
        }
1456
1457
2.13M
        h_sbr_cal_env->filtBufferNoise_e = noise_e;
1458
2.13M
      }
1459
1460
      /* find best scaling! */
1461
2.17M
      scale_change = -(DFRACT_BITS - 1);
1462
54.7M
      for (k = 0; k < noSubbands; k++) {
1463
52.5M
        scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
1464
52.5M
      }
1465
2.17M
      sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
1466
1467
2.17M
      if ((scale_change - sc_change + 1) < 0)
1468
522k
        scale_change -= (scale_change - sc_change + 1);
1469
1470
2.17M
      scale_change = (scale_change - sc_change) + 1;
1471
1472
54.7M
      for (k = 0; k < noSubbands; k++) {
1473
52.5M
        int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
1474
52.5M
        pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
1475
52.5M
        pNrgs->nrgGain_e[k] += sc;
1476
52.5M
      }
1477
1478
2.17M
      if (!useLP) {
1479
54.0M
        for (k = 0; k < noSubbands; k++) {
1480
51.9M
          int sc =
1481
51.9M
              scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
1482
51.9M
          h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
1483
51.9M
        }
1484
2.13M
      }
1485
1486
14.6M
      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.4M
        if ((j == no_cols) && (start_pos < no_cols)) {
1495
10.3k
          int shift = (int)(noise_e - final_e);
1496
10.3k
          if (!useLP)
1497
7.21k
            filtBufferNoiseShift = shift; /* shifting of
1498
                                             h_sbr_cal_env->filtBufferNoise[k]
1499
                                             will be applied in function
1500
                                             adjustTimeSlotHQ() */
1501
10.3k
          if (shift >= 0) {
1502
6.80k
            shift = fixMin(DFRACT_BITS - 1, shift);
1503
202k
            for (k = 0; k < noSubbands; k++) {
1504
195k
              pNrgs->nrgSine[k] <<= shift;
1505
195k
              pNrgs->noiseLevel[k] <<= shift;
1506
              /*
1507
              if (!useLP)
1508
                h_sbr_cal_env->filtBufferNoise[k]  <<= shift;
1509
              */
1510
195k
            }
1511
6.80k
          } else {
1512
3.51k
            shift = fixMin(DFRACT_BITS - 1, -shift);
1513
121k
            for (k = 0; k < noSubbands; k++) {
1514
118k
              pNrgs->nrgSine[k] >>= shift;
1515
118k
              pNrgs->noiseLevel[k] >>= shift;
1516
              /*
1517
              if (!useLP)
1518
                h_sbr_cal_env->filtBufferNoise[k]  >>= shift;
1519
              */
1520
118k
            }
1521
3.51k
          }
1522
1523
          /* update noise scaling */
1524
10.3k
          noise_e = final_e;
1525
10.3k
          if (!useLP)
1526
7.21k
            h_sbr_cal_env->filtBufferNoise_e =
1527
7.21k
                noise_e; /* scaling value unused! */
1528
1529
          /* update gain buffer*/
1530
10.3k
          sc_change -= (final_e - input_e);
1531
1532
10.3k
          if (sc_change < 0) {
1533
121k
            for (k = 0; k < noSubbands; k++) {
1534
118k
              pNrgs->nrgGain[k] >>= -sc_change;
1535
118k
              pNrgs->nrgGain_e[k] += -sc_change;
1536
118k
            }
1537
3.51k
            if (!useLP) {
1538
120k
              for (k = 0; k < noSubbands; k++) {
1539
117k
                h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
1540
117k
              }
1541
3.47k
            }
1542
6.80k
          } else {
1543
6.80k
            scale_change += sc_change;
1544
6.80k
          }
1545
1546
10.3k
        } /* if */
1547
1548
12.4M
        if (!useLP) {
1549
          /* Prevent the smoothing filter from running on constant levels */
1550
11.4M
          if (j - start_pos < smooth_length)
1551
3.17M
            smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
1552
8.30M
          else
1553
8.30M
            smooth_ratio = FL2FXCONST_SGL(0.0f);
1554
1555
11.4M
          if (iTES_enable) {
1556
            /* adjustTimeSlotHQ() without adding of additional harmonics */
1557
1.42M
            adjustTimeSlotHQ_GainAndNoise(
1558
1.42M
                &analysBufferReal[j][lowSubband],
1559
1.42M
                &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1560
1.42M
                lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1),
1561
1.42M
                smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
1562
10.0M
          } else {
1563
10.0M
            adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1564
10.0M
                             &analysBufferImag[j][lowSubband], h_sbr_cal_env,
1565
10.0M
                             pNrgs, lowSubband, noSubbands,
1566
10.0M
                             fMin(scale_change, DFRACT_BITS - 1), smooth_ratio,
1567
10.0M
                             noNoiseFlag, filtBufferNoiseShift);
1568
10.0M
          }
1569
11.4M
        } else {
1570
983k
          FDK_ASSERT(!iTES_enable); /* not supported */
1571
983k
          if (flags & SBRDEC_ELD_GRID) {
1572
            /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
1573
263k
            adjustTimeSlot_EldGrid(
1574
263k
                &analysBufferReal[j][lowSubband], pNrgs,
1575
263k
                &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1576
263k
                fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1577
263k
                &h_sbr_cal_env->phaseIndex,
1578
263k
                fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
1579
263k
                     -(DFRACT_BITS - 1)));
1580
719k
          } else {
1581
719k
            adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
1582
719k
                             &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1583
719k
                             fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1584
719k
                             &h_sbr_cal_env->phaseIndex);
1585
719k
          }
1586
983k
        }
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.4M
        pNrgs->exponent[(j < no_cols) ? 0 : 1] =
1592
12.4M
            (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
1593
12.4M
                    scale_change);
1594
12.4M
      } /* for */
1595
1596
2.17M
      if (iTES_enable) {
1597
42.2k
        apply_inter_tes(
1598
42.2k
            analysBufferReal, /* pABufR, */
1599
42.2k
            analysBufferImag, /* pABufI, */
1600
42.2k
            sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
1601
42.2k
            stop_pos, lowSubband, noSubbands,
1602
42.2k
            hFrameData
1603
42.2k
                ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
1604
42.2k
        );
1605
1606
        /* add additional harmonics */
1607
1.46M
        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.42M
          scale_change = 0;
1611
1612
1.42M
          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
118k
            scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
1618
118k
          }
1619
1620
1.42M
          adjustTimeSlotHQ_AddHarmonics(
1621
1.42M
              &analysBufferReal[j][lowSubband],
1622
1.42M
              &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1623
1.42M
              lowSubband, noSubbands,
1624
1.42M
              -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
1625
1.42M
        }
1626
42.2k
      }
1627
1628
2.17M
      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.13M
        FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1635
2.13M
                  noSubbands * sizeof(FIXP_DBL));
1636
2.13M
        FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1637
2.13M
                  noSubbands * sizeof(SCHAR));
1638
2.13M
        FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1639
2.13M
                  noSubbands * sizeof(FIXP_DBL));
1640
2.13M
      }
1641
2.17M
    }
1642
0
    C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1643
2.17M
  }
1644
1645
  /* adapt adj_e to the scale change caused by apply_inter_tes() */
1646
358k
  adj_e += iTES_scale_change;
1647
1648
  /* Rescale output samples */
1649
358k
  {
1650
358k
    FIXP_DBL maxVal;
1651
358k
    int ov_reserve, reserve;
1652
1653
    /* Determine headroom in old adjusted samples */
1654
358k
    maxVal =
1655
358k
        maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1656
358k
                         lowSubband, ov_highSubband, 0, first_start);
1657
1658
358k
    ov_reserve = fNorm(maxVal);
1659
1660
    /* Determine headroom in new adjusted samples */
1661
358k
    maxVal =
1662
358k
        maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1663
358k
                         lowSubband, highSubband, first_start, no_cols);
1664
1665
358k
    reserve = fNorm(maxVal);
1666
1667
    /* Determine common output exponent */
1668
358k
    output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
1669
1670
    /* Rescale old samples */
1671
358k
    rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1672
358k
                          lowSubband, ov_highSubband, 0, first_start,
1673
358k
                          ov_adj_e - output_e);
1674
1675
    /* Rescale new samples */
1676
358k
    rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1677
358k
                          lowSubband, highSubband, first_start, no_cols,
1678
358k
                          adj_e - output_e);
1679
358k
  }
1680
1681
  /* Update hb_scale */
1682
358k
  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
358k
  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
358k
  if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1691
969
    h_sbr_cal_env->prevTranEnv = 0;
1692
357k
  else
1693
357k
    h_sbr_cal_env->prevTranEnv = -1;
1694
1695
358k
  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
117k
    FDK_ASSERT(hFrameData->frameInfo
1699
117k
                   .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
1700
117k
               PVC_NTIMESLOT);
1701
117k
    if (hFrameData->frameInfo
1702
117k
            .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
1703
117k
        PVC_NTIMESLOT) {
1704
98.1k
      FDK_ASSERT(noiseLevels ==
1705
98.1k
                 (hFrameData->sbrNoiseFloorLevel +
1706
98.1k
                  (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
1707
98.1k
      h_sbr_cal_env->prevNNfb = noNoiseBands;
1708
1709
98.1k
      h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
1710
98.1k
      h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
1711
1712
98.1k
      h_sbr_cal_env->prevLoSubband = lowSubband;
1713
98.1k
      h_sbr_cal_env->prevHiSubband = highSubband;
1714
98.1k
      h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
1715
1716
98.1k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
1717
98.1k
                noSubFrameBands[0] + 1);
1718
98.1k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
1719
98.1k
                noSubFrameBands[1] + 1);
1720
98.1k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
1721
98.1k
                hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
1722
1723
98.1k
      FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
1724
98.1k
                MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
1725
98.1k
    }
1726
117k
  }
1727
1728
358k
  C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
1729
358k
}
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
152k
    const UINT flags) {
1746
152k
  SBR_ERROR err = SBRDEC_OK;
1747
152k
  int i;
1748
1749
  /* Clear previous missing harmonics flags */
1750
456k
  for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
1751
304k
    hs->harmFlagsPrev[i] = 0;
1752
304k
    hs->harmFlagsPrevActive[i] = 0;
1753
304k
  }
1754
152k
  hs->harmIndex = 0;
1755
1756
152k
  FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
1757
152k
  hs->prevNNfb = 0;
1758
152k
  FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
1759
152k
  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
152k
  hs->prevTranEnv = -1;
1766
1767
  /* initialization */
1768
152k
  resetSbrEnvelopeCalc(hs);
1769
1770
152k
  if (chan == 0) { /* do this only once */
1771
98.8k
    err = resetFreqBandTables(hHeaderData, flags);
1772
98.8k
  }
1773
1774
152k
  return err;
1775
152k
}
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
153k
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
471k
{
1798
471k
  hCalEnv->phaseIndex = 0;
1799
1800
  /* Noise exponent needs to be reset because the output exponent for the next
1801
   * frame depends on it */
1802
471k
  hCalEnv->filtBufferNoise_e = 0;
1803
1804
471k
  hCalEnv->startUp = 1;
1805
471k
}
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.13M
{
1821
2.13M
  int band;
1822
2.13M
  int diff;
1823
1824
54.0M
  for (band = 0; band < subbands; band++) {
1825
51.9M
    diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
1826
51.9M
    if (diff > 0) {
1827
2.68M
      filtBuffer[band] >>=
1828
2.68M
          fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
1829
                                          shifting the mantissa. */
1830
2.68M
      filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1831
49.2M
    } 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
37.4M
      int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
1836
1837
37.4M
      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
31.6M
        filtBuffer[band] <<= (-diff);
1842
31.6M
        filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1843
31.6M
      } else {
1844
5.82M
        filtBuffer[band] <<=
1845
5.82M
            reserve; /* Shift the mantissa as far as possible: */
1846
5.82M
        filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1847
1848
        /* For the remaining difference, change the new gain value */
1849
5.82M
        diff = -(reserve + diff);
1850
5.82M
        nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
1851
5.82M
        nrgGain_e[band] += diff;
1852
5.82M
      }
1853
37.4M
    }
1854
51.9M
  }
1855
2.13M
}
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.31M
{
1873
1.31M
  int width = highSubband - lowSubband;
1874
1875
1.31M
  if ((width > 0) && (shift != 0)) {
1876
1.22M
    if (im != NULL) {
1877
25.2M
      for (int l = start_pos; l < next_pos; l++) {
1878
24.2M
        scaleValues(&re[l][lowSubband], width, shift);
1879
24.2M
        scaleValues(&im[l][lowSubband], width, shift);
1880
24.2M
      }
1881
954k
    } else {
1882
4.84M
      for (int l = start_pos; l < next_pos; l++) {
1883
4.57M
        scaleValues(&re[l][lowSubband], width, shift);
1884
4.57M
      }
1885
268k
    }
1886
1.22M
  }
1887
1.31M
}
1888
1889
static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
1890
4.98M
                                           INT width) {
1891
4.98M
  maxVal = (FIXP_DBL)0;
1892
136M
  while (width-- != 0) {
1893
131M
    FIXP_DBL tmp = *(reTmp++);
1894
131M
    maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
1895
131M
  }
1896
1897
4.98M
  return maxVal;
1898
4.98M
}
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.59M
) {
1917
1.59M
  FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1918
1.59M
  unsigned int width = highSubband - lowSubband;
1919
1920
1.59M
  FDK_ASSERT(width <= (64));
1921
1922
1.59M
  if (width > 0) {
1923
1.59M
    if (im != NULL) {
1924
37.7M
      for (int l = start_pos; l < next_pos; l++) {
1925
36.4M
        int k = width;
1926
36.4M
        FIXP_DBL *reTmp = &re[l][lowSubband];
1927
36.4M
        FIXP_DBL *imTmp = &im[l][lowSubband];
1928
656M
        do {
1929
656M
          FIXP_DBL tmp1 = *(reTmp++);
1930
656M
          FIXP_DBL tmp2 = *(imTmp++);
1931
656M
          maxVal |=
1932
656M
              (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
1933
656M
          maxVal |=
1934
656M
              (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
1935
656M
        } while (--k != 0);
1936
36.4M
      }
1937
1.29M
    } else {
1938
5.28M
      for (int l = start_pos; l < next_pos; l++) {
1939
4.98M
        maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
1940
4.98M
      }
1941
300k
    }
1942
1.59M
  }
1943
1944
1.59M
  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
895k
    FIXP_DBL lowerPow2 =
1948
895k
        (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
1949
895k
    if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
1950
895k
  }
1951
1952
1.59M
  return (maxVal);
1953
1.59M
}
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
31.9M
#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.14M
{
1995
2.14M
  FIXP_SGL invWidth;
1996
2.14M
  SCHAR preShift;
1997
2.14M
  SCHAR shift;
1998
2.14M
  FIXP_DBL sum;
1999
2.14M
  int k;
2000
2001
  /* Divide by width of envelope later: */
2002
2.14M
  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.14M
  frameExp = frameExp << 1;
2006
2007
54.1M
  for (k = lowSubband; k < highSubband; k++) {
2008
52.0M
    FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2009
52.0M
    FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2010
52.0M
    FIXP_DBL maxVal;
2011
2012
52.0M
    if (analysBufferImag != NULL) {
2013
51.4M
      int l;
2014
51.4M
      maxVal = FL2FX_DBL(0.0f);
2015
337M
      for (l = start_pos; l < next_pos; l++) {
2016
286M
        bufferImag[l] = analysBufferImag[l][k];
2017
286M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
2018
286M
                             ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
2019
286M
        bufferReal[l] = analysBufferReal[l][k];
2020
286M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2021
286M
                             ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2022
286M
      }
2023
51.4M
    } else {
2024
590k
      int l;
2025
590k
      maxVal = FL2FX_DBL(0.0f);
2026
17.0M
      for (l = start_pos; l < next_pos; l++) {
2027
16.4M
        bufferReal[l] = analysBufferReal[l][k];
2028
16.4M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2029
16.4M
                             ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2030
16.4M
      }
2031
590k
    }
2032
2033
52.0M
    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
31.8M
      FIXP_DBL accu;
2041
31.8M
      preShift = CntLeadingZeros(maxVal) - 1;
2042
31.8M
      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
31.8M
      preShift = fMin(preShift, (SCHAR)25);
2049
2050
31.8M
      accu = FL2FXCONST_DBL(0.0f);
2051
31.8M
      if (preShift >= 0) {
2052
30.8M
        int l;
2053
30.8M
        if (analysBufferImag != NULL) {
2054
172M
          for (l = start_pos; l < next_pos; l++) {
2055
141M
            FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
2056
141M
            FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
2057
141M
            accu = fPow2AddDiv2(accu, temp1);
2058
141M
            accu = fPow2AddDiv2(accu, temp2);
2059
141M
          }
2060
30.7M
        } else {
2061
1.84M
          for (l = start_pos; l < next_pos; l++) {
2062
1.75M
            FIXP_DBL temp = bufferReal[l] << (int)preShift;
2063
1.75M
            accu = fPow2AddDiv2(accu, temp);
2064
1.75M
          }
2065
90.5k
        }
2066
30.8M
      } else { /* if negative shift value */
2067
984k
        int l;
2068
984k
        int negpreShift = -preShift;
2069
984k
        if (analysBufferImag != NULL) {
2070
8.27M
          for (l = start_pos; l < next_pos; l++) {
2071
7.30M
            FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
2072
7.30M
            FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
2073
7.30M
            accu = fPow2AddDiv2(accu, temp1);
2074
7.30M
            accu = fPow2AddDiv2(accu, temp2);
2075
7.30M
          }
2076
977k
        } else {
2077
150k
          for (l = start_pos; l < next_pos; l++) {
2078
143k
            FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
2079
143k
            accu = fPow2AddDiv2(accu, temp);
2080
143k
          }
2081
6.88k
        }
2082
984k
      }
2083
31.8M
      accu <<= 1;
2084
2085
      /* Convert double precision to Mantissa/Exponent: */
2086
31.8M
      shift = fNorm(accu);
2087
31.8M
      sum = accu << (int)shift;
2088
2089
      /* Divide by width of envelope and apply frame scale: */
2090
31.8M
      *nrgEst++ = fMult(sum, invWidth);
2091
31.8M
      shift += 2 * preShift;
2092
31.8M
      if (analysBufferImag != NULL)
2093
31.7M
        *nrgEst_e++ = frameExp - shift;
2094
97.4k
      else
2095
97.4k
        *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
2096
31.8M
    }                                       /* maxVal!=0 */
2097
20.2M
    else {
2098
      /* Prevent a zero-mantissa-number from being misinterpreted
2099
         due to its exponent. */
2100
20.2M
      *nrgEst++ = FL2FXCONST_DBL(0.0f);
2101
20.2M
      *nrgEst_e++ = 0;
2102
20.2M
    }
2103
52.0M
  }
2104
2.14M
}
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
36.4k
{
2123
36.4k
  FIXP_SGL invWidth;
2124
36.4k
  FIXP_DBL temp;
2125
36.4k
  SCHAR preShift;
2126
36.4k
  SCHAR shift, sum_e;
2127
36.4k
  FIXP_DBL sum;
2128
2129
36.4k
  int j, k, l, li, ui;
2130
36.4k
  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
36.4k
  invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2135
  /* The common exponent needs to be doubled because all mantissas are squared:
2136
   */
2137
36.4k
  input_e = input_e << 1;
2138
2139
306k
  for (j = 0; j < nSfb; j++) {
2140
269k
    li = freqBandTable[j];
2141
269k
    ui = freqBandTable[j + 1];
2142
2143
269k
    FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
2144
269k
                                       ui, start_pos, next_pos);
2145
2146
269k
    if (maxVal != FL2FXCONST_DBL(0.f)) {
2147
177k
      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
177k
      preShift -= SHIFT_BEFORE_SQUARE;
2156
2157
177k
      sumAll = FL2FXCONST_DBL(0.0f);
2158
2159
460k
      for (k = li; k < ui; k++) {
2160
282k
        sumLine = FL2FXCONST_DBL(0.0f);
2161
2162
282k
        if (analysBufferImag != NULL) {
2163
229k
          if (preShift >= 0) {
2164
9.62M
            for (l = start_pos; l < next_pos; l++) {
2165
9.40M
              temp = analysBufferReal[l][k] << (int)preShift;
2166
9.40M
              sumLine += fPow2Div2(temp);
2167
9.40M
              temp = analysBufferImag[l][k] << (int)preShift;
2168
9.40M
              sumLine += fPow2Div2(temp);
2169
9.40M
            }
2170
222k
          } else {
2171
120k
            for (l = start_pos; l < next_pos; l++) {
2172
113k
              temp = analysBufferReal[l][k] >> -(int)preShift;
2173
113k
              sumLine += fPow2Div2(temp);
2174
113k
              temp = analysBufferImag[l][k] >> -(int)preShift;
2175
113k
              sumLine += fPow2Div2(temp);
2176
113k
            }
2177
7.07k
          }
2178
229k
        } else {
2179
52.7k
          if (preShift >= 0) {
2180
841k
            for (l = start_pos; l < next_pos; l++) {
2181
791k
              temp = analysBufferReal[l][k] << (int)preShift;
2182
791k
              sumLine += fPow2Div2(temp);
2183
791k
            }
2184
50.2k
          } else {
2185
63.6k
            for (l = start_pos; l < next_pos; l++) {
2186
61.1k
              temp = analysBufferReal[l][k] >> -(int)preShift;
2187
61.1k
              sumLine += fPow2Div2(temp);
2188
61.1k
            }
2189
2.51k
          }
2190
52.7k
        }
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
282k
        sumLine = sumLine >> (4 - 1);
2195
282k
        sumAll += sumLine;
2196
282k
      }
2197
2198
      /* Convert double precision to Mantissa/Exponent: */
2199
177k
      shift = fNorm(sumAll);
2200
177k
      sum = sumAll << (int)shift;
2201
2202
      /* Divide by width of envelope: */
2203
177k
      sum = fMult(sum, invWidth);
2204
2205
      /* Divide by width of Sfb: */
2206
177k
      sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
2207
2208
      /* Set all Subband energies in the Sfb to the average energy: */
2209
177k
      if (analysBufferImag != NULL)
2210
160k
        sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
2211
17.1k
      else
2212
17.1k
        sum_e = input_e + 4 + 1 -
2213
17.1k
                shift; /* -4 to compensate right-shift; +1 due to missing
2214
                          imag. part */
2215
2216
177k
      sum_e -= 2 * preShift;
2217
177k
    } /* maxVal!=0 */
2218
91.8k
    else {
2219
      /* Prevent a zero-mantissa-number from being misinterpreted
2220
         due to its exponent. */
2221
91.8k
      sum = FL2FXCONST_DBL(0.0f);
2222
91.8k
      sum_e = 0;
2223
91.8k
    }
2224
2225
800k
    for (k = li; k < ui; k++) {
2226
530k
      *nrgEst++ = sum;
2227
530k
      *nrgEst_e++ = sum_e;
2228
530k
    }
2229
269k
  }
2230
36.4k
}
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
52.5M
{
2247
52.5M
  FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
2248
52.5M
  SCHAR nrgEst_e =
2249
52.5M
      nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
2250
52.5M
  FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
2251
52.5M
  SCHAR *ptrNrgGain_e =
2252
52.5M
      &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
2253
52.5M
  FIXP_DBL *ptrNoiseLevel =
2254
52.5M
      &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
2255
52.5M
  SCHAR *ptrNoiseLevel_e =
2256
52.5M
      &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
2257
52.5M
  FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
2258
52.5M
  SCHAR *ptrNrgSine_e =
2259
52.5M
      &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
2260
2261
52.5M
  FIXP_DBL a, b, c;
2262
52.5M
  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
52.5M
  b_e = (int)(nrgEst_e - 1);
2270
52.5M
  if (b_e >= 0) {
2271
27.9M
    nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2272
27.9M
             (nrgEst >> 1);
2273
27.9M
    nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
2274
2275
27.9M
  } else {
2276
24.6M
    nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2277
24.6M
             (FL2FXCONST_DBL(0.5f) >> 1);
2278
24.6M
    nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
2279
24.6M
  }
2280
2281
  /*  A = NrgRef * TmpNoise */
2282
52.5M
  a = fMult(nrgRef, tmpNoise);
2283
52.5M
  a_e = nrgRef_e + tmpNoise_e;
2284
2285
  /*  B = 1 + TmpNoise */
2286
52.5M
  b_e = (int)(tmpNoise_e - 1);
2287
52.5M
  if (b_e >= 0) {
2288
15.6M
    b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2289
15.6M
        (tmpNoise >> 1);
2290
15.6M
    b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
2291
36.9M
  } else {
2292
36.9M
    b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2293
36.9M
        (FL2FXCONST_DBL(0.5f) >> 1);
2294
36.9M
    b_e = 2; /* shift by 1 bit to avoid overflow */
2295
36.9M
  }
2296
2297
  /*  noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
2298
52.5M
  FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
2299
2300
52.5M
  if (sinePresentFlag) {
2301
    /*  C = (1 + TmpNoise) * NrgEst */
2302
289k
    c = fMult(b, nrgEst);
2303
289k
    c_e = b_e + nrgEst_e;
2304
2305
    /*  gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
2306
289k
    FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
2307
2308
289k
    if (sineMapped) {
2309
      /*  sineLevel = nrgRef/ (1 + TmpNoise) */
2310
95.2k
      FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
2311
95.2k
    }
2312
52.2M
  } else {
2313
52.2M
    if (noNoiseFlag) {
2314
      /*  B = NrgEst */
2315
58.0k
      b = nrgEst;
2316
58.0k
      b_e = nrgEst_e;
2317
52.2M
    } else {
2318
      /*  B = NrgEst * (1 + TmpNoise) */
2319
52.2M
      b = fMult(b, nrgEst);
2320
52.2M
      b_e = b_e + nrgEst_e;
2321
52.2M
    }
2322
2323
    /*  gain = nrgRef / B */
2324
52.2M
    INT result_exp = 0;
2325
52.2M
    *ptrNrgGain = fDivNorm(nrgRef, b, &result_exp);
2326
52.2M
    *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.2M
    int headroom = CountLeadingBits(*ptrNrgGain);
2331
52.2M
    *ptrNrgGain <<= headroom;
2332
52.2M
    *ptrNrgGain_e -= headroom;
2333
52.2M
  }
2334
52.5M
}
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.47M
{
2351
7.47M
  FIXP_DBL *nrgRef =
2352
7.47M
      nrgs->nrgRef; /*!< Reference Energy according to envelope data */
2353
7.47M
  SCHAR *nrgRef_e =
2354
7.47M
      nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
2355
                         (exponent) */
2356
7.47M
  FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
2357
7.47M
  SCHAR *nrgEst_e =
2358
7.47M
      nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
2359
2360
7.47M
  FIXP_DBL sumRef = 1;
2361
7.47M
  FIXP_DBL sumEst = 1;
2362
7.47M
  SCHAR sumRef_e = -FRACT_BITS;
2363
7.47M
  SCHAR sumEst_e = -FRACT_BITS;
2364
7.47M
  int k;
2365
2366
60.0M
  for (k = lowSubband; k < highSubband; k++) {
2367
    /* Add nrgRef[k] to sumRef: */
2368
52.6M
    FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
2369
52.6M
                    &sumRef_e);
2370
2371
    /* Add nrgEst[k] to sumEst: */
2372
52.6M
    FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
2373
52.6M
                    &sumEst_e);
2374
52.6M
  }
2375
2376
7.47M
  FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
2377
7.47M
                     ptrAvgGain_e);
2378
2379
7.47M
  *ptrSumRef = sumRef;
2380
7.47M
  *ptrSumRef_e = sumRef_e;
2381
7.47M
}
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
263k
{
2395
263k
  int k;
2396
263k
  FIXP_DBL signalReal, sbNoise;
2397
263k
  int tone_count = 0;
2398
2399
263k
  FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2400
263k
  FIXP_DBL *RESTRICT pNoiseLevel =
2401
263k
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2402
263k
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2403
2404
263k
  int phaseIndex = *ptrPhaseIndex;
2405
263k
  UCHAR harmIndex = *ptrHarmIndex;
2406
2407
263k
  static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2408
2409
263k
  static const FIXP_DBL harmonicPhaseX[4][2] = {
2410
263k
      {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
2411
263k
       FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
2412
263k
      {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
2413
263k
       FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
2414
263k
      {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
2415
263k
       FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
2416
263k
      {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
2417
263k
       FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
2418
2419
263k
  const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
2420
263k
  const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
2421
2422
263k
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2423
263k
  const FIXP_DBL min_val = -max_val;
2424
2425
263k
  *(ptrReal - 1) = fAddSaturate(
2426
263k
      *(ptrReal - 1),
2427
263k
      SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
2428
263k
                     scale_diff_low, DFRACT_BITS));
2429
263k
  FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
2430
2431
263k
  int idx_k = lowSubband & 1;
2432
2433
1.98M
  for (k = 0; k < noSubbands; k++) {
2434
1.71M
    FIXP_DBL sineLevel_curr = *pSineLevel++;
2435
1.71M
    phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2436
2437
1.71M
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2438
1.71M
                 << scale_change;
2439
1.71M
    sbNoise = *pNoiseLevel++;
2440
1.71M
    if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2441
1.64M
      signalReal +=
2442
1.64M
          fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2443
1.64M
    }
2444
1.71M
    signalReal += sineLevel_curr * p_harmonicPhase[0];
2445
1.71M
    signalReal =
2446
1.71M
        fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2447
1.71M
    pSineLevel_prev = sineLevel_curr;
2448
1.71M
    idx_k = !idx_k;
2449
1.71M
    if (k < noSubbands - 1) {
2450
1.45M
      signalReal =
2451
1.45M
          fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
2452
1.45M
    } else /* (k == noSubbands - 1)  */
2453
263k
    {
2454
263k
      if (k + lowSubband + 1 < 63) {
2455
260k
        *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2456
260k
      }
2457
263k
    }
2458
1.71M
    *ptrReal++ = signalReal;
2459
2460
1.71M
    if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
2461
25.0k
      if (++tone_count == 16) {
2462
440
        k++;
2463
440
        break;
2464
440
      }
2465
25.0k
    }
2466
1.71M
  }
2467
  /* Run again, if previous loop got breaked with tone_count = 16 */
2468
267k
  for (; k < noSubbands; k++) {
2469
3.79k
    FIXP_DBL sineLevel_curr = *pSineLevel++;
2470
3.79k
    phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2471
2472
3.79k
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2473
3.79k
                 << scale_change;
2474
3.79k
    sbNoise = *pNoiseLevel++;
2475
3.79k
    if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2476
1.85k
      signalReal +=
2477
1.85k
          fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2478
1.85k
    }
2479
3.79k
    signalReal += sineLevel_curr * p_harmonicPhase[0];
2480
3.79k
    *ptrReal++ = signalReal;
2481
3.79k
  }
2482
2483
263k
  *ptrHarmIndex = (harmIndex + 1) & 3;
2484
263k
  *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
2485
263k
}
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
719k
{
2501
719k
  FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2502
719k
  FIXP_DBL *pNoiseLevel =
2503
719k
      nrgs->noiseLevel;                 /*!< Noise levels of current envelope */
2504
719k
  FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2505
2506
719k
  int k;
2507
719k
  int index = *ptrPhaseIndex;
2508
719k
  UCHAR harmIndex = *ptrHarmIndex;
2509
719k
  UCHAR freqInvFlag = (lowSubband & 1);
2510
719k
  FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
2511
719k
  int tone_count = 0;
2512
719k
  int sineSign = 1;
2513
719k
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2514
719k
  const FIXP_DBL min_val = -max_val;
2515
2516
7.97M
#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
2517
719k
#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
719k
  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
719k
  signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2531
719k
               << scale_change;
2532
719k
  sineLevel = *pSineLevel++;
2533
719k
  sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
2534
2535
719k
  if (sineLevel != FL2FXCONST_DBL(0.0f))
2536
43.8k
    tone_count++;
2537
676k
  else if (!noNoiseFlag)
2538
    /* Add noisefloor to the amplified signal */
2539
674k
    signalReal +=
2540
674k
        fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2541
2542
719k
  {
2543
719k
    if (!(harmIndex & 0x1)) {
2544
      /* harmIndex 0,2 */
2545
359k
      signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel;
2546
359k
      *ptrReal++ = signalReal;
2547
359k
    } else {
2548
      /* harmIndex 1,3 in combination with freqInvFlag */
2549
359k
      int shift = (int)(scale_change + 1);
2550
359k
      shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift)
2551
359k
                           : fixMax(-(DFRACT_BITS - 1), shift);
2552
2553
359k
      FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
2554
359k
                                   : (fMultDiv2(C1, sineLevel) << (-shift));
2555
359k
      FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
2556
2557
      /* save switch and compare operations and reduce to XOR statement */
2558
359k
      if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
2559
177k
        *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
2560
177k
        signalReal -= tmp2;
2561
182k
      } else {
2562
182k
        *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
2563
182k
        signalReal += tmp2;
2564
182k
      }
2565
359k
      *ptrReal++ = signalReal;
2566
359k
      freqInvFlag = !freqInvFlag;
2567
359k
    }
2568
719k
  }
2569
2570
719k
  pNoiseLevel++;
2571
2572
719k
  if (noSubbands > 2) {
2573
717k
    if (!(harmIndex & 0x1)) {
2574
      /* harmIndex 0,2 */
2575
358k
      if (!harmIndex) {
2576
179k
        sineSign = 0;
2577
179k
      }
2578
2579
7.48M
      for (k = noSubbands - 2; k != 0; k--) {
2580
7.13M
        FIXP_DBL sinelevel = *pSineLevel++;
2581
7.13M
        index++;
2582
7.13M
        if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
2583
7.13M
             FL2FXCONST_DBL(0.0f)) &&
2584
6.68M
            !noNoiseFlag) {
2585
          /* Add noisefloor to the amplified signal */
2586
6.64M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2587
6.64M
          signalReal +=
2588
6.64M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2589
6.64M
        }
2590
2591
        /* The next multiplication constitutes the actual envelope adjustment of
2592
         * the signal. */
2593
7.13M
        signalReal +=
2594
7.13M
            fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2595
7.13M
            << scale_change;
2596
2597
7.13M
        pNoiseLevel++;
2598
7.13M
        *ptrReal++ = signalReal;
2599
7.13M
      } /* for ... */
2600
358k
    } else {
2601
      /* harmIndex 1,3 in combination with freqInvFlag */
2602
358k
      if (harmIndex == 1) freqInvFlag = !freqInvFlag;
2603
2604
7.48M
      for (k = noSubbands - 2; k != 0; k--) {
2605
7.13M
        index++;
2606
        /* The next multiplication constitutes the actual envelope adjustment of
2607
         * the signal. */
2608
7.13M
        signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2609
7.13M
                     << scale_change;
2610
2611
7.13M
        if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
2612
447k
          tone_count++;
2613
6.68M
        else if (!noNoiseFlag) {
2614
          /* Add noisefloor to the amplified signal */
2615
6.64M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2616
6.64M
          signalReal +=
2617
6.64M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2618
6.64M
        }
2619
2620
7.13M
        pNoiseLevel++;
2621
2622
7.13M
        if (tone_count <= 16) {
2623
6.92M
          FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
2624
6.92M
          signalReal += (freqInvFlag) ? (-addSine) : (addSine);
2625
6.92M
        }
2626
2627
7.13M
        *ptrReal++ = signalReal;
2628
7.13M
        freqInvFlag = !freqInvFlag;
2629
7.13M
      } /* for ... */
2630
358k
    }
2631
717k
  }
2632
2633
719k
  if (noSubbands > -1) {
2634
719k
    index++;
2635
    /* The next multiplication constitutes the actual envelope adjustment of the
2636
     * signal. */
2637
719k
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
2638
719k
                 << scale_change;
2639
719k
    sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
2640
719k
    sineLevel = pSineLevel[0];
2641
2642
719k
    if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
2643
4.53k
      tone_count++;
2644
715k
    else if (!noNoiseFlag) {
2645
      /* Add noisefloor to the amplified signal */
2646
710k
      index &= (SBR_NF_NO_RANDOM_VAL - 1);
2647
710k
      signalReal = signalReal + fMult(FDK_sbrDecoder_sbr_randomPhase[index][0],
2648
710k
                                      pNoiseLevel[0]);
2649
710k
    }
2650
2651
719k
    if (!(harmIndex & 0x1)) {
2652
      /* harmIndex 0,2 */
2653
359k
      *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
2654
359k
    } else {
2655
      /* harmIndex 1,3 in combination with freqInvFlag */
2656
359k
      if (tone_count <= 16) {
2657
338k
        if (freqInvFlag) {
2658
169k
          *ptrReal++ = signalReal - sineLevelPrev;
2659
169k
          if (noSubbands + lowSubband < 63)
2660
168k
            *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
2661
169k
        } else {
2662
168k
          *ptrReal++ = signalReal + sineLevelPrev;
2663
168k
          if (noSubbands + lowSubband < 63)
2664
167k
            *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
2665
168k
        }
2666
338k
      } else
2667
21.2k
        *ptrReal = signalReal;
2668
359k
    }
2669
719k
  }
2670
719k
  *ptrHarmIndex = (harmIndex + 1) & 3;
2671
719k
  *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2672
719k
}
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.42M
{
2687
1.42M
  FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2688
1.42M
  FIXP_DBL *RESTRICT noiseLevel =
2689
1.42M
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2690
1.42M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2691
2692
1.42M
  FIXP_DBL *RESTRICT filtBuffer =
2693
1.42M
      h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2694
1.42M
  FIXP_DBL *RESTRICT filtBufferNoise =
2695
1.42M
      h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2696
1.42M
  int *RESTRICT ptrPhaseIndex =
2697
1.42M
      &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2698
2699
1.42M
  int k;
2700
1.42M
  FIXP_DBL signalReal, signalImag;
2701
1.42M
  FIXP_DBL noiseReal, noiseImag;
2702
1.42M
  FIXP_DBL smoothedGain, smoothedNoise;
2703
1.42M
  FIXP_SGL direct_ratio =
2704
1.42M
      /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2705
1.42M
  int index = *ptrPhaseIndex;
2706
1.42M
  int shift;
2707
1.42M
  FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2708
1.42M
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2709
1.42M
  const FIXP_DBL min_val = -max_val;
2710
2711
1.42M
  *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2712
2713
1.42M
  filtBufferNoiseShift +=
2714
1.42M
      1; /* due to later use of fMultDiv2 instead of fMult */
2715
1.42M
  if (filtBufferNoiseShift < 0) {
2716
2.06k
    shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2717
1.42M
  } else {
2718
1.42M
    shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2719
1.42M
    max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2720
1.42M
    min_val_noise = -max_val_noise;
2721
1.42M
  }
2722
2723
1.42M
  if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2724
447k
    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
428k
      smoothedGain =
2730
428k
          fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2731
2732
428k
      if (filtBufferNoiseShift < 0) {
2733
282
        smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2734
282
                        fMult(direct_ratio, noiseLevel[k]);
2735
428k
      } else {
2736
428k
        smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2737
428k
        smoothedNoise =
2738
428k
            (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2739
428k
            fMult(direct_ratio, noiseLevel[k]);
2740
428k
      }
2741
2742
428k
      smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2743
428k
                           (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
428k
      signalReal =
2751
428k
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2752
428k
          << scale_change;
2753
428k
      signalImag =
2754
428k
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2755
428k
          << scale_change;
2756
2757
428k
      index++;
2758
2759
428k
      if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
2760
        /* Just the amplified signal is saved */
2761
1.43k
        *ptrReal++ = signalReal;
2762
1.43k
        *ptrImag++ = signalImag;
2763
427k
      } else {
2764
        /* Add noisefloor to the amplified signal */
2765
427k
        index &= (SBR_NF_NO_RANDOM_VAL - 1);
2766
427k
        noiseReal =
2767
427k
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2768
427k
        noiseImag =
2769
427k
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2770
427k
        *ptrReal++ = (signalReal + noiseReal);
2771
427k
        *ptrImag++ = (signalImag + noiseImag);
2772
427k
      }
2773
428k
    }
2774
1.40M
  } else {
2775
36.4M
    for (k = 0; k < noSubbands; k++) {
2776
35.0M
      smoothedGain = gain[k];
2777
35.0M
      signalReal =
2778
35.0M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2779
35.0M
          << scale_change;
2780
35.0M
      signalImag =
2781
35.0M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2782
35.0M
          << scale_change;
2783
2784
35.0M
      index++;
2785
2786
35.0M
      if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
2787
        /* Add noisefloor to the amplified signal */
2788
34.3M
        smoothedNoise = noiseLevel[k];
2789
34.3M
        index &= (SBR_NF_NO_RANDOM_VAL - 1);
2790
34.3M
        noiseReal =
2791
34.3M
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2792
34.3M
        noiseImag =
2793
34.3M
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2794
2795
34.3M
        signalReal += noiseReal;
2796
34.3M
        signalImag += noiseImag;
2797
34.3M
      }
2798
35.0M
      *ptrReal++ = signalReal;
2799
35.0M
      *ptrImag++ = signalImag;
2800
35.0M
    }
2801
1.40M
  }
2802
1.42M
}
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.42M
) {
2815
1.42M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2816
1.42M
  UCHAR *RESTRICT ptrHarmIndex =
2817
1.42M
      &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2818
2819
1.42M
  int k;
2820
1.42M
  FIXP_DBL signalReal, signalImag;
2821
1.42M
  UCHAR harmIndex = *ptrHarmIndex;
2822
1.42M
  int freqInvFlag = (lowSubband & 1);
2823
1.42M
  FIXP_DBL sineLevel;
2824
2825
1.42M
  *ptrHarmIndex = (harmIndex + 1) & 3;
2826
2827
36.8M
  for (k = 0; k < noSubbands; k++) {
2828
35.4M
    sineLevel = pSineLevel[k];
2829
35.4M
    freqInvFlag ^= 1;
2830
35.4M
    if (sineLevel != FL2FXCONST_DBL(0.f)) {
2831
28.4k
      signalReal = ptrReal[k];
2832
28.4k
      signalImag = ptrImag[k];
2833
28.4k
      sineLevel = scaleValue(sineLevel, scale_change);
2834
28.4k
      if (harmIndex & 2) {
2835
        /* case 2,3 */
2836
14.0k
        sineLevel = -sineLevel;
2837
14.0k
      }
2838
28.4k
      if (!(harmIndex & 1)) {
2839
        /* case 0,2: */
2840
14.2k
        ptrReal[k] = signalReal + sineLevel;
2841
14.2k
      } else {
2842
        /* case 1,3 */
2843
14.2k
        if (!freqInvFlag) sineLevel = -sineLevel;
2844
14.2k
        ptrImag[k] = signalImag + sineLevel;
2845
14.2k
      }
2846
28.4k
    }
2847
35.4M
  }
2848
1.42M
}
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
10.0M
{
2863
10.0M
  FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2864
10.0M
  FIXP_DBL *RESTRICT noiseLevel =
2865
10.0M
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2866
10.0M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2867
2868
10.0M
  FIXP_DBL *RESTRICT filtBuffer =
2869
10.0M
      h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2870
10.0M
  FIXP_DBL *RESTRICT filtBufferNoise =
2871
10.0M
      h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2872
10.0M
  UCHAR *RESTRICT ptrHarmIndex =
2873
10.0M
      &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2874
10.0M
  int *RESTRICT ptrPhaseIndex =
2875
10.0M
      &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2876
2877
10.0M
  int k;
2878
10.0M
  FIXP_DBL signalReal, signalImag;
2879
10.0M
  FIXP_DBL noiseReal, noiseImag;
2880
10.0M
  FIXP_DBL smoothedGain, smoothedNoise;
2881
10.0M
  FIXP_SGL direct_ratio =
2882
10.0M
      /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2883
10.0M
  int index = *ptrPhaseIndex;
2884
10.0M
  UCHAR harmIndex = *ptrHarmIndex;
2885
10.0M
  int freqInvFlag = (lowSubband & 1);
2886
10.0M
  FIXP_DBL sineLevel;
2887
10.0M
  int shift;
2888
10.0M
  FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2889
10.0M
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2890
10.0M
  const FIXP_DBL min_val = -max_val;
2891
2892
10.0M
  *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2893
10.0M
  *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
10.0M
  filtBufferNoiseShift +=
2905
10.0M
      1; /* due to later use of fMultDiv2 instead of fMult */
2906
10.0M
  if (filtBufferNoiseShift < 0) {
2907
1.69k
    shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2908
10.0M
  } else {
2909
10.0M
    shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2910
10.0M
    max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2911
10.0M
    min_val_noise = -max_val_noise;
2912
10.0M
  }
2913
2914
10.0M
  if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2915
66.9M
    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
63.7M
      smoothedGain =
2922
63.7M
          fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2923
2924
63.7M
      if (filtBufferNoiseShift < 0) {
2925
290
        smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2926
290
                        fMult(direct_ratio, noiseLevel[k]);
2927
63.7M
      } else {
2928
63.7M
        smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2929
63.7M
        smoothedNoise =
2930
63.7M
            (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2931
63.7M
            fMult(direct_ratio, noiseLevel[k]);
2932
63.7M
      }
2933
2934
63.7M
      smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2935
63.7M
                           (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
63.7M
      signalReal =
2943
63.7M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2944
63.7M
          << scale_change;
2945
63.7M
      signalImag =
2946
63.7M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2947
63.7M
          << scale_change;
2948
2949
63.7M
      index++;
2950
2951
63.7M
      if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2952
79.4k
        sineLevel = pSineLevel[k];
2953
2954
79.4k
        switch (harmIndex) {
2955
20.1k
          case 0:
2956
20.1k
            *ptrReal++ = (signalReal + sineLevel);
2957
20.1k
            *ptrImag++ = (signalImag);
2958
20.1k
            break;
2959
19.6k
          case 2:
2960
19.6k
            *ptrReal++ = (signalReal - sineLevel);
2961
19.6k
            *ptrImag++ = (signalImag);
2962
19.6k
            break;
2963
20.1k
          case 1:
2964
20.1k
            *ptrReal++ = (signalReal);
2965
20.1k
            if (freqInvFlag)
2966
18.8k
              *ptrImag++ = (signalImag - sineLevel);
2967
1.24k
            else
2968
1.24k
              *ptrImag++ = (signalImag + sineLevel);
2969
20.1k
            break;
2970
19.6k
          case 3:
2971
19.6k
            *ptrReal++ = signalReal;
2972
19.6k
            if (freqInvFlag)
2973
18.3k
              *ptrImag++ = (signalImag + sineLevel);
2974
1.22k
            else
2975
1.22k
              *ptrImag++ = (signalImag - sineLevel);
2976
19.6k
            break;
2977
79.4k
        }
2978
63.6M
      } else {
2979
63.6M
        if (noNoiseFlag) {
2980
          /* Just the amplified signal is saved */
2981
0
          *ptrReal++ = (signalReal);
2982
0
          *ptrImag++ = (signalImag);
2983
63.6M
        } else {
2984
          /* Add noisefloor to the amplified signal */
2985
63.6M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2986
63.6M
          noiseReal =
2987
63.6M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2988
63.6M
          noiseImag =
2989
63.6M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2990
63.6M
          *ptrReal++ = (signalReal + noiseReal);
2991
63.6M
          *ptrImag++ = (signalImag + noiseImag);
2992
63.6M
        }
2993
63.6M
      }
2994
63.7M
      freqInvFlag ^= 1;
2995
63.7M
    }
2996
2997
6.90M
  } else {
2998
207M
    for (k = 0; k < noSubbands; k++) {
2999
200M
      smoothedGain = gain[k];
3000
200M
      signalReal =
3001
200M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
3002
200M
          << scale_change;
3003
200M
      signalImag =
3004
200M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
3005
200M
          << scale_change;
3006
3007
200M
      index++;
3008
3009
200M
      if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
3010
160k
        switch (harmIndex) {
3011
40.7k
          case 0:
3012
40.7k
            signalReal += sineLevel;
3013
40.7k
            break;
3014
40.7k
          case 1:
3015
40.7k
            if (freqInvFlag)
3016
26.7k
              signalImag -= sineLevel;
3017
13.9k
            else
3018
13.9k
              signalImag += sineLevel;
3019
40.7k
            break;
3020
39.6k
          case 2:
3021
39.6k
            signalReal -= sineLevel;
3022
39.6k
            break;
3023
39.6k
          case 3:
3024
39.6k
            if (freqInvFlag)
3025
25.7k
              signalImag += sineLevel;
3026
13.8k
            else
3027
13.8k
              signalImag -= sineLevel;
3028
39.6k
            break;
3029
160k
        }
3030
200M
      } else {
3031
200M
        if (noNoiseFlag == 0) {
3032
          /* Add noisefloor to the amplified signal */
3033
200M
          smoothedNoise = noiseLevel[k];
3034
200M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
3035
200M
          noiseReal =
3036
200M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
3037
200M
          noiseImag =
3038
200M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
3039
3040
200M
          signalReal += noiseReal;
3041
200M
          signalImag += noiseImag;
3042
200M
        }
3043
200M
      }
3044
200M
      *ptrReal++ = signalReal;
3045
200M
      *ptrImag++ = signalImag;
3046
3047
200M
      freqInvFlag ^= 1;
3048
200M
    }
3049
6.90M
  }
3050
10.0M
}
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
336k
    UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
3070
336k
  int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
3071
336k
  UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
3072
336k
  int patchBorders[MAX_NUM_PATCHES + 1];
3073
336k
  int kx, k2;
3074
3075
336k
  int lowSubband = freqBandTable[0];
3076
336k
  int highSubband = freqBandTable[noFreqBands];
3077
3078
  /* 1 limiter band. */
3079
336k
  if (limiterBands == 0) {
3080
5.24k
    limiterBandTable[0] = 0;
3081
5.24k
    limiterBandTable[1] = highSubband - lowSubband;
3082
5.24k
    nBands = 1;
3083
331k
  } else {
3084
331k
    if (!sbrPatchingMode && xOverQmf != NULL) {
3085
38.4k
      noPatches = 0;
3086
3087
38.4k
      if (b41Sbr == 1) {
3088
97.5k
        for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
3089
81.3k
          if (xOverQmf[i] != 0) noPatches++;
3090
22.2k
      } else {
3091
88.9k
        for (i = 1; i < MAX_STRETCH_HBE; i++)
3092
66.6k
          if (xOverQmf[i] != 0) noPatches++;
3093
22.2k
      }
3094
115k
      for (i = 0; i < noPatches; i++) {
3095
77.0k
        patchBorders[i] = xOverQmf[i] - lowSubband;
3096
77.0k
      }
3097
292k
    } else {
3098
825k
      for (i = 0; i < noPatches; i++) {
3099
532k
        patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
3100
532k
      }
3101
292k
    }
3102
331k
    patchBorders[i] = highSubband - lowSubband;
3103
3104
    /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
3105
2.53M
    for (k = 0; k <= noFreqBands; k++) {
3106
2.20M
      workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
3107
2.20M
    }
3108
712k
    for (k = 1; k < noPatches; k++) {
3109
380k
      workLimiterBandTable[noFreqBands + k] = patchBorders[k];
3110
380k
    }
3111
3112
331k
    tempNoLim = nBands = noFreqBands + noPatches - 1;
3113
331k
    shellsort(workLimiterBandTable, tempNoLim + 1);
3114
3115
331k
    loLimIndex = 0;
3116
331k
    hiLimIndex = 1;
3117
3118
2.47M
    while (hiLimIndex <= tempNoLim) {
3119
2.14M
      FIXP_DBL div_m, oct_m, temp;
3120
2.14M
      INT div_e = 0, oct_e = 0, temp_e = 0;
3121
3122
2.14M
      k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
3123
2.14M
      kx = workLimiterBandTable[loLimIndex] + lowSubband;
3124
3125
2.14M
      div_m = fDivNorm(k2, kx, &div_e);
3126
3127
      /* calculate number of octaves */
3128
2.14M
      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.14M
      temp = fMultNorm(
3133
2.14M
          oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands],
3134
2.14M
          &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.14M
      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.14M
      if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) {
3148
1.25M
        if (workLimiterBandTable[hiLimIndex] ==
3149
1.25M
            workLimiterBandTable[loLimIndex]) {
3150
65.1k
          workLimiterBandTable[hiLimIndex] = highSubband;
3151
65.1k
          nBands--;
3152
65.1k
          hiLimIndex++;
3153
65.1k
          continue;
3154
65.1k
        }
3155
1.18M
        isPatchBorder[0] = isPatchBorder[1] = 0;
3156
4.74M
        for (k = 0; k <= noPatches; k++) {
3157
3.95M
          if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
3158
396k
            isPatchBorder[1] = 1;
3159
396k
            break;
3160
396k
          }
3161
3.95M
        }
3162
1.18M
        if (!isPatchBorder[1]) {
3163
791k
          workLimiterBandTable[hiLimIndex] = highSubband;
3164
791k
          nBands--;
3165
791k
          hiLimIndex++;
3166
791k
          continue;
3167
791k
        }
3168
1.58M
        for (k = 0; k <= noPatches; k++) {
3169
1.36M
          if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
3170
174k
            isPatchBorder[0] = 1;
3171
174k
            break;
3172
174k
          }
3173
1.36M
        }
3174
396k
        if (!isPatchBorder[0]) {
3175
222k
          workLimiterBandTable[loLimIndex] = highSubband;
3176
222k
          nBands--;
3177
222k
        }
3178
396k
      }
3179
1.29M
      loLimIndex = hiLimIndex;
3180
1.29M
      hiLimIndex++;
3181
1.29M
    }
3182
331k
    shellsort(workLimiterBandTable, tempNoLim + 1);
3183
3184
    /* Test if algorithm exceeded maximum allowed limiterbands */
3185
331k
    if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
3186
3.79k
      return SBRDEC_UNSUPPORTED_CONFIG;
3187
3.79k
    }
3188
3189
    /* Restrict maximum value of limiter band table */
3190
327k
    if (workLimiterBandTable[tempNoLim] > highSubband) {
3191
1.00k
      return SBRDEC_UNSUPPORTED_CONFIG;
3192
1.00k
    }
3193
3194
    /* Copy limiterbands from working buffer into final destination */
3195
1.71M
    for (k = 0; k <= nBands; k++) {
3196
1.39M
      limiterBandTable[k] = workLimiterBandTable[k];
3197
1.39M
    }
3198
326k
  }
3199
331k
  *noLimiterBands = nBands;
3200
3201
331k
  return SBRDEC_OK;
3202
336k
}