Coverage Report

Created: 2023-03-26 06:13

/src/aac/libSBRdec/src/env_calc.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten
5
Forschung e.V. All rights reserved.
6
7
 1.    INTRODUCTION
8
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10
scheme for digital audio. This FDK AAC Codec software is intended to be used on
11
a wide variety of Android devices.
12
13
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14
general perceptual audio codecs. AAC-ELD is considered the best-performing
15
full-bandwidth communications codec by independent studies and is widely
16
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17
specifications.
18
19
Patent licenses for necessary patent claims for the FDK AAC Codec (including
20
those of Fraunhofer) may be obtained through Via Licensing
21
(www.vialicensing.com) or through the respective patent owners individually for
22
the purpose of encoding or decoding bit streams in products that are compliant
23
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24
Android devices already license these patent claims through Via Licensing or
25
directly from the patent owners, and therefore FDK AAC Codec software may
26
already be covered under those patent licenses when it is used for those
27
licensed purposes only.
28
29
Commercially-licensed AAC software libraries, including floating-point versions
30
with enhanced sound quality, are also available from Fraunhofer. Users are
31
encouraged to check the Fraunhofer website for additional applications
32
information and documentation.
33
34
2.    COPYRIGHT LICENSE
35
36
Redistribution and use in source and binary forms, with or without modification,
37
are permitted without payment of copyright license fees provided that you
38
satisfy the following conditions:
39
40
You must retain the complete text of this software license in redistributions of
41
the FDK AAC Codec or your modifications thereto in source code form.
42
43
You must retain the complete text of this software license in the documentation
44
and/or other materials provided with redistributions of the FDK AAC Codec or
45
your modifications thereto in binary form. You must make available free of
46
charge copies of the complete source code of the FDK AAC Codec and your
47
modifications thereto to recipients of copies in binary form.
48
49
The name of Fraunhofer may not be used to endorse or promote products derived
50
from this library without prior written permission.
51
52
You may not charge copyright license fees for anyone to use, copy or distribute
53
the FDK AAC Codec software or your modifications thereto.
54
55
Your modified versions of the FDK AAC Codec must carry prominent notices stating
56
that you changed the software and the date of any change. For modified versions
57
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59
AAC Codec Library for Android."
60
61
3.    NO PATENT LICENSE
62
63
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65
Fraunhofer provides no warranty of patent non-infringement with respect to this
66
software.
67
68
You may use this FDK AAC Codec software or modifications thereto only for
69
purposes that are authorized by appropriate patent licenses.
70
71
4.    DISCLAIMER
72
73
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75
including but not limited to the implied warranties of merchantability and
76
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78
or consequential damages, including but not limited to procurement of substitute
79
goods or services; loss of use, data, or profits, or business interruption,
80
however caused and on any theory of liability, whether in contract, strict
81
liability, or tort (including negligence), arising in any way out of the use of
82
this software, even if advised of the possibility of such damage.
83
84
5.    CONTACT INFORMATION
85
86
Fraunhofer Institute for Integrated Circuits IIS
87
Attention: Audio and Multimedia Departments - FDK AAC LL
88
Am Wolfsmantel 33
89
91058 Erlangen, Germany
90
91
www.iis.fraunhofer.de/amm
92
amm-info@iis.fraunhofer.de
93
----------------------------------------------------------------------------- */
94
95
/**************************** SBR decoder library ******************************
96
97
   Author(s):
98
99
   Description:
100
101
*******************************************************************************/
102
103
/*!
104
  \file
105
  \brief  Envelope calculation
106
107
  The envelope adjustor compares the energies present in the transposed
108
  highband to the reference energies conveyed with the bitstream.
109
  The highband is amplified (sometimes) or attenuated (mostly) to the
110
  desired level.
111
112
  The spectral shape of the reference energies can be changed several times per
113
  frame if necessary. Each set of energy values corresponding to a certain range
114
  in time will be called an <em>envelope</em> here.
115
  The bitstream supports several frequency scales and two resolutions. Normally,
116
  one or more QMF-subbands are grouped to one SBR-band. An envelope contains
117
  reference energies for each SBR-band.
118
  In addition to the energy envelopes, noise envelopes are transmitted that
119
  define the ratio of energy which is generated by adding noise instead of
120
  transposing the lowband. The noise envelopes are given in a coarser time
121
  and frequency resolution.
122
  If a signal contains strong tonal components, synthetic sines can be
123
  generated in individual SBR bands.
124
125
  An overlap buffer of 6 QMF-timeslots is used to allow a more
126
  flexible alignment of the envelopes in time that is not restricted to the
127
  core codec's frame borders.
128
  Therefore the envelope adjustor has access to the spectral data of the
129
  current frame as well as the last 6 QMF-timeslots of the previous frame.
130
  However, in average only the data of 1 frame is being processed as
131
  the adjustor is called once per frame.
132
133
  Depending on the frequency range set in the bitstream, only QMF-subbands
134
  between <em>lowSubband</em> and <em>highSubband</em> are adjusted.
135
136
  Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a
137
  special Mantissa-Exponent format ( see  calculateSbrEnvelope() ) are being
138
  used. The main entry point for this modules is calculateSbrEnvelope().
139
140
  \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref
141
  documentationOverview
142
*/
143
144
#include "env_calc.h"
145
146
#include "sbrdec_freq_sca.h"
147
#include "env_extr.h"
148
#include "transcendent.h"
149
#include "sbr_ram.h"
150
#include "sbr_rom.h"
151
152
#include "genericStds.h" /* need FDKpow() for debug outputs */
153
154
27.0M
#define MAX_SFB_NRG_HEADROOM (1)
155
26.2M
#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
404k
{
259
404k
  int i;
260
404k
  int bitcount = 31;
261
404k
  ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0};
262
404k
  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
404k
  FDKmemset(sineMapped, 32,
281
404k
            MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */
282
404k
  FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG));
283
4.55M
  for (i = 0; i < nSfb; i++) {
284
4.14M
    ULONG maskSfb =
285
4.14M
        1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */
286
287
4.14M
    if (*curFlags & maskSfb) {          /* There is a sine in this band */
288
89.3k
      const int lsb = freqBandTable[0]; /* start of sbr range */
289
      /* qmf band to which sine should be added */
290
89.3k
      const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1;
291
89.3k
      const int qmfBandDiv32 = qmfBand >> 5;
292
89.3k
      const int maskQmfBand =
293
89.3k
          1 << (qmfBand &
294
89.3k
                31); /* mask to extract harmonic flag from prevFlags */
295
296
      /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */
297
89.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
89.3k
      sineMapped[qmfBand - lsb] =
305
89.3k
          (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv;
306
89.3k
      if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) {
307
85.9k
        harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand;
308
85.9k
      }
309
89.3k
    }
310
311
4.14M
    if (bitcount-- == 0) {
312
8.57k
      bitcount = 31;
313
8.57k
      curFlags++;
314
8.57k
    }
315
4.14M
  }
316
404k
  FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands,
317
404k
            sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE);
318
404k
}
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
115k
{
344
  /* Reset the output vector first */
345
115k
  FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */
346
347
115k
  if (trailingSbrFrame) {
348
    /* restore sineMapped[] of previous frame */
349
84.0k
    int i;
350
84.0k
    const int lsb = freqBandTable[0];
351
84.0k
    const int usb = freqBandTable[nSfb];
352
1.78M
    for (i = lsb; i < usb; i++) {
353
1.69M
      const int qmfBandDiv32 = i >> 5;
354
1.69M
      const int maskQmfBand =
355
1.69M
          1 << (i & 31); /* mask to extract harmonic flag from prevFlags */
356
357
      /* Two cases need to be distinguished ... */
358
1.69M
      if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) {
359
        /* the sine mapping already started last PVC frame -> seamlessly
360
         * continue */
361
402
        sineMapped[i - lsb] = 0;
362
1.69M
      } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) {
363
        /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts
364
         * in this frame */
365
542
        sineMapped[i - lsb] =
366
542
            *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots
367
                                                   ahead of last frame now */
368
542
      }
369
1.69M
    }
370
84.0k
  }
371
115k
  *sinusoidalPosPrev = sinusoidalPos;
372
115k
}
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
97.1k
{
385
97.1k
  FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */
386
97.1k
  SCHAR *nrgGain_e =
387
97.1k
      nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */
388
97.1k
  FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */
389
97.1k
  SCHAR *nrgEst_e =
390
97.1k
      nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */
391
97.1k
  int grouping = 0, index = 0, noGroups, k;
392
97.1k
  int groupVector[MAX_FREQ_COEFFS];
393
394
  /* Calculate grouping*/
395
1.52M
  for (k = 0; k < noSubbands - 1; k++) {
396
1.42M
    if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) {
397
62.1k
      if (grouping == 0) {
398
39.9k
        groupVector[index++] = k;
399
39.9k
        grouping = 1;
400
39.9k
      } else {
401
22.1k
        if (groupVector[index - 1] + 3 == k) {
402
0
          groupVector[index++] = k + 1;
403
0
          grouping = 0;
404
0
        }
405
22.1k
      }
406
1.36M
    } else {
407
1.36M
      if (grouping) {
408
36.4k
        if (useAliasReduction[k])
409
36.1k
          groupVector[index++] = k + 1;
410
280
        else
411
280
          groupVector[index++] = k;
412
36.4k
        grouping = 0;
413
36.4k
      }
414
1.36M
    }
415
1.42M
  }
416
417
97.1k
  if (grouping) {
418
3.59k
    groupVector[index++] = noSubbands;
419
3.59k
  }
420
97.1k
  noGroups = index >> 1;
421
422
  /*Calculate new gain*/
423
137k
  for (int group = 0; group < noGroups; group++) {
424
39.9k
    FIXP_DBL nrgOrig = FL2FXCONST_DBL(
425
39.9k
        0.0f); /* Original signal energy in current group of bands */
426
39.9k
    SCHAR nrgOrig_e = 0;
427
39.9k
    FIXP_DBL nrgAmp = FL2FXCONST_DBL(
428
39.9k
        0.0f); /* Amplified signal energy in group (using current gains) */
429
39.9k
    SCHAR nrgAmp_e = 0;
430
39.9k
    FIXP_DBL nrgMod = FL2FXCONST_DBL(
431
39.9k
        0.0f); /* Signal energy in group when applying modified gains */
432
39.9k
    SCHAR nrgMod_e = 0;
433
39.9k
    FIXP_DBL groupGain; /* Total energy gain in group */
434
39.9k
    SCHAR groupGain_e;
435
39.9k
    FIXP_DBL compensation; /* Compensation factor for the energy change when
436
                              applying modified gains */
437
39.9k
    SCHAR compensation_e;
438
439
39.9k
    int startGroup = groupVector[2 * group];
440
39.9k
    int stopGroup = groupVector[2 * group + 1];
441
442
    /* Calculate total energy in group before and after amplification with
443
     * current gains: */
444
141k
    for (k = startGroup; k < stopGroup; k++) {
445
      /* Get original band energy */
446
101k
      FIXP_DBL tmp = nrgEst[k];
447
101k
      SCHAR tmp_e = nrgEst_e[k];
448
449
101k
      FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e);
450
451
      /* Multiply band energy with current gain */
452
101k
      tmp = fMult(tmp, nrgGain[k]);
453
101k
      tmp_e = tmp_e + nrgGain_e[k];
454
455
101k
      FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e);
456
101k
    }
457
458
    /* Calculate total energy gain in group */
459
39.9k
    FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain,
460
39.9k
                       &groupGain_e);
461
462
141k
    for (k = startGroup; k < stopGroup; k++) {
463
101k
      FIXP_DBL tmp;
464
101k
      SCHAR tmp_e;
465
466
101k
      FIXP_DBL alpha = degreeAlias[k];
467
101k
      if (k < noSubbands - 1) {
468
98.2k
        if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1];
469
98.2k
      }
470
471
      /* Modify gain depending on the degree of aliasing */
472
101k
      FDK_add_MantExp(
473
101k
          fMult(alpha, groupGain), groupGain_e,
474
101k
          fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha,
475
101k
                nrgGain[k]),
476
101k
          nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]);
477
478
      /* Apply modified gain to original energy */
479
101k
      tmp = fMult(nrgGain[k], nrgEst[k]);
480
101k
      tmp_e = nrgGain_e[k] + nrgEst_e[k];
481
482
      /* Accumulate energy with modified gains applied */
483
101k
      FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e);
484
101k
    }
485
486
    /* Calculate compensation factor to retain the energy of the amplified
487
     * signal */
488
39.9k
    FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation,
489
39.9k
                       &compensation_e);
490
491
    /* Apply compensation factor to all gains of the group */
492
141k
    for (k = startGroup; k < stopGroup; k++) {
493
101k
      nrgGain[k] = fMult(nrgGain[k], compensation);
494
101k
      nrgGain_e[k] = nrgGain_e[k] + compensation_e;
495
101k
    }
496
39.9k
  }
497
97.1k
}
498
499
22.4M
#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
40.8k
                            const UCHAR gamma_idx) {
515
40.8k
  int highSubband = lowSubband + nbSubband;
516
40.8k
  FIXP_DBL *subsample_power_high, *subsample_power_low;
517
40.8k
  SCHAR *subsample_power_high_sf, *subsample_power_low_sf;
518
40.8k
  FIXP_DBL total_power_high = (FIXP_DBL)0;
519
40.8k
  FIXP_DBL total_power_low = (FIXP_DBL)0;
520
40.8k
  FIXP_DBL *gain;
521
40.8k
  int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))];
522
523
  /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */
524
40.8k
  int gamma_sf =
525
40.8k
      (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */
526
527
40.8k
  int nbSubsample = stopPos - startPos;
528
40.8k
  int i, j;
529
530
40.8k
  C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1);
531
40.8k
  subsample_power_high = pTmp->subsample_power_high;
532
40.8k
  subsample_power_low = pTmp->subsample_power_low;
533
40.8k
  subsample_power_high_sf = pTmp->subsample_power_high_sf;
534
40.8k
  subsample_power_low_sf = pTmp->subsample_power_low_sf;
535
40.8k
  gain = pTmp->gain;
536
537
40.8k
  if (gamma_idx > 0) {
538
19.0k
    int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample);
539
19.0k
    int total_power_low_sf = 1 - DFRACT_BITS;
540
19.0k
    int total_power_high_sf = 1 - DFRACT_BITS;
541
542
830k
    for (i = 0; i < nbSubsample; ++i) {
543
811k
      FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
544
811k
      FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
545
811k
      FIXP_DBL maxVal = (FIXP_DBL)0;
546
547
811k
      int ts = startPos + i;
548
549
811k
      int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale
550
811k
                                   : sbrScaleFactor->lb_scale;
551
811k
      low_sf = 15 - low_sf;
552
553
16.0M
      for (j = 0; j < lowSubband; ++j) {
554
15.2M
        bufferImag[j] = qmfImag[startPos + i][j];
555
15.2M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
556
15.2M
                             ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
557
15.2M
        bufferReal[j] = qmfReal[startPos + i][j];
558
15.2M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
559
15.2M
                             ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
560
15.2M
      }
561
562
811k
      subsample_power_low[i] = (FIXP_DBL)0;
563
811k
      subsample_power_low_sf[i] = 0;
564
565
811k
      if (maxVal != FL2FXCONST_DBL(0.f)) {
566
        /* multiply first, then shift for safe summation */
567
522k
        int preShift = 1 - CntLeadingZeros(maxVal);
568
522k
        int postShift = 32 - fNormz((FIXP_DBL)lowSubband);
569
570
        /* reduce preShift because otherwise we risk to square -1.f */
571
522k
        if (preShift != 0) preShift++;
572
573
522k
        subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1;
574
575
522k
        scaleValues(bufferReal, lowSubband, -preShift);
576
522k
        scaleValues(bufferImag, lowSubband, -preShift);
577
10.8M
        for (j = 0; j < lowSubband; ++j) {
578
10.3M
          FIXP_DBL addme;
579
10.3M
          addme = fPow2Div2(bufferReal[j]);
580
10.3M
          subsample_power_low[i] += addme >> postShift;
581
10.3M
          addme = fPow2Div2(bufferImag[j]);
582
10.3M
          subsample_power_low[i] += addme >> postShift;
583
10.3M
        }
584
522k
      }
585
586
      /* now get high */
587
588
811k
      maxVal = (FIXP_DBL)0;
589
590
811k
      int high_sf = exp[(ts < 16 * RATE) ? 0 : 1];
591
592
13.9M
      for (j = lowSubband; j < highSubband; ++j) {
593
13.1M
        bufferImag[j] = qmfImag[startPos + i][j];
594
13.1M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^
595
13.1M
                             ((LONG)bufferImag[j] >> (DFRACT_BITS - 1)));
596
13.1M
        bufferReal[j] = qmfReal[startPos + i][j];
597
13.1M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^
598
13.1M
                             ((LONG)bufferReal[j] >> (DFRACT_BITS - 1)));
599
13.1M
      }
600
601
811k
      subsample_power_high[i] = (FIXP_DBL)0;
602
811k
      subsample_power_high_sf[i] = 0;
603
604
811k
      if (maxVal != FL2FXCONST_DBL(0.f)) {
605
737k
        int preShift = 1 - CntLeadingZeros(maxVal);
606
        /* reduce preShift because otherwise we risk to square -1.f */
607
737k
        if (preShift != 0) preShift++;
608
609
737k
        int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband));
610
737k
        subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1;
611
612
737k
        scaleValues(&bufferReal[lowSubband], highSubband - lowSubband,
613
737k
                    -preShift);
614
737k
        scaleValues(&bufferImag[lowSubband], highSubband - lowSubband,
615
737k
                    -preShift);
616
11.2M
        for (j = lowSubband; j < highSubband; j++) {
617
10.5M
          subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift;
618
10.5M
          subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift;
619
10.5M
        }
620
737k
      }
621
622
      /* sum all together */
623
811k
      FIXP_DBL new_summand = subsample_power_low[i];
624
811k
      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
811k
      if (new_summand_sf > total_power_low_sf) {
628
39.3k
        int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf);
629
39.3k
        total_power_low >>= diff;
630
39.3k
        total_power_low_sf = new_summand_sf;
631
771k
      } else if (new_summand_sf < total_power_low_sf) {
632
265k
        new_summand >>=
633
265k
            fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf);
634
265k
      }
635
636
811k
      total_power_low += (new_summand >> preShift2);
637
638
811k
      new_summand = subsample_power_high[i];
639
811k
      new_summand_sf = subsample_power_high_sf[i];
640
811k
      if (new_summand_sf > total_power_high_sf) {
641
37.5k
        total_power_high >>=
642
37.5k
            fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf);
643
37.5k
        total_power_high_sf = new_summand_sf;
644
773k
      } else if (new_summand_sf < total_power_high_sf) {
645
384k
        new_summand >>=
646
384k
            fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf);
647
384k
      }
648
649
811k
      total_power_high += (new_summand >> preShift2);
650
811k
    }
651
652
19.0k
    total_power_low_sf += preShift2;
653
19.0k
    total_power_high_sf += preShift2;
654
655
    /* gain[i] = e_LOW[i] */
656
830k
    for (i = 0; i < nbSubsample; ++i) {
657
811k
      int sf2;
658
811k
      FIXP_DBL mult =
659
811k
          fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2);
660
811k
      int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2;
661
662
811k
      if (total_power_low != FIXP_DBL(0)) {
663
622k
        gain[i] = fDivNorm(mult, total_power_low, &sf2);
664
622k
        gain_sf[i] = mult_sf - total_power_low_sf + sf2;
665
622k
        gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]);
666
622k
        if (gain_sf[i] < 0) {
667
214k
          gain[i] >>= fMin(DFRACT_BITS - 1, -gain_sf[i]);
668
214k
          gain_sf[i] = 0;
669
214k
        }
670
622k
      } else {
671
188k
        if (mult == FIXP_DBL(0)) {
672
185k
          gain[i] = FIXP_DBL(0);
673
185k
          gain_sf[i] = 0;
674
185k
        } else {
675
2.47k
          gain[i] = (FIXP_DBL)MAXVAL_DBL;
676
2.47k
          gain_sf[i] = 0;
677
2.47k
        }
678
188k
      }
679
811k
    }
680
681
19.0k
    FIXP_DBL total_power_high_after = (FIXP_DBL)0;
682
19.0k
    int total_power_high_after_sf = 1 - DFRACT_BITS;
683
684
    /* gain[i] = g_inter[i] */
685
830k
    for (i = 0; i < nbSubsample; ++i) {
686
      /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */
687
811k
      FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >>
688
811k
                     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
811k
      FIXP_DBL mult = (gain[i] - one) >> 1;
693
811k
      int mult_sf = gain_sf[i] + gamma_sf;
694
695
811k
      one = FL2FXCONST_DBL(0.5f) >> mult_sf;
696
811k
      gain[i] = one + mult;
697
811k
      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
811k
      FIXP_DBL gain_pow2;
702
811k
      int gain_pow2_sf;
703
704
811k
      if (fIsLessThan(gain[i], gain_sf[i], FL2FXCONST_DBL(0.2f), 0)) {
705
454k
        gain[i] = FL2FXCONST_DBL(0.8f);
706
454k
        gain_sf[i] = -2;
707
454k
        gain_pow2 = FL2FXCONST_DBL(0.64f);
708
454k
        gain_pow2_sf = -4;
709
454k
      } else {
710
        /* this upscaling seems quite important */
711
357k
        int r = CountLeadingBits(gain[i]);
712
357k
        gain[i] <<= r;
713
357k
        gain_sf[i] -= r;
714
715
357k
        gain_pow2 = fPow2(gain[i]);
716
357k
        gain_pow2_sf = gain_sf[i] << 1;
717
357k
      }
718
719
811k
      int room;
720
811k
      subsample_power_high[i] =
721
811k
          fMultNorm(subsample_power_high[i], gain_pow2, &room);
722
811k
      subsample_power_high_sf[i] =
723
811k
          subsample_power_high_sf[i] + gain_pow2_sf + room;
724
725
811k
      int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */
726
811k
      if (new_summand_sf > total_power_high_after_sf) {
727
61.4k
        total_power_high_after >>=
728
61.4k
            fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf);
729
61.4k
        total_power_high_after_sf = new_summand_sf;
730
749k
      } else if (new_summand_sf < total_power_high_after_sf) {
731
535k
        subsample_power_high[i] >>=
732
535k
            fMin(DFRACT_BITS - 1, total_power_high_after_sf - new_summand_sf);
733
535k
      }
734
811k
      total_power_high_after += subsample_power_high[i] >> preShift2;
735
811k
    }
736
737
19.0k
    total_power_high_after_sf += preShift2;
738
739
19.0k
    int sf2 = 0;
740
19.0k
    FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f);
741
19.0k
    int gain_adj_2_sf = 1;
742
743
19.0k
    if ((total_power_high != (FIXP_DBL)0) &&
744
19.0k
        (total_power_high_after != (FIXP_DBL)0)) {
745
17.5k
      gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2);
746
17.5k
      gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2;
747
17.5k
    }
748
749
19.0k
    FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf);
750
19.0k
    int gain_adj_sf = gain_adj_2_sf;
751
752
830k
    for (i = 0; i < nbSubsample; ++i) {
753
811k
      int gain_e = fMax(
754
811k
          fMin(gain_sf[i] + gain_adj_sf - INTER_TES_SF_CHANGE, DFRACT_BITS - 1),
755
811k
          -(DFRACT_BITS - 1));
756
811k
      FIXP_DBL gain_final = fMult(gain[i], gain_adj);
757
811k
      gain_final = scaleValueSaturate(gain_final, gain_e);
758
759
13.9M
      for (j = lowSubband; j < highSubband; j++) {
760
13.1M
        qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain_final);
761
13.1M
        qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain_final);
762
13.1M
      }
763
811k
    }
764
21.7k
  } 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
828k
    for (i = 0; i < nbSubsample; ++i) {
768
11.6M
      for (j = lowSubband; j < highSubband; j++) {
769
10.7M
        qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE;
770
10.7M
        qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE;
771
10.7M
      }
772
806k
    }
773
21.7k
  }
774
40.8k
  C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1);
775
40.8k
}
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
404k
    const UINT flags, const int frameErrorFlag) {
877
404k
  int c, i, i_stop, j, envNoise = 0;
878
404k
  UCHAR *borders = hFrameData->frameInfo.borders;
879
404k
  UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders;
880
404k
  int pvc_mode = pPvcDynamicData->pvc_mode;
881
404k
  int first_start =
882
404k
      ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep;
883
404k
  FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel;
884
404k
  HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData;
885
404k
  UCHAR **pFreqBandTable = hFreq->freqBandTable;
886
404k
  UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise;
887
888
404k
  int lowSubband = hFreq->lowSubband;
889
404k
  int highSubband = hFreq->highSubband;
890
404k
  int noSubbands = highSubband - lowSubband;
891
892
  /* old high subband before headerchange
893
     we asume no headerchange here        */
894
404k
  int ov_highSubband = hFreq->highSubband;
895
896
404k
  int noNoiseBands = hFreq->nNfb;
897
404k
  UCHAR *noSubFrameBands = hFreq->nSfb;
898
404k
  int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep;
899
900
404k
  SCHAR sineMapped[MAX_FREQ_COEFFS];
901
404k
  SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale);
902
404k
  SCHAR adj_e = 0;
903
404k
  SCHAR output_e;
904
404k
  SCHAR final_e = 0;
905
  /* inter-TES is active in one or more envelopes of the current SBR frame */
906
404k
  const int iTES_enable = hFrameData->iTESactive;
907
404k
  const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0;
908
404k
  SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP;
909
910
404k
  UCHAR smooth_length = 0;
911
912
404k
  FIXP_SGL *pIenv = hFrameData->iEnvelope;
913
914
404k
  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
404k
  if (hFreq->highSubband < hFreq->ov_highSubband) {
921
27.7k
    ov_highSubband = hFreq->ov_highSubband;
922
27.7k
  }
923
924
404k
  if (pvc_mode > 0) {
925
115k
    if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) {
926
      /* noise envelope of previous frame is trailing into current PVC frame */
927
84.0k
      envNoise = -1;
928
84.0k
      noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel;
929
84.0k
      noNoiseBands = h_sbr_cal_env->prevNNfb;
930
84.0k
      noSubFrameBands = h_sbr_cal_env->prevNSfb;
931
84.0k
      lowSubband = h_sbr_cal_env->prevLoSubband;
932
84.0k
      highSubband = h_sbr_cal_env->prevHiSubband;
933
934
84.0k
      noSubbands = highSubband - lowSubband;
935
84.0k
      ov_highSubband = highSubband;
936
84.0k
      if (highSubband < h_sbr_cal_env->prev_ov_highSubband) {
937
7.49k
        ov_highSubband = h_sbr_cal_env->prev_ov_highSubband;
938
7.49k
      }
939
940
84.0k
      pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo;
941
84.0k
      pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi;
942
84.0k
      pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise;
943
84.0k
    }
944
945
115k
    mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1],
946
115k
                    h_sbr_cal_env->harmFlagsPrev,
947
115k
                    h_sbr_cal_env->harmFlagsPrevActive, sineMapped,
948
115k
                    hFrameData->sinusoidal_position,
949
115k
                    &h_sbr_cal_env->sinusoidal_positionPrev,
950
115k
                    (borders[0] > bordersPvc[0]) ? 1 : 0);
951
289k
  } else {
952
    /*
953
      Extract sine flags for all QMF bands
954
    */
955
289k
    mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
956
289k
                 hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
957
289k
                 h_sbr_cal_env->harmFlagsPrevActive,
958
289k
                 hFrameData->frameInfo.tranEnv, sineMapped);
959
289k
  }
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
404k
  if (!useLP)
969
329k
    adj_e = h_sbr_cal_env->filtBufferNoise_e -
970
329k
            getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands) +
971
329k
            (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
404k
  if (pvc_mode > 0) {
978
115k
    INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax;
979
980
    /* Energy -> magnitude (sqrt halfens exponent) */
981
115k
    maxSfbNrg_e =
982
115k
        (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
115k
    maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
992
993
115k
    adj_e = maxSfbNrg_e;
994
    // final_e should not exist for PVC fixfix framing
995
289k
  } else {
996
647k
    for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) {
997
358k
      INT maxSfbNrg_e =
998
358k
          -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */
999
1000
      /* Fetch frequency resolution for current envelope: */
1001
3.76M
      for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) {
1002
3.40M
        maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E));
1003
3.40M
      }
1004
358k
      maxSfbNrg_e -= NRG_EXP_OFFSET;
1005
1006
      /* Energy -> magnitude (sqrt halfens exponent) */
1007
358k
      maxSfbNrg_e =
1008
358k
          (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
358k
      maxSfbNrg_e += (6 + MAX_SFB_NRG_HEADROOM);
1018
1019
358k
      if (borders[i] < hHeaderData->numberTimeSlots)
1020
        /* This envelope affects timeslots that belong to the output frame */
1021
353k
        adj_e = fMax(maxSfbNrg_e, adj_e);
1022
1023
358k
      if (borders[i + 1] > hHeaderData->numberTimeSlots)
1024
        /* This envelope affects timeslots after the output frame */
1025
15.8k
        final_e = fMax(maxSfbNrg_e, final_e);
1026
358k
    }
1027
289k
  }
1028
  /*
1029
    Calculate adjustment factors and apply them for every envelope.
1030
  */
1031
404k
  pIenv = hFrameData->iEnvelope;
1032
1033
404k
  if (pvc_mode > 0) {
1034
    /* iterate over SBR time slots starting with bordersPvc[i] */
1035
115k
    i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to
1036
                          PVC */
1037
115k
    i_stop = PVC_NTIMESLOT;
1038
115k
    FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT);
1039
289k
  } else {
1040
    /* iterate over SBR envelopes starting with 0 */
1041
289k
    i = 0;
1042
289k
    i_stop = hFrameData->frameInfo.nEnvelopes;
1043
289k
  }
1044
2.60M
  for (; i < i_stop; i++) {
1045
2.20M
    int k, noNoiseFlag;
1046
2.20M
    SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale);
1047
2.20M
    C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1);
1048
1049
    /*
1050
      Helper variables.
1051
    */
1052
2.20M
    int start_pos, stop_pos, freq_res;
1053
2.20M
    if (pvc_mode > 0) {
1054
1.84M
      start_pos =
1055
1.84M
          hHeaderData->timeStep *
1056
1.84M
          i; /* Start-position in time (subband sample) for current envelope. */
1057
1.84M
      stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time
1058
                                                     (subband sample) for
1059
                                                     current envelope. */
1060
1.84M
      freq_res =
1061
1.84M
          hFrameData->frameInfo
1062
1.84M
              .freqRes[0]; /* Frequency resolution for current envelope. */
1063
1.84M
      FDK_ASSERT(
1064
1.84M
          freq_res ==
1065
1.84M
          hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]);
1066
1.84M
    } else {
1067
358k
      start_pos = hHeaderData->timeStep *
1068
358k
                  borders[i]; /* Start-position in time (subband sample) for
1069
                                 current envelope. */
1070
358k
      stop_pos = hHeaderData->timeStep *
1071
358k
                 borders[i + 1]; /* Stop-position in time (subband sample) for
1072
                                    current envelope. */
1073
358k
      freq_res =
1074
358k
          hFrameData->frameInfo
1075
358k
              .freqRes[i]; /* Frequency resolution for current envelope. */
1076
358k
    }
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
0
    FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS));
1084
1085
2.20M
    if (pvc_mode > 0) {
1086
      /* get predicted energy values from PVC module */
1087
1.84M
      expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef,
1088
1.84M
                    pNrgs->nrgRef_e);
1089
1090
1.84M
      if (i == borders[0]) {
1091
115k
        mapSineFlags(pFreqBandTable[1], noSubFrameBands[1],
1092
115k
                     hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev,
1093
115k
                     h_sbr_cal_env->harmFlagsPrevActive,
1094
115k
                     hFrameData->sinusoidal_position, sineMapped);
1095
115k
      }
1096
1097
1.84M
      if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1098
173k
        if (envNoise >= 0) {
1099
89.7k
          noiseLevels += noNoiseBands; /* The noise floor data is stored in a
1100
                                          row [noiseFloor1 noiseFloor2...].*/
1101
89.7k
        } else {
1102
          /* leave trailing noise envelope of past frame */
1103
84.0k
          noNoiseBands = hFreq->nNfb;
1104
84.0k
          noSubFrameBands = hFreq->nSfb;
1105
84.0k
          noiseLevels = hFrameData->sbrNoiseFloorLevel;
1106
1107
84.0k
          lowSubband = hFreq->lowSubband;
1108
84.0k
          highSubband = hFreq->highSubband;
1109
1110
84.0k
          noSubbands = highSubband - lowSubband;
1111
84.0k
          ov_highSubband = highSubband;
1112
84.0k
          if (highSubband < hFreq->ov_highSubband) {
1113
7.77k
            ov_highSubband = hFreq->ov_highSubband;
1114
7.77k
          }
1115
1116
84.0k
          pFreqBandTable[0] = hFreq->freqBandTableLo;
1117
84.0k
          pFreqBandTable[1] = hFreq->freqBandTableHi;
1118
84.0k
          pFreqBandTableNoise = hFreq->freqBandTableNoise;
1119
84.0k
        }
1120
173k
        envNoise++;
1121
173k
      }
1122
1.84M
    } 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
358k
      if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) {
1127
55.0k
        noiseLevels += noNoiseBands; /* The noise floor data is stored in a row
1128
                                        [noiseFloor1 noiseFloor2...].*/
1129
55.0k
        envNoise++;
1130
55.0k
      }
1131
358k
    }
1132
2.20M
    if (i == hFrameData->frameInfo.tranEnv ||
1133
2.20M
        i == h_sbr_cal_env->prevTranEnv) /* attack */
1134
13.9k
    {
1135
13.9k
      noNoiseFlag = 1;
1136
13.9k
      if (!useLP) smooth_length = 0; /* No smoothing on attacks! */
1137
2.19M
    } else {
1138
2.19M
      noNoiseFlag = 0;
1139
2.19M
      if (!useLP)
1140
2.10M
        smooth_length = (1 - hHeaderData->bs_data.smoothingLength)
1141
2.10M
                        << 2; /* can become either 0 or 4 */
1142
2.19M
    }
1143
1144
    /*
1145
      Energy estimation in transposed highband.
1146
    */
1147
2.20M
    if (hHeaderData->bs_data.interpolFreq)
1148
2.13M
      calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1149
2.13M
                        lowSubband, highSubband, start_pos, stop_pos, input_e,
1150
2.13M
                        pNrgs->nrgEst, pNrgs->nrgEst_e);
1151
73.8k
    else
1152
73.8k
      calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1153
73.8k
                    noSubFrameBands[freq_res], pFreqBandTable[freq_res],
1154
73.8k
                    start_pos, stop_pos, input_e, pNrgs->nrgEst,
1155
73.8k
                    pNrgs->nrgEst_e);
1156
1157
    /*
1158
      Calculate subband gains
1159
    */
1160
2.20M
    {
1161
2.20M
      UCHAR *table = pFreqBandTable[freq_res];
1162
2.20M
      UCHAR *pUiNoise =
1163
2.20M
          &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor
1164
                                      band. */
1165
1166
2.20M
      FIXP_SGL *pNoiseLevels = noiseLevels;
1167
1168
2.20M
      FIXP_DBL tmpNoise =
1169
2.20M
          FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1170
2.20M
      SCHAR tmpNoise_e =
1171
2.20M
          (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1172
1173
2.20M
      int cc = 0;
1174
2.20M
      c = 0;
1175
2.20M
      if (pvc_mode > 0) {
1176
9.10M
        for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1177
7.25M
          UCHAR sinePresentFlag = 0;
1178
7.25M
          int li = table[j];
1179
7.25M
          int ui = table[j + 1];
1180
1181
50.0M
          for (k = li; k < ui; k++) {
1182
42.7M
            sinePresentFlag |= (i >= sineMapped[cc]);
1183
42.7M
            cc++;
1184
42.7M
          }
1185
1186
50.0M
          for (k = li; k < ui; k++) {
1187
42.7M
            FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband];
1188
42.7M
            SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband];
1189
1190
42.7M
            if (k >= *pUiNoise) {
1191
2.45M
              tmpNoise =
1192
2.45M
                  FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1193
2.45M
              tmpNoise_e =
1194
2.45M
                  (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1195
1196
2.45M
              pUiNoise++;
1197
2.45M
            }
1198
1199
42.7M
            FDK_ASSERT(k >= lowSubband);
1200
1201
42.7M
            if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1202
1203
42.7M
            pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1204
42.7M
            pNrgs->nrgSine_e[c] = 0;
1205
1206
42.7M
            calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1207
42.7M
                            sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1208
1209
42.7M
            c++;
1210
42.7M
          }
1211
7.25M
        }
1212
1.84M
      } else {
1213
3.76M
        for (j = 0; j < noSubFrameBands[freq_res]; j++) {
1214
3.40M
          FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M));
1215
3.40M
          SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET;
1216
1217
3.40M
          UCHAR sinePresentFlag = 0;
1218
3.40M
          int li = table[j];
1219
3.40M
          int ui = table[j + 1];
1220
1221
11.2M
          for (k = li; k < ui; k++) {
1222
7.87M
            sinePresentFlag |= (i >= sineMapped[cc]);
1223
7.87M
            cc++;
1224
7.87M
          }
1225
1226
11.2M
          for (k = li; k < ui; k++) {
1227
7.87M
            if (k >= *pUiNoise) {
1228
448k
              tmpNoise =
1229
448k
                  FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M));
1230
448k
              tmpNoise_e =
1231
448k
                  (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET;
1232
1233
448k
              pUiNoise++;
1234
448k
            }
1235
1236
7.87M
            FDK_ASSERT(k >= lowSubband);
1237
1238
7.87M
            if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag;
1239
1240
7.87M
            pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f);
1241
7.87M
            pNrgs->nrgSine_e[c] = 0;
1242
1243
7.87M
            calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e,
1244
7.87M
                            sinePresentFlag, i >= sineMapped[c], noNoiseFlag);
1245
1246
7.87M
            pNrgs->nrgRef[c] = refNrg;
1247
7.87M
            pNrgs->nrgRef_e[c] = refNrg_e;
1248
1249
7.87M
            c++;
1250
7.87M
          }
1251
3.40M
          pIenv++;
1252
3.40M
        }
1253
358k
      }
1254
2.20M
    }
1255
1256
    /*
1257
      Noise limiting
1258
    */
1259
1260
9.38M
    for (c = 0; c < hFreq->noLimiterBands; c++) {
1261
7.18M
      FIXP_DBL sumRef, boostGain, maxGain;
1262
7.18M
      FIXP_DBL accu = FL2FXCONST_DBL(0.0f);
1263
7.18M
      SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0;
1264
7.18M
      int maxGainLimGainSum_e = 0;
1265
1266
7.18M
      calcAvgGain(pNrgs, hFreq->limiterBandTable[c],
1267
7.18M
                  hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain,
1268
7.18M
                  &maxGain_e);
1269
1270
      /* Multiply maxGain with limiterGain: */
1271
7.18M
      maxGain = fMult(
1272
7.18M
          maxGain,
1273
7.18M
          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.18M
      maxGainLimGainSum_e =
1281
7.18M
          maxGain_e +
1282
7.18M
          FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains];
1283
7.18M
      maxGain_e =
1284
7.18M
          (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e;
1285
1286
      /* Scale mantissa of MaxGain into range between 0.5 and 1: */
1287
7.18M
      if (maxGain == FL2FXCONST_DBL(0.0f))
1288
371
        maxGain_e = -FRACT_BITS;
1289
7.18M
      else {
1290
7.18M
        SCHAR charTemp = CountLeadingBits(maxGain);
1291
7.18M
        maxGain_e -= charTemp;
1292
7.18M
        maxGain <<= (int)charTemp;
1293
7.18M
      }
1294
1295
7.18M
      if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */
1296
1.55M
        maxGain = FL2FXCONST_DBL(0.5f);
1297
1.55M
        maxGain_e = maxGainLimit_e;
1298
1.55M
      }
1299
1300
      /* Every subband gain is compared to the scaled "average gain"
1301
         and limited if necessary: */
1302
57.8M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1303
50.6M
           k++) {
1304
50.6M
        if ((pNrgs->nrgGain_e[k] > maxGain_e) ||
1305
50.6M
            (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) {
1306
18.3M
          FIXP_DBL noiseAmp;
1307
18.3M
          SCHAR noiseAmp_e;
1308
1309
18.3M
          FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k],
1310
18.3M
                             pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e);
1311
18.3M
          pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp);
1312
18.3M
          pNrgs->noiseLevel_e[k] += noiseAmp_e;
1313
18.3M
          pNrgs->nrgGain[k] = maxGain;
1314
18.3M
          pNrgs->nrgGain_e[k] = maxGain_e;
1315
18.3M
        }
1316
50.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
57.8M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1325
50.6M
           k++) {
1326
        /* 1.a  Add energy of adjusted signal (using preliminary gain) */
1327
50.6M
        FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]);
1328
50.6M
        SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k];
1329
50.6M
        FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e);
1330
1331
        /* 1.b  Add sine energy (if present) */
1332
50.6M
        if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) {
1333
111k
          FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e,
1334
111k
                          &accu, &accu_e);
1335
50.5M
        } else {
1336
          /* 1.c  Add noise energy (if present) */
1337
50.5M
          if (noNoiseFlag == 0) {
1338
50.2M
            FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu,
1339
50.2M
                            accu_e, &accu, &accu_e);
1340
50.2M
          }
1341
50.5M
        }
1342
50.6M
      }
1343
1344
      /* 2.a  Calculate ratio of wanted energy and accumulated energy */
1345
7.18M
      if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */
1346
857k
        boostGain = FL2FXCONST_DBL(0.6279716f);
1347
857k
        boostGain_e = 2;
1348
6.32M
      } else {
1349
6.32M
        INT div_e;
1350
6.32M
        boostGain = fDivNorm(sumRef, accu, &div_e);
1351
6.32M
        boostGain_e = sumRef_e - accu_e + div_e;
1352
6.32M
      }
1353
1354
      /* 2.b Result too high? --> Limit the boost factor to +4 dB */
1355
7.18M
      if ((boostGain_e > 3) ||
1356
7.18M
          (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) ||
1357
7.18M
          (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) {
1358
1.97M
        boostGain = FL2FXCONST_DBL(0.6279716f);
1359
1.97M
        boostGain_e = 2;
1360
1.97M
      }
1361
      /* 3.  Multiply all signal components with the boost factor */
1362
57.8M
      for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1];
1363
50.6M
           k++) {
1364
50.6M
        pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain);
1365
50.6M
        pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1;
1366
1367
50.6M
        pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain);
1368
50.6M
        pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1;
1369
1370
50.6M
        pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain);
1371
50.6M
        pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1;
1372
50.6M
      }
1373
7.18M
    }
1374
    /* End of noise limiting */
1375
1376
2.20M
    if (useLP)
1377
97.1k
      aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction,
1378
97.1k
                        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.20M
    noise_e = (start_pos < no_cols) ? adj_e : final_e;
1387
1388
2.20M
    if (start_pos >= no_cols) {
1389
4.87k
      int diff = h_sbr_cal_env->filtBufferNoise_e - noise_e;
1390
4.87k
      if (diff > 0) {
1391
119
        int s = getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands);
1392
119
        if (diff > s) {
1393
28
          final_e += diff - s;
1394
28
          noise_e = final_e;
1395
28
        }
1396
119
      }
1397
4.87k
    }
1398
1399
    /*
1400
      Convert energies to amplitude levels
1401
    */
1402
52.8M
    for (k = 0; k < noSubbands; k++) {
1403
50.6M
      FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e);
1404
50.6M
      FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k],
1405
50.6M
                       &pNrgs->nrgGain_e[k]);
1406
50.6M
      FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k],
1407
50.6M
                       &noise_e);
1408
50.6M
    }
1409
1410
    /*
1411
      Apply calculated gains and adaptive noise
1412
    */
1413
1414
    /* assembleHfSignals() */
1415
2.20M
    {
1416
2.20M
      int scale_change, sc_change;
1417
2.20M
      FIXP_SGL smooth_ratio;
1418
2.20M
      int filtBufferNoiseShift = 0;
1419
1420
      /* Initialize smoothing buffers with the first valid values */
1421
2.20M
      if (h_sbr_cal_env->startUp) {
1422
110k
        if (!useLP) {
1423
86.9k
          h_sbr_cal_env->filtBufferNoise_e = noise_e;
1424
1425
86.9k
          FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1426
86.9k
                    noSubbands * sizeof(SCHAR));
1427
86.9k
          FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1428
86.9k
                    noSubbands * sizeof(FIXP_DBL));
1429
86.9k
          FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1430
86.9k
                    noSubbands * sizeof(FIXP_DBL));
1431
86.9k
        }
1432
110k
        h_sbr_cal_env->startUp = 0;
1433
110k
      }
1434
1435
2.20M
      if (!useLP) {
1436
2.10M
        equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer,   /* buffered */
1437
2.10M
                              h_sbr_cal_env->filtBuffer_e, /* buffered */
1438
2.10M
                              pNrgs->nrgGain,              /* current  */
1439
2.10M
                              pNrgs->nrgGain_e,            /* current  */
1440
2.10M
                              noSubbands);
1441
1442
        /* Adapt exponent of buffered noise levels to the current exponent
1443
           so they can easily be smoothed */
1444
2.10M
        if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) {
1445
2.07M
          int shift = fixMin(DFRACT_BITS - 1,
1446
2.07M
                             (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1447
50.5M
          for (k = 0; k < noSubbands; k++)
1448
48.4M
            h_sbr_cal_env->filtBufferNoise[k] <<= shift;
1449
2.07M
        } else {
1450
28.7k
          int shift =
1451
28.7k
              fixMin(DFRACT_BITS - 1,
1452
28.7k
                     -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e));
1453
723k
          for (k = 0; k < noSubbands; k++)
1454
694k
            h_sbr_cal_env->filtBufferNoise[k] >>= shift;
1455
28.7k
        }
1456
1457
2.10M
        h_sbr_cal_env->filtBufferNoise_e = noise_e;
1458
2.10M
      }
1459
1460
      /* find best scaling! */
1461
2.20M
      scale_change = -(DFRACT_BITS - 1);
1462
52.8M
      for (k = 0; k < noSubbands; k++) {
1463
50.6M
        scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]);
1464
50.6M
      }
1465
2.20M
      sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e;
1466
1467
2.20M
      if ((scale_change - sc_change + 1) < 0)
1468
730k
        scale_change -= (scale_change - sc_change + 1);
1469
1470
2.20M
      scale_change = (scale_change - sc_change) + 1;
1471
1472
52.8M
      for (k = 0; k < noSubbands; k++) {
1473
50.6M
        int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1);
1474
50.6M
        pNrgs->nrgGain[k] >>= fixMin(sc, DFRACT_BITS - 1);
1475
50.6M
        pNrgs->nrgGain_e[k] += sc;
1476
50.6M
      }
1477
1478
2.20M
      if (!useLP) {
1479
51.2M
        for (k = 0; k < noSubbands; k++) {
1480
49.1M
          int sc =
1481
49.1M
              scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1);
1482
49.1M
          h_sbr_cal_env->filtBuffer[k] >>= fixMin(sc, DFRACT_BITS - 1);
1483
49.1M
        }
1484
2.10M
      }
1485
1486
16.4M
      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
14.2M
        if ((j == no_cols) && (start_pos < no_cols)) {
1495
10.9k
          int shift = (int)(noise_e - final_e);
1496
10.9k
          if (!useLP)
1497
5.42k
            filtBufferNoiseShift = shift; /* shifting of
1498
                                             h_sbr_cal_env->filtBufferNoise[k]
1499
                                             will be applied in function
1500
                                             adjustTimeSlotHQ() */
1501
10.9k
          if (shift >= 0) {
1502
7.08k
            shift = fixMin(DFRACT_BITS - 1, shift);
1503
174k
            for (k = 0; k < noSubbands; k++) {
1504
166k
              pNrgs->nrgSine[k] <<= shift;
1505
166k
              pNrgs->noiseLevel[k] <<= shift;
1506
              /*
1507
              if (!useLP)
1508
                h_sbr_cal_env->filtBufferNoise[k]  <<= shift;
1509
              */
1510
166k
            }
1511
7.08k
          } else {
1512
3.89k
            shift = fixMin(DFRACT_BITS - 1, -shift);
1513
31.4k
            for (k = 0; k < noSubbands; k++) {
1514
27.5k
              pNrgs->nrgSine[k] >>= shift;
1515
27.5k
              pNrgs->noiseLevel[k] >>= shift;
1516
              /*
1517
              if (!useLP)
1518
                h_sbr_cal_env->filtBufferNoise[k]  >>= shift;
1519
              */
1520
27.5k
            }
1521
3.89k
          }
1522
1523
          /* update noise scaling */
1524
10.9k
          noise_e = final_e;
1525
10.9k
          if (!useLP)
1526
5.42k
            h_sbr_cal_env->filtBufferNoise_e =
1527
5.42k
                noise_e; /* scaling value unused! */
1528
1529
          /* update gain buffer*/
1530
10.9k
          sc_change -= (final_e - input_e);
1531
1532
10.9k
          if (sc_change < 0) {
1533
31.4k
            for (k = 0; k < noSubbands; k++) {
1534
27.5k
              pNrgs->nrgGain[k] >>= -sc_change;
1535
27.5k
              pNrgs->nrgGain_e[k] += -sc_change;
1536
27.5k
            }
1537
3.89k
            if (!useLP) {
1538
25.8k
              for (k = 0; k < noSubbands; k++) {
1539
22.2k
                h_sbr_cal_env->filtBuffer[k] >>= -sc_change;
1540
22.2k
              }
1541
3.60k
            }
1542
7.08k
          } else {
1543
7.08k
            scale_change += sc_change;
1544
7.08k
          }
1545
1546
10.9k
        } /* if */
1547
1548
14.2M
        if (!useLP) {
1549
          /* Prevent the smoothing filter from running on constant levels */
1550
12.0M
          if (j - start_pos < smooth_length)
1551
3.24M
            smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos];
1552
8.82M
          else
1553
8.82M
            smooth_ratio = FL2FXCONST_SGL(0.0f);
1554
1555
12.0M
          if (iTES_enable) {
1556
            /* adjustTimeSlotHQ() without adding of additional harmonics */
1557
1.61M
            adjustTimeSlotHQ_GainAndNoise(
1558
1.61M
                &analysBufferReal[j][lowSubband],
1559
1.61M
                &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1560
1.61M
                lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1),
1561
1.61M
                smooth_ratio, noNoiseFlag, filtBufferNoiseShift);
1562
10.4M
          } else {
1563
10.4M
            adjustTimeSlotHQ(&analysBufferReal[j][lowSubband],
1564
10.4M
                             &analysBufferImag[j][lowSubband], h_sbr_cal_env,
1565
10.4M
                             pNrgs, lowSubband, noSubbands,
1566
10.4M
                             fMin(scale_change, DFRACT_BITS - 1), smooth_ratio,
1567
10.4M
                             noNoiseFlag, filtBufferNoiseShift);
1568
10.4M
          }
1569
12.0M
        } else {
1570
2.14M
          FDK_ASSERT(!iTES_enable); /* not supported */
1571
2.14M
          if (flags & SBRDEC_ELD_GRID) {
1572
            /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */
1573
237k
            adjustTimeSlot_EldGrid(
1574
237k
                &analysBufferReal[j][lowSubband], pNrgs,
1575
237k
                &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1576
237k
                fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1577
237k
                &h_sbr_cal_env->phaseIndex,
1578
237k
                fMax(EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale,
1579
237k
                     -(DFRACT_BITS - 1)));
1580
1.90M
          } else {
1581
1.90M
            adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs,
1582
1.90M
                             &h_sbr_cal_env->harmIndex, lowSubband, noSubbands,
1583
1.90M
                             fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag,
1584
1.90M
                             &h_sbr_cal_env->phaseIndex);
1585
1.90M
          }
1586
2.14M
        }
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
14.2M
        pNrgs->exponent[(j < no_cols) ? 0 : 1] =
1592
14.2M
            (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 -
1593
14.2M
                    scale_change);
1594
14.2M
      } /* for */
1595
1596
2.20M
      if (iTES_enable) {
1597
40.8k
        apply_inter_tes(
1598
40.8k
            analysBufferReal, /* pABufR, */
1599
40.8k
            analysBufferImag, /* pABufI, */
1600
40.8k
            sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos,
1601
40.8k
            stop_pos, lowSubband, noSubbands,
1602
40.8k
            hFrameData
1603
40.8k
                ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */
1604
40.8k
        );
1605
1606
        /* add additional harmonics */
1607
1.65M
        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.61M
          scale_change = 0;
1611
1612
1.61M
          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
128k
            scale_change = pNrgs->exponent[1] - pNrgs->exponent[0];
1618
128k
          }
1619
1620
1.61M
          adjustTimeSlotHQ_AddHarmonics(
1621
1.61M
              &analysBufferReal[j][lowSubband],
1622
1.61M
              &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs,
1623
1.61M
              lowSubband, noSubbands,
1624
1.61M
              -iTES_scale_change + ((j < no_cols) ? scale_change : 0));
1625
1.61M
        }
1626
40.8k
      }
1627
1628
2.20M
      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.10M
        FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain,
1635
2.10M
                  noSubbands * sizeof(FIXP_DBL));
1636
2.10M
        FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e,
1637
2.10M
                  noSubbands * sizeof(SCHAR));
1638
2.10M
        FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel,
1639
2.10M
                  noSubbands * sizeof(FIXP_DBL));
1640
2.10M
      }
1641
2.20M
    }
1642
2.20M
    C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1);
1643
2.20M
  }
1644
1645
  /* adapt adj_e to the scale change caused by apply_inter_tes() */
1646
404k
  adj_e += iTES_scale_change;
1647
1648
  /* Rescale output samples */
1649
404k
  {
1650
404k
    FIXP_DBL maxVal;
1651
404k
    int ov_reserve, reserve;
1652
1653
    /* Determine headroom in old adjusted samples */
1654
404k
    maxVal =
1655
404k
        maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1656
404k
                         lowSubband, ov_highSubband, 0, first_start);
1657
1658
404k
    ov_reserve = fNorm(maxVal);
1659
1660
    /* Determine headroom in new adjusted samples */
1661
404k
    maxVal =
1662
404k
        maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1663
404k
                         lowSubband, highSubband, first_start, no_cols);
1664
1665
404k
    reserve = fNorm(maxVal);
1666
1667
    /* Determine common output exponent */
1668
404k
    output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve);
1669
1670
    /* Rescale old samples */
1671
404k
    rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1672
404k
                          lowSubband, ov_highSubband, 0, first_start,
1673
404k
                          ov_adj_e - output_e);
1674
1675
    /* Rescale new samples */
1676
404k
    rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag,
1677
404k
                          lowSubband, highSubband, first_start, no_cols,
1678
404k
                          adj_e - output_e);
1679
404k
  }
1680
1681
  /* Update hb_scale */
1682
404k
  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
404k
  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
404k
  if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes)
1691
4.40k
    h_sbr_cal_env->prevTranEnv = 0;
1692
400k
  else
1693
400k
    h_sbr_cal_env->prevTranEnv = -1;
1694
1695
404k
  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
115k
    FDK_ASSERT(hFrameData->frameInfo
1699
0
                   .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] <
1700
0
               PVC_NTIMESLOT);
1701
115k
    if (hFrameData->frameInfo
1702
115k
            .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] >
1703
115k
        PVC_NTIMESLOT) {
1704
88.7k
      FDK_ASSERT(noiseLevels ==
1705
0
                 (hFrameData->sbrNoiseFloorLevel +
1706
0
                  (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands));
1707
0
      h_sbr_cal_env->prevNNfb = noNoiseBands;
1708
1709
88.7k
      h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0];
1710
88.7k
      h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1];
1711
1712
88.7k
      h_sbr_cal_env->prevLoSubband = lowSubband;
1713
88.7k
      h_sbr_cal_env->prevHiSubband = highSubband;
1714
88.7k
      h_sbr_cal_env->prev_ov_highSubband = ov_highSubband;
1715
1716
88.7k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0],
1717
88.7k
                noSubFrameBands[0] + 1);
1718
88.7k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1],
1719
88.7k
                noSubFrameBands[1] + 1);
1720
88.7k
      FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise,
1721
88.7k
                hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise));
1722
1723
88.7k
      FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels,
1724
88.7k
                MAX_NOISE_COEFFS * sizeof(FIXP_SGL));
1725
88.7k
    }
1726
115k
  }
1727
1728
404k
  C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64)
1729
404k
}
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
241k
    const UINT flags) {
1746
241k
  SBR_ERROR err = SBRDEC_OK;
1747
241k
  int i;
1748
1749
  /* Clear previous missing harmonics flags */
1750
725k
  for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) {
1751
483k
    hs->harmFlagsPrev[i] = 0;
1752
483k
    hs->harmFlagsPrevActive[i] = 0;
1753
483k
  }
1754
241k
  hs->harmIndex = 0;
1755
1756
241k
  FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel));
1757
241k
  hs->prevNNfb = 0;
1758
241k
  FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise));
1759
241k
  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
241k
  hs->prevTranEnv = -1;
1766
1767
  /* initialization */
1768
241k
  resetSbrEnvelopeCalc(hs);
1769
1770
241k
  if (chan == 0) { /* do this only once */
1771
156k
    err = resetFreqBandTables(hHeaderData, flags);
1772
156k
  }
1773
1774
241k
  return err;
1775
241k
}
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
249k
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
645k
{
1798
645k
  hCalEnv->phaseIndex = 0;
1799
1800
  /* Noise exponent needs to be reset because the output exponent for the next
1801
   * frame depends on it */
1802
645k
  hCalEnv->filtBufferNoise_e = 0;
1803
1804
645k
  hCalEnv->startUp = 1;
1805
645k
}
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.10M
{
1821
2.10M
  int band;
1822
2.10M
  int diff;
1823
1824
51.2M
  for (band = 0; band < subbands; band++) {
1825
49.1M
    diff = (int)(nrgGain_e[band] - filtBuffer_e[band]);
1826
49.1M
    if (diff > 0) {
1827
2.18M
      filtBuffer[band] >>=
1828
2.18M
          fMin(diff, DFRACT_BITS - 1); /* Compensate for the scale change by
1829
                                          shifting the mantissa. */
1830
2.18M
      filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */
1831
46.9M
    } else if (diff < 0) {
1832
      /* The buffered gains seem to be larger, but maybe there
1833
         are some unused bits left in the mantissa */
1834
1835
38.0M
      int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1;
1836
1837
38.0M
      if ((-diff) <= reserve) {
1838
        /* There is enough space in the buffered mantissa so
1839
           that we can take the new exponent as common.
1840
        */
1841
33.2M
        filtBuffer[band] <<= (-diff);
1842
33.2M
        filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */
1843
33.2M
      } else {
1844
4.82M
        filtBuffer[band] <<=
1845
4.82M
            reserve; /* Shift the mantissa as far as possible: */
1846
4.82M
        filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */
1847
1848
        /* For the remaining difference, change the new gain value */
1849
4.82M
        diff = -(reserve + diff);
1850
4.82M
        nrgGain[band] >>= fMin(diff, DFRACT_BITS - 1);
1851
4.82M
        nrgGain_e[band] += diff;
1852
4.82M
      }
1853
38.0M
    }
1854
49.1M
  }
1855
2.10M
}
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.51M
{
1873
1.51M
  int width = highSubband - lowSubband;
1874
1875
1.51M
  if ((width > 0) && (shift != 0)) {
1876
1.39M
    if (im != NULL) {
1877
27.4M
      for (int l = start_pos; l < next_pos; l++) {
1878
26.4M
        scaleValues(&re[l][lowSubband], width, shift);
1879
26.4M
        scaleValues(&im[l][lowSubband], width, shift);
1880
26.4M
      }
1881
1.00M
    } else {
1882
7.96M
      for (int l = start_pos; l < next_pos; l++) {
1883
7.57M
        scaleValues(&re[l][lowSubband], width, shift);
1884
7.57M
      }
1885
394k
    }
1886
1.39M
  }
1887
1.51M
}
1888
1889
static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp,
1890
11.2M
                                           INT width) {
1891
11.2M
  maxVal = (FIXP_DBL)0;
1892
240M
  while (width-- != 0) {
1893
228M
    FIXP_DBL tmp = *(reTmp++);
1894
228M
    maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1)));
1895
228M
  }
1896
1897
11.2M
  return maxVal;
1898
11.2M
}
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
2.10M
) {
1917
2.10M
  FIXP_DBL maxVal = FL2FX_DBL(0.0f);
1918
2.10M
  unsigned int width = highSubband - lowSubband;
1919
1920
2.10M
  FDK_ASSERT(width <= (64));
1921
1922
2.10M
  if (width > 0) {
1923
2.10M
    if (im != NULL) {
1924
47.2M
      for (int l = start_pos; l < next_pos; l++) {
1925
45.6M
        int k = width;
1926
45.6M
        FIXP_DBL *reTmp = &re[l][lowSubband];
1927
45.6M
        FIXP_DBL *imTmp = &im[l][lowSubband];
1928
675M
        do {
1929
675M
          FIXP_DBL tmp1 = *(reTmp++);
1930
675M
          FIXP_DBL tmp2 = *(imTmp++);
1931
675M
          maxVal |=
1932
675M
              (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1)));
1933
675M
          maxVal |=
1934
675M
              (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1)));
1935
675M
        } while (--k != 0);
1936
45.6M
      }
1937
1.55M
    } else {
1938
11.8M
      for (int l = start_pos; l < next_pos; l++) {
1939
11.2M
        maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width);
1940
11.2M
      }
1941
547k
    }
1942
2.10M
  }
1943
1944
2.10M
  if (maxVal > (FIXP_DBL)0) {
1945
    /* For negative input values, maxVal is too small by 1. Add 1 only when
1946
     * necessary: if maxVal is a power of 2 */
1947
1.08M
    FIXP_DBL lowerPow2 =
1948
1.08M
        (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal)));
1949
1.08M
    if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1;
1950
1.08M
  }
1951
1952
2.10M
  return (maxVal);
1953
2.10M
}
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
29.7M
#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.13M
{
1995
2.13M
  FIXP_SGL invWidth;
1996
2.13M
  SCHAR preShift;
1997
2.13M
  SCHAR shift;
1998
2.13M
  FIXP_DBL sum;
1999
2.13M
  int k;
2000
2001
  /* Divide by width of envelope later: */
2002
2.13M
  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.13M
  frameExp = frameExp << 1;
2006
2007
51.4M
  for (k = lowSubband; k < highSubband; k++) {
2008
49.2M
    FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2009
49.2M
    FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))];
2010
49.2M
    FIXP_DBL maxVal;
2011
2012
49.2M
    if (analysBufferImag != NULL) {
2013
48.1M
      int l;
2014
48.1M
      maxVal = FL2FX_DBL(0.0f);
2015
303M
      for (l = start_pos; l < next_pos; l++) {
2016
255M
        bufferImag[l] = analysBufferImag[l][k];
2017
255M
        maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^
2018
255M
                             ((LONG)bufferImag[l] >> (DFRACT_BITS - 1)));
2019
255M
        bufferReal[l] = analysBufferReal[l][k];
2020
255M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2021
255M
                             ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2022
255M
      }
2023
48.1M
    } else {
2024
1.14M
      int l;
2025
1.14M
      maxVal = FL2FX_DBL(0.0f);
2026
33.4M
      for (l = start_pos; l < next_pos; l++) {
2027
32.3M
        bufferReal[l] = analysBufferReal[l][k];
2028
32.3M
        maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^
2029
32.3M
                             ((LONG)bufferReal[l] >> (DFRACT_BITS - 1)));
2030
32.3M
      }
2031
1.14M
    }
2032
2033
49.2M
    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
29.4M
      FIXP_DBL accu;
2041
29.4M
      preShift = CntLeadingZeros(maxVal) - 1;
2042
29.4M
      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
29.4M
      preShift = fMin(preShift, (SCHAR)25);
2049
2050
29.4M
      accu = FL2FXCONST_DBL(0.0f);
2051
29.4M
      if (preShift >= 0) {
2052
28.0M
        int l;
2053
28.0M
        if (analysBufferImag != NULL) {
2054
150M
          for (l = start_pos; l < next_pos; l++) {
2055
122M
            FIXP_DBL temp1 = bufferReal[l] << (int)preShift;
2056
122M
            FIXP_DBL temp2 = bufferImag[l] << (int)preShift;
2057
122M
            accu = fPow2AddDiv2(accu, temp1);
2058
122M
            accu = fPow2AddDiv2(accu, temp2);
2059
122M
          }
2060
28.0M
        } else {
2061
843k
          for (l = start_pos; l < next_pos; l++) {
2062
796k
            FIXP_DBL temp = bufferReal[l] << (int)preShift;
2063
796k
            accu = fPow2AddDiv2(accu, temp);
2064
796k
          }
2065
46.8k
        }
2066
28.0M
      } else { /* if negative shift value */
2067
1.37M
        int l;
2068
1.37M
        int negpreShift = -preShift;
2069
1.37M
        if (analysBufferImag != NULL) {
2070
9.82M
          for (l = start_pos; l < next_pos; l++) {
2071
8.45M
            FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift;
2072
8.45M
            FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift;
2073
8.45M
            accu = fPow2AddDiv2(accu, temp1);
2074
8.45M
            accu = fPow2AddDiv2(accu, temp2);
2075
8.45M
          }
2076
1.37M
        } else {
2077
155k
          for (l = start_pos; l < next_pos; l++) {
2078
147k
            FIXP_DBL temp = bufferReal[l] >> (int)negpreShift;
2079
147k
            accu = fPow2AddDiv2(accu, temp);
2080
147k
          }
2081
8.03k
        }
2082
1.37M
      }
2083
29.4M
      accu <<= 1;
2084
2085
      /* Convert double precision to Mantissa/Exponent: */
2086
29.4M
      shift = fNorm(accu);
2087
29.4M
      sum = accu << (int)shift;
2088
2089
      /* Divide by width of envelope and apply frame scale: */
2090
29.4M
      *nrgEst++ = fMult(sum, invWidth);
2091
29.4M
      shift += 2 * preShift;
2092
29.4M
      if (analysBufferImag != NULL)
2093
29.4M
        *nrgEst_e++ = frameExp - shift;
2094
54.9k
      else
2095
54.9k
        *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */
2096
29.4M
    }                                       /* maxVal!=0 */
2097
19.8M
    else {
2098
      /* Prevent a zero-mantissa-number from being misinterpreted
2099
         due to its exponent. */
2100
19.8M
      *nrgEst++ = FL2FXCONST_DBL(0.0f);
2101
19.8M
      *nrgEst_e++ = 0;
2102
19.8M
    }
2103
49.2M
  }
2104
2.13M
}
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
73.8k
{
2123
73.8k
  FIXP_SGL invWidth;
2124
73.8k
  FIXP_DBL temp;
2125
73.8k
  SCHAR preShift;
2126
73.8k
  SCHAR shift, sum_e;
2127
73.8k
  FIXP_DBL sum;
2128
2129
73.8k
  int j, k, l, li, ui;
2130
73.8k
  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
73.8k
  invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos));
2135
  /* The common exponent needs to be doubled because all mantissas are squared:
2136
   */
2137
73.8k
  input_e = input_e << 1;
2138
2139
654k
  for (j = 0; j < nSfb; j++) {
2140
580k
    li = freqBandTable[j];
2141
580k
    ui = freqBandTable[j + 1];
2142
2143
580k
    FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li,
2144
580k
                                       ui, start_pos, next_pos);
2145
2146
580k
    if (maxVal != FL2FXCONST_DBL(0.f)) {
2147
303k
      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
303k
      preShift -= SHIFT_BEFORE_SQUARE;
2156
2157
303k
      sumAll = FL2FXCONST_DBL(0.0f);
2158
2159
783k
      for (k = li; k < ui; k++) {
2160
479k
        sumLine = FL2FXCONST_DBL(0.0f);
2161
2162
479k
        if (analysBufferImag != NULL) {
2163
394k
          if (preShift >= 0) {
2164
16.2M
            for (l = start_pos; l < next_pos; l++) {
2165
15.9M
              temp = analysBufferReal[l][k] << (int)preShift;
2166
15.9M
              sumLine += fPow2Div2(temp);
2167
15.9M
              temp = analysBufferImag[l][k] << (int)preShift;
2168
15.9M
              sumLine += fPow2Div2(temp);
2169
15.9M
            }
2170
375k
          } else {
2171
212k
            for (l = start_pos; l < next_pos; l++) {
2172
193k
              temp = analysBufferReal[l][k] >> -(int)preShift;
2173
193k
              sumLine += fPow2Div2(temp);
2174
193k
              temp = analysBufferImag[l][k] >> -(int)preShift;
2175
193k
              sumLine += fPow2Div2(temp);
2176
193k
            }
2177
19.6k
          }
2178
394k
        } else {
2179
84.6k
          if (preShift >= 0) {
2180
2.48M
            for (l = start_pos; l < next_pos; l++) {
2181
2.40M
              temp = analysBufferReal[l][k] << (int)preShift;
2182
2.40M
              sumLine += fPow2Div2(temp);
2183
2.40M
            }
2184
78.3k
          } else {
2185
160k
            for (l = start_pos; l < next_pos; l++) {
2186
154k
              temp = analysBufferReal[l][k] >> -(int)preShift;
2187
154k
              sumLine += fPow2Div2(temp);
2188
154k
            }
2189
6.36k
          }
2190
84.6k
        }
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
479k
        sumLine = sumLine >> (4 - 1);
2195
479k
        sumAll += sumLine;
2196
479k
      }
2197
2198
      /* Convert double precision to Mantissa/Exponent: */
2199
303k
      shift = fNorm(sumAll);
2200
303k
      sum = sumAll << (int)shift;
2201
2202
      /* Divide by width of envelope: */
2203
303k
      sum = fMult(sum, invWidth);
2204
2205
      /* Divide by width of Sfb: */
2206
303k
      sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li)));
2207
2208
      /* Set all Subband energies in the Sfb to the average energy: */
2209
303k
      if (analysBufferImag != NULL)
2210
276k
        sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */
2211
27.2k
      else
2212
27.2k
        sum_e = input_e + 4 + 1 -
2213
27.2k
                shift; /* -4 to compensate right-shift; +1 due to missing
2214
                          imag. part */
2215
2216
303k
      sum_e -= 2 * preShift;
2217
303k
    } /* maxVal!=0 */
2218
277k
    else {
2219
      /* Prevent a zero-mantissa-number from being misinterpreted
2220
         due to its exponent. */
2221
277k
      sum = FL2FXCONST_DBL(0.0f);
2222
277k
      sum_e = 0;
2223
277k
    }
2224
2225
1.93M
    for (k = li; k < ui; k++) {
2226
1.35M
      *nrgEst++ = sum;
2227
1.35M
      *nrgEst_e++ = sum_e;
2228
1.35M
    }
2229
580k
  }
2230
73.8k
}
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
50.6M
{
2247
50.6M
  FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */
2248
50.6M
  SCHAR nrgEst_e =
2249
50.6M
      nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */
2250
50.6M
  FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */
2251
50.6M
  SCHAR *ptrNrgGain_e =
2252
50.6M
      &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */
2253
50.6M
  FIXP_DBL *ptrNoiseLevel =
2254
50.6M
      &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */
2255
50.6M
  SCHAR *ptrNoiseLevel_e =
2256
50.6M
      &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */
2257
50.6M
  FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */
2258
50.6M
  SCHAR *ptrNrgSine_e =
2259
50.6M
      &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */
2260
2261
50.6M
  FIXP_DBL a, b, c;
2262
50.6M
  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
50.6M
  b_e = (int)(nrgEst_e - 1);
2270
50.6M
  if (b_e >= 0) {
2271
25.6M
    nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2272
25.6M
             (nrgEst >> 1);
2273
25.6M
    nrgEst_e += 1; /* shift by 1 bit to avoid overflow */
2274
2275
25.6M
  } else {
2276
24.9M
    nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2277
24.9M
             (FL2FXCONST_DBL(0.5f) >> 1);
2278
24.9M
    nrgEst_e = 2; /* shift by 1 bit to avoid overflow */
2279
24.9M
  }
2280
2281
  /*  A = NrgRef * TmpNoise */
2282
50.6M
  a = fMult(nrgRef, tmpNoise);
2283
50.6M
  a_e = nrgRef_e + tmpNoise_e;
2284
2285
  /*  B = 1 + TmpNoise */
2286
50.6M
  b_e = (int)(tmpNoise_e - 1);
2287
50.6M
  if (b_e >= 0) {
2288
10.7M
    b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) +
2289
10.7M
        (tmpNoise >> 1);
2290
10.7M
    b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */
2291
39.8M
  } else {
2292
39.8M
    b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) +
2293
39.8M
        (FL2FXCONST_DBL(0.5f) >> 1);
2294
39.8M
    b_e = 2; /* shift by 1 bit to avoid overflow */
2295
39.8M
  }
2296
2297
  /*  noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */
2298
50.6M
  FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e);
2299
2300
50.6M
  if (sinePresentFlag) {
2301
    /*  C = (1 + TmpNoise) * NrgEst */
2302
259k
    c = fMult(b, nrgEst);
2303
259k
    c_e = b_e + nrgEst_e;
2304
2305
    /*  gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */
2306
259k
    FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e);
2307
2308
259k
    if (sineMapped) {
2309
      /*  sineLevel = nrgRef/ (1 + TmpNoise) */
2310
111k
      FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e);
2311
111k
    }
2312
50.3M
  } else {
2313
50.3M
    if (noNoiseFlag) {
2314
      /*  B = NrgEst */
2315
273k
      b = nrgEst;
2316
273k
      b_e = nrgEst_e;
2317
50.1M
    } else {
2318
      /*  B = NrgEst * (1 + TmpNoise) */
2319
50.1M
      b = fMult(b, nrgEst);
2320
50.1M
      b_e = b_e + nrgEst_e;
2321
50.1M
    }
2322
2323
    /*  gain = nrgRef / B */
2324
50.3M
    INT result_exp = 0;
2325
50.3M
    *ptrNrgGain = fDivNorm(nrgRef, b, &result_exp);
2326
50.3M
    *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
50.3M
    int headroom = CountLeadingBits(*ptrNrgGain);
2331
50.3M
    *ptrNrgGain <<= headroom;
2332
50.3M
    *ptrNrgGain_e -= headroom;
2333
50.3M
  }
2334
50.6M
}
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.18M
{
2351
7.18M
  FIXP_DBL *nrgRef =
2352
7.18M
      nrgs->nrgRef; /*!< Reference Energy according to envelope data */
2353
7.18M
  SCHAR *nrgRef_e =
2354
7.18M
      nrgs->nrgRef_e; /*!< Reference Energy according to envelope data
2355
                         (exponent) */
2356
7.18M
  FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */
2357
7.18M
  SCHAR *nrgEst_e =
2358
7.18M
      nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */
2359
2360
7.18M
  FIXP_DBL sumRef = 1;
2361
7.18M
  FIXP_DBL sumEst = 1;
2362
7.18M
  SCHAR sumRef_e = -FRACT_BITS;
2363
7.18M
  SCHAR sumEst_e = -FRACT_BITS;
2364
7.18M
  int k;
2365
2366
57.8M
  for (k = lowSubband; k < highSubband; k++) {
2367
    /* Add nrgRef[k] to sumRef: */
2368
50.6M
    FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef,
2369
50.6M
                    &sumRef_e);
2370
2371
    /* Add nrgEst[k] to sumEst: */
2372
50.6M
    FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst,
2373
50.6M
                    &sumEst_e);
2374
50.6M
  }
2375
2376
7.18M
  FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain,
2377
7.18M
                     ptrAvgGain_e);
2378
2379
7.18M
  *ptrSumRef = sumRef;
2380
7.18M
  *ptrSumRef_e = sumRef_e;
2381
7.18M
}
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
237k
{
2395
237k
  int k;
2396
237k
  FIXP_DBL signalReal, sbNoise;
2397
237k
  int tone_count = 0;
2398
2399
237k
  FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2400
237k
  FIXP_DBL *RESTRICT pNoiseLevel =
2401
237k
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2402
237k
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2403
2404
237k
  int phaseIndex = *ptrPhaseIndex;
2405
237k
  UCHAR harmIndex = *ptrHarmIndex;
2406
2407
237k
  static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
2408
2409
237k
  static const FIXP_DBL harmonicPhaseX[4][2] = {
2410
237k
      {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001),
2411
237k
       FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)},
2412
237k
      {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001),
2413
237k
       FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)},
2414
237k
      {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001),
2415
237k
       FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)},
2416
237k
      {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001),
2417
237k
       FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}};
2418
2419
237k
  const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0];
2420
237k
  const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0];
2421
2422
237k
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2423
237k
  const FIXP_DBL min_val = -max_val;
2424
2425
237k
  *(ptrReal - 1) = fAddSaturate(
2426
237k
      *(ptrReal - 1),
2427
237k
      SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]),
2428
237k
                     scale_diff_low, DFRACT_BITS));
2429
237k
  FIXP_DBL pSineLevel_prev = (FIXP_DBL)0;
2430
2431
237k
  int idx_k = lowSubband & 1;
2432
2433
1.67M
  for (k = 0; k < noSubbands; k++) {
2434
1.43M
    FIXP_DBL sineLevel_curr = *pSineLevel++;
2435
1.43M
    phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2436
2437
1.43M
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2438
1.43M
                 << scale_change;
2439
1.43M
    sbNoise = *pNoiseLevel++;
2440
1.43M
    if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2441
1.31M
      signalReal +=
2442
1.31M
          fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2443
1.31M
    }
2444
1.43M
    signalReal += sineLevel_curr * p_harmonicPhase[0];
2445
1.43M
    signalReal =
2446
1.43M
        fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2447
1.43M
    pSineLevel_prev = sineLevel_curr;
2448
1.43M
    idx_k = !idx_k;
2449
1.43M
    if (k < noSubbands - 1) {
2450
1.19M
      signalReal =
2451
1.19M
          fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]);
2452
1.19M
    } else /* (k == noSubbands - 1)  */
2453
237k
    {
2454
237k
      if (k + lowSubband + 1 < 63) {
2455
233k
        *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]);
2456
233k
      }
2457
237k
    }
2458
1.43M
    *ptrReal++ = signalReal;
2459
2460
1.43M
    if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) {
2461
47.4k
      if (++tone_count == 16) {
2462
246
        k++;
2463
246
        break;
2464
246
      }
2465
47.4k
    }
2466
1.43M
  }
2467
  /* Run again, if previous loop got breaked with tone_count = 16 */
2468
239k
  for (; k < noSubbands; k++) {
2469
2.01k
    FIXP_DBL sineLevel_curr = *pSineLevel++;
2470
2.01k
    phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1);
2471
2472
2.01k
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2473
2.01k
                 << scale_change;
2474
2.01k
    sbNoise = *pNoiseLevel++;
2475
2.01k
    if (((INT)sineLevel_curr | noNoiseFlag) == 0) {
2476
935
      signalReal +=
2477
935
          fMult(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise);
2478
935
    }
2479
2.01k
    signalReal += sineLevel_curr * p_harmonicPhase[0];
2480
2.01k
    *ptrReal++ = signalReal;
2481
2.01k
  }
2482
2483
237k
  *ptrHarmIndex = (harmIndex + 1) & 3;
2484
237k
  *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1);
2485
237k
}
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
1.90M
{
2501
1.90M
  FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */
2502
1.90M
  FIXP_DBL *pNoiseLevel =
2503
1.90M
      nrgs->noiseLevel;                 /*!< Noise levels of current envelope */
2504
1.90M
  FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2505
2506
1.90M
  int k;
2507
1.90M
  int index = *ptrPhaseIndex;
2508
1.90M
  UCHAR harmIndex = *ptrHarmIndex;
2509
1.90M
  UCHAR freqInvFlag = (lowSubband & 1);
2510
1.90M
  FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev;
2511
1.90M
  int tone_count = 0;
2512
1.90M
  int sineSign = 1;
2513
1.90M
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2514
1.90M
  const FIXP_DBL min_val = -max_val;
2515
2516
21.7M
#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f))
2517
1.90M
#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
1.90M
  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
1.90M
  signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2531
1.90M
               << scale_change;
2532
1.90M
  sineLevel = *pSineLevel++;
2533
1.90M
  sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f);
2534
2535
1.90M
  if (sineLevel != FL2FXCONST_DBL(0.0f))
2536
79.3k
    tone_count++;
2537
1.82M
  else if (!noNoiseFlag)
2538
    /* Add noisefloor to the amplified signal */
2539
1.79M
    signalReal +=
2540
1.79M
        fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2541
2542
1.90M
  {
2543
1.90M
    if (!(harmIndex & 0x1)) {
2544
      /* harmIndex 0,2 */
2545
952k
      signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel;
2546
952k
      *ptrReal++ = signalReal;
2547
952k
    } else {
2548
      /* harmIndex 1,3 in combination with freqInvFlag */
2549
952k
      int shift = (int)(scale_change + 1);
2550
952k
      shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift)
2551
952k
                           : fixMax(-(DFRACT_BITS - 1), shift);
2552
2553
952k
      FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift)
2554
952k
                                   : (fMultDiv2(C1, sineLevel) << (-shift));
2555
952k
      FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext);
2556
2557
      /* save switch and compare operations and reduce to XOR statement */
2558
952k
      if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) {
2559
474k
        *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), tmp1);
2560
474k
        signalReal -= tmp2;
2561
477k
      } else {
2562
477k
        *(ptrReal - 1) = fAddSaturate(*(ptrReal - 1), -tmp1);
2563
477k
        signalReal += tmp2;
2564
477k
      }
2565
952k
      *ptrReal++ = signalReal;
2566
952k
      freqInvFlag = !freqInvFlag;
2567
952k
    }
2568
1.90M
  }
2569
2570
1.90M
  pNoiseLevel++;
2571
2572
1.90M
  if (noSubbands > 2) {
2573
1.90M
    if (!(harmIndex & 0x1)) {
2574
      /* harmIndex 0,2 */
2575
951k
      if (!harmIndex) {
2576
476k
        sineSign = 0;
2577
476k
      }
2578
2579
20.1M
      for (k = noSubbands - 2; k != 0; k--) {
2580
19.2M
        FIXP_DBL sinelevel = *pSineLevel++;
2581
19.2M
        index++;
2582
19.2M
        if (((signalReal = (sineSign ? -sinelevel : sinelevel)) ==
2583
19.2M
             FL2FXCONST_DBL(0.0f)) &&
2584
19.2M
            !noNoiseFlag) {
2585
          /* Add noisefloor to the amplified signal */
2586
18.0M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2587
18.0M
          signalReal +=
2588
18.0M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2589
18.0M
        }
2590
2591
        /* The next multiplication constitutes the actual envelope adjustment of
2592
         * the signal. */
2593
19.2M
        signalReal +=
2594
19.2M
            fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2595
19.2M
            << scale_change;
2596
2597
19.2M
        pNoiseLevel++;
2598
19.2M
        *ptrReal++ = signalReal;
2599
19.2M
      } /* for ... */
2600
951k
    } else {
2601
      /* harmIndex 1,3 in combination with freqInvFlag */
2602
951k
      if (harmIndex == 1) freqInvFlag = !freqInvFlag;
2603
2604
20.1M
      for (k = noSubbands - 2; k != 0; k--) {
2605
19.2M
        index++;
2606
        /* The next multiplication constitutes the actual envelope adjustment of
2607
         * the signal. */
2608
19.2M
        signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain++), max_val), min_val)
2609
19.2M
                     << scale_change;
2610
2611
19.2M
        if (*pSineLevel++ != FL2FXCONST_DBL(0.0f))
2612
789k
          tone_count++;
2613
18.4M
        else if (!noNoiseFlag) {
2614
          /* Add noisefloor to the amplified signal */
2615
18.0M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2616
18.0M
          signalReal +=
2617
18.0M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]);
2618
18.0M
        }
2619
2620
19.2M
        pNoiseLevel++;
2621
2622
19.2M
        if (tone_count <= 16) {
2623
18.9M
          FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1);
2624
18.9M
          signalReal += (freqInvFlag) ? (-addSine) : (addSine);
2625
18.9M
        }
2626
2627
19.2M
        *ptrReal++ = signalReal;
2628
19.2M
        freqInvFlag = !freqInvFlag;
2629
19.2M
      } /* for ... */
2630
951k
    }
2631
1.90M
  }
2632
2633
1.90M
  if (noSubbands > -1) {
2634
1.90M
    index++;
2635
    /* The next multiplication constitutes the actual envelope adjustment of the
2636
     * signal. */
2637
1.90M
    signalReal = fMax(fMin(fMultDiv2(*ptrReal, *pGain), max_val), min_val)
2638
1.90M
                 << scale_change;
2639
1.90M
    sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f));
2640
1.90M
    sineLevel = pSineLevel[0];
2641
2642
1.90M
    if (pSineLevel[0] != FL2FXCONST_DBL(0.0f))
2643
50.6k
      tone_count++;
2644
1.85M
    else if (!noNoiseFlag) {
2645
      /* Add noisefloor to the amplified signal */
2646
1.82M
      index &= (SBR_NF_NO_RANDOM_VAL - 1);
2647
1.82M
      signalReal = signalReal + fMult(FDK_sbrDecoder_sbr_randomPhase[index][0],
2648
1.82M
                                      pNoiseLevel[0]);
2649
1.82M
    }
2650
2651
1.90M
    if (!(harmIndex & 0x1)) {
2652
      /* harmIndex 0,2 */
2653
952k
      *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel);
2654
952k
    } else {
2655
      /* harmIndex 1,3 in combination with freqInvFlag */
2656
952k
      if (tone_count <= 16) {
2657
921k
        if (freqInvFlag) {
2658
461k
          *ptrReal++ = signalReal - sineLevelPrev;
2659
461k
          if (noSubbands + lowSubband < 63)
2660
453k
            *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel);
2661
461k
        } else {
2662
460k
          *ptrReal++ = signalReal + sineLevelPrev;
2663
460k
          if (noSubbands + lowSubband < 63)
2664
453k
            *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel);
2665
460k
        }
2666
921k
      } else
2667
30.6k
        *ptrReal = signalReal;
2668
952k
    }
2669
1.90M
  }
2670
1.90M
  *ptrHarmIndex = (harmIndex + 1) & 3;
2671
1.90M
  *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1);
2672
1.90M
}
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.61M
{
2687
1.61M
  FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2688
1.61M
  FIXP_DBL *RESTRICT noiseLevel =
2689
1.61M
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2690
1.61M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2691
2692
1.61M
  FIXP_DBL *RESTRICT filtBuffer =
2693
1.61M
      h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2694
1.61M
  FIXP_DBL *RESTRICT filtBufferNoise =
2695
1.61M
      h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2696
1.61M
  int *RESTRICT ptrPhaseIndex =
2697
1.61M
      &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2698
2699
1.61M
  int k;
2700
1.61M
  FIXP_DBL signalReal, signalImag;
2701
1.61M
  FIXP_DBL noiseReal, noiseImag;
2702
1.61M
  FIXP_DBL smoothedGain, smoothedNoise;
2703
1.61M
  FIXP_SGL direct_ratio =
2704
1.61M
      /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2705
1.61M
  int index = *ptrPhaseIndex;
2706
1.61M
  int shift;
2707
1.61M
  FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2708
1.61M
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2709
1.61M
  const FIXP_DBL min_val = -max_val;
2710
2711
1.61M
  *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2712
2713
1.61M
  filtBufferNoiseShift +=
2714
1.61M
      1; /* due to later use of fMultDiv2 instead of fMult */
2715
1.61M
  if (filtBufferNoiseShift < 0) {
2716
5.88k
    shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2717
1.61M
  } else {
2718
1.61M
    shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2719
1.61M
    max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2720
1.61M
    min_val_noise = -max_val_noise;
2721
1.61M
  }
2722
2723
1.61M
  if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2724
571k
    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
550k
      smoothedGain =
2730
550k
          fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2731
2732
550k
      if (filtBufferNoiseShift < 0) {
2733
244
        smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2734
244
                        fMult(direct_ratio, noiseLevel[k]);
2735
549k
      } else {
2736
549k
        smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2737
549k
        smoothedNoise =
2738
549k
            (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2739
549k
            fMult(direct_ratio, noiseLevel[k]);
2740
549k
      }
2741
2742
550k
      smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2743
550k
                           (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
550k
      signalReal =
2751
550k
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2752
550k
          << scale_change;
2753
550k
      signalImag =
2754
550k
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2755
550k
          << scale_change;
2756
2757
550k
      index++;
2758
2759
550k
      if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) {
2760
        /* Just the amplified signal is saved */
2761
1.42k
        *ptrReal++ = signalReal;
2762
1.42k
        *ptrImag++ = signalImag;
2763
548k
      } else {
2764
        /* Add noisefloor to the amplified signal */
2765
548k
        index &= (SBR_NF_NO_RANDOM_VAL - 1);
2766
548k
        noiseReal =
2767
548k
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2768
548k
        noiseImag =
2769
548k
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2770
548k
        *ptrReal++ = (signalReal + noiseReal);
2771
548k
        *ptrImag++ = (signalImag + noiseImag);
2772
548k
      }
2773
550k
    }
2774
1.59M
  } else {
2775
24.9M
    for (k = 0; k < noSubbands; k++) {
2776
23.3M
      smoothedGain = gain[k];
2777
23.3M
      signalReal =
2778
23.3M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2779
23.3M
          << scale_change;
2780
23.3M
      signalImag =
2781
23.3M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2782
23.3M
          << scale_change;
2783
2784
23.3M
      index++;
2785
2786
23.3M
      if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) {
2787
        /* Add noisefloor to the amplified signal */
2788
19.3M
        smoothedNoise = noiseLevel[k];
2789
19.3M
        index &= (SBR_NF_NO_RANDOM_VAL - 1);
2790
19.3M
        noiseReal =
2791
19.3M
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2792
19.3M
        noiseImag =
2793
19.3M
            fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2794
2795
19.3M
        signalReal += noiseReal;
2796
19.3M
        signalImag += noiseImag;
2797
19.3M
      }
2798
23.3M
      *ptrReal++ = signalReal;
2799
23.3M
      *ptrImag++ = signalImag;
2800
23.3M
    }
2801
1.59M
  }
2802
1.61M
}
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.61M
) {
2815
1.61M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2816
1.61M
  UCHAR *RESTRICT ptrHarmIndex =
2817
1.61M
      &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2818
2819
1.61M
  int k;
2820
1.61M
  FIXP_DBL signalReal, signalImag;
2821
1.61M
  UCHAR harmIndex = *ptrHarmIndex;
2822
1.61M
  int freqInvFlag = (lowSubband & 1);
2823
1.61M
  FIXP_DBL sineLevel;
2824
2825
1.61M
  *ptrHarmIndex = (harmIndex + 1) & 3;
2826
2827
25.5M
  for (k = 0; k < noSubbands; k++) {
2828
23.9M
    sineLevel = pSineLevel[k];
2829
23.9M
    freqInvFlag ^= 1;
2830
23.9M
    if (sineLevel != FL2FXCONST_DBL(0.f)) {
2831
63.0k
      signalReal = ptrReal[k];
2832
63.0k
      signalImag = ptrImag[k];
2833
63.0k
      sineLevel = scaleValue(sineLevel, scale_change);
2834
63.0k
      if (harmIndex & 2) {
2835
        /* case 2,3 */
2836
31.4k
        sineLevel = -sineLevel;
2837
31.4k
      }
2838
63.0k
      if (!(harmIndex & 1)) {
2839
        /* case 0,2: */
2840
31.5k
        ptrReal[k] = signalReal + sineLevel;
2841
31.5k
      } else {
2842
        /* case 1,3 */
2843
31.5k
        if (!freqInvFlag) sineLevel = -sineLevel;
2844
31.5k
        ptrImag[k] = signalImag + sineLevel;
2845
31.5k
      }
2846
63.0k
    }
2847
23.9M
  }
2848
1.61M
}
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.4M
{
2863
10.4M
  FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */
2864
10.4M
  FIXP_DBL *RESTRICT noiseLevel =
2865
10.4M
      nrgs->noiseLevel; /*!< Noise levels of current envelope */
2866
10.4M
  FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */
2867
2868
10.4M
  FIXP_DBL *RESTRICT filtBuffer =
2869
10.4M
      h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */
2870
10.4M
  FIXP_DBL *RESTRICT filtBufferNoise =
2871
10.4M
      h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */
2872
10.4M
  UCHAR *RESTRICT ptrHarmIndex =
2873
10.4M
      &h_sbr_cal_env->harmIndex; /*!< Harmonic index */
2874
10.4M
  int *RESTRICT ptrPhaseIndex =
2875
10.4M
      &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */
2876
2877
10.4M
  int k;
2878
10.4M
  FIXP_DBL signalReal, signalImag;
2879
10.4M
  FIXP_DBL noiseReal, noiseImag;
2880
10.4M
  FIXP_DBL smoothedGain, smoothedNoise;
2881
10.4M
  FIXP_SGL direct_ratio =
2882
10.4M
      /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio;
2883
10.4M
  int index = *ptrPhaseIndex;
2884
10.4M
  UCHAR harmIndex = *ptrHarmIndex;
2885
10.4M
  int freqInvFlag = (lowSubband & 1);
2886
10.4M
  FIXP_DBL sineLevel;
2887
10.4M
  int shift;
2888
10.4M
  FIXP_DBL max_val_noise = 0, min_val_noise = 0;
2889
10.4M
  const FIXP_DBL max_val = MAX_VAL_NRG_HEADROOM >> scale_change;
2890
10.4M
  const FIXP_DBL min_val = -max_val;
2891
2892
10.4M
  *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1);
2893
10.4M
  *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.4M
  filtBufferNoiseShift +=
2905
10.4M
      1; /* due to later use of fMultDiv2 instead of fMult */
2906
10.4M
  if (filtBufferNoiseShift < 0) {
2907
1.32k
    shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift);
2908
10.4M
  } else {
2909
10.4M
    shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift);
2910
10.4M
    max_val_noise = MAX_VAL_NRG_HEADROOM >> shift;
2911
10.4M
    min_val_noise = -max_val_noise;
2912
10.4M
  }
2913
2914
10.4M
  if (smooth_ratio > FL2FXCONST_SGL(0.0f)) {
2915
68.7M
    for (k = 0; k < noSubbands; k++) {
2916
      /*
2917
        Smoothing: The old envelope has been bufferd and a certain ratio
2918
        of the old gains and noise levels is used.
2919
      */
2920
2921
65.5M
      smoothedGain =
2922
65.5M
          fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]);
2923
2924
65.5M
      if (filtBufferNoiseShift < 0) {
2925
238
        smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) +
2926
238
                        fMult(direct_ratio, noiseLevel[k]);
2927
65.5M
      } else {
2928
65.5M
        smoothedNoise = fMultDiv2(smooth_ratio, filtBufferNoise[k]);
2929
65.5M
        smoothedNoise =
2930
65.5M
            (fMax(fMin(smoothedNoise, max_val_noise), min_val_noise) << shift) +
2931
65.5M
            fMult(direct_ratio, noiseLevel[k]);
2932
65.5M
      }
2933
2934
65.5M
      smoothedNoise = fMax(fMin(smoothedNoise, (FIXP_DBL)(MAXVAL_DBL / 2)),
2935
65.5M
                           (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
65.5M
      signalReal =
2943
65.5M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
2944
65.5M
          << scale_change;
2945
65.5M
      signalImag =
2946
65.5M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
2947
65.5M
          << scale_change;
2948
2949
65.5M
      index++;
2950
2951
65.5M
      if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) {
2952
76.5k
        sineLevel = pSineLevel[k];
2953
2954
76.5k
        switch (harmIndex) {
2955
19.1k
          case 0:
2956
19.1k
            *ptrReal++ = (signalReal + sineLevel);
2957
19.1k
            *ptrImag++ = (signalImag);
2958
19.1k
            break;
2959
19.1k
          case 2:
2960
19.1k
            *ptrReal++ = (signalReal - sineLevel);
2961
19.1k
            *ptrImag++ = (signalImag);
2962
19.1k
            break;
2963
19.1k
          case 1:
2964
19.1k
            *ptrReal++ = (signalReal);
2965
19.1k
            if (freqInvFlag)
2966
16.7k
              *ptrImag++ = (signalImag - sineLevel);
2967
2.38k
            else
2968
2.38k
              *ptrImag++ = (signalImag + sineLevel);
2969
19.1k
            break;
2970
19.1k
          case 3:
2971
19.1k
            *ptrReal++ = signalReal;
2972
19.1k
            if (freqInvFlag)
2973
16.7k
              *ptrImag++ = (signalImag + sineLevel);
2974
2.39k
            else
2975
2.39k
              *ptrImag++ = (signalImag - sineLevel);
2976
19.1k
            break;
2977
76.5k
        }
2978
65.4M
      } else {
2979
65.4M
        if (noNoiseFlag) {
2980
          /* Just the amplified signal is saved */
2981
0
          *ptrReal++ = (signalReal);
2982
0
          *ptrImag++ = (signalImag);
2983
65.4M
        } else {
2984
          /* Add noisefloor to the amplified signal */
2985
65.4M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
2986
65.4M
          noiseReal =
2987
65.4M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
2988
65.4M
          noiseImag =
2989
65.4M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
2990
65.4M
          *ptrReal++ = (signalReal + noiseReal);
2991
65.4M
          *ptrImag++ = (signalImag + noiseImag);
2992
65.4M
        }
2993
65.4M
      }
2994
65.5M
      freqInvFlag ^= 1;
2995
65.5M
    }
2996
2997
7.23M
  } else {
2998
195M
    for (k = 0; k < noSubbands; k++) {
2999
187M
      smoothedGain = gain[k];
3000
187M
      signalReal =
3001
187M
          fMax(fMin(fMultDiv2(*ptrReal, smoothedGain), max_val), min_val)
3002
187M
          << scale_change;
3003
187M
      signalImag =
3004
187M
          fMax(fMin(fMultDiv2(*ptrImag, smoothedGain), max_val), min_val)
3005
187M
          << scale_change;
3006
3007
187M
      index++;
3008
3009
187M
      if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) {
3010
134k
        switch (harmIndex) {
3011
33.5k
          case 0:
3012
33.5k
            signalReal += sineLevel;
3013
33.5k
            break;
3014
33.5k
          case 1:
3015
33.5k
            if (freqInvFlag)
3016
22.1k
              signalImag -= sineLevel;
3017
11.4k
            else
3018
11.4k
              signalImag += sineLevel;
3019
33.5k
            break;
3020
33.5k
          case 2:
3021
33.5k
            signalReal -= sineLevel;
3022
33.5k
            break;
3023
33.5k
          case 3:
3024
33.5k
            if (freqInvFlag)
3025
22.0k
              signalImag += sineLevel;
3026
11.4k
            else
3027
11.4k
              signalImag -= sineLevel;
3028
33.5k
            break;
3029
134k
        }
3030
187M
      } else {
3031
187M
        if (noNoiseFlag == 0) {
3032
          /* Add noisefloor to the amplified signal */
3033
185M
          smoothedNoise = noiseLevel[k];
3034
185M
          index &= (SBR_NF_NO_RANDOM_VAL - 1);
3035
185M
          noiseReal =
3036
185M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise);
3037
185M
          noiseImag =
3038
185M
              fMult(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise);
3039
3040
185M
          signalReal += noiseReal;
3041
185M
          signalImag += noiseImag;
3042
185M
        }
3043
187M
      }
3044
187M
      *ptrReal++ = signalReal;
3045
187M
      *ptrImag++ = signalImag;
3046
3047
187M
      freqInvFlag ^= 1;
3048
187M
    }
3049
7.23M
  }
3050
10.4M
}
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
430k
    UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) {
3070
430k
  int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands;
3071
430k
  UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
3072
430k
  int patchBorders[MAX_NUM_PATCHES + 1];
3073
430k
  int kx, k2;
3074
3075
430k
  int lowSubband = freqBandTable[0];
3076
430k
  int highSubband = freqBandTable[noFreqBands];
3077
3078
  /* 1 limiter band. */
3079
430k
  if (limiterBands == 0) {
3080
12.8k
    limiterBandTable[0] = 0;
3081
12.8k
    limiterBandTable[1] = highSubband - lowSubband;
3082
12.8k
    nBands = 1;
3083
418k
  } else {
3084
418k
    if (!sbrPatchingMode && xOverQmf != NULL) {
3085
42.6k
      noPatches = 0;
3086
3087
42.6k
      if (b41Sbr == 1) {
3088
142k
        for (i = 1; i < MAX_NUM_PATCHES_HBE; i++)
3089
118k
          if (xOverQmf[i] != 0) noPatches++;
3090
23.7k
      } else {
3091
75.4k
        for (i = 1; i < MAX_STRETCH_HBE; i++)
3092
56.5k
          if (xOverQmf[i] != 0) noPatches++;
3093
18.8k
      }
3094
136k
      for (i = 0; i < noPatches; i++) {
3095
94.0k
        patchBorders[i] = xOverQmf[i] - lowSubband;
3096
94.0k
      }
3097
375k
    } else {
3098
1.02M
      for (i = 0; i < noPatches; i++) {
3099
647k
        patchBorders[i] = patchParam[i].guardStartBand - lowSubband;
3100
647k
      }
3101
375k
    }
3102
418k
    patchBorders[i] = highSubband - lowSubband;
3103
3104
    /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */
3105
3.22M
    for (k = 0; k <= noFreqBands; k++) {
3106
2.80M
      workLimiterBandTable[k] = freqBandTable[k] - lowSubband;
3107
2.80M
    }
3108
882k
    for (k = 1; k < noPatches; k++) {
3109
464k
      workLimiterBandTable[noFreqBands + k] = patchBorders[k];
3110
464k
    }
3111
3112
418k
    tempNoLim = nBands = noFreqBands + noPatches - 1;
3113
418k
    shellsort(workLimiterBandTable, tempNoLim + 1);
3114
3115
418k
    loLimIndex = 0;
3116
418k
    hiLimIndex = 1;
3117
3118
3.13M
    while (hiLimIndex <= tempNoLim) {
3119
2.71M
      FIXP_DBL div_m, oct_m, temp;
3120
2.71M
      INT div_e = 0, oct_e = 0, temp_e = 0;
3121
3122
2.71M
      k2 = workLimiterBandTable[hiLimIndex] + lowSubband;
3123
2.71M
      kx = workLimiterBandTable[loLimIndex] + lowSubband;
3124
3125
2.71M
      div_m = fDivNorm(k2, kx, &div_e);
3126
3127
      /* calculate number of octaves */
3128
2.71M
      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.71M
      temp = fMultNorm(
3133
2.71M
          oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands],
3134
2.71M
          &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.71M
      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.71M
      if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) {
3148
1.62M
        if (workLimiterBandTable[hiLimIndex] ==
3149
1.62M
            workLimiterBandTable[loLimIndex]) {
3150
87.8k
          workLimiterBandTable[hiLimIndex] = highSubband;
3151
87.8k
          nBands--;
3152
87.8k
          hiLimIndex++;
3153
87.8k
          continue;
3154
87.8k
        }
3155
1.53M
        isPatchBorder[0] = isPatchBorder[1] = 0;
3156
6.15M
        for (k = 0; k <= noPatches; k++) {
3157
5.11M
          if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) {
3158
502k
            isPatchBorder[1] = 1;
3159
502k
            break;
3160
502k
          }
3161
5.11M
        }
3162
1.53M
        if (!isPatchBorder[1]) {
3163
1.03M
          workLimiterBandTable[hiLimIndex] = highSubband;
3164
1.03M
          nBands--;
3165
1.03M
          hiLimIndex++;
3166
1.03M
          continue;
3167
1.03M
        }
3168
2.02M
        for (k = 0; k <= noPatches; k++) {
3169
1.74M
          if (workLimiterBandTable[loLimIndex] == patchBorders[k]) {
3170
218k
            isPatchBorder[0] = 1;
3171
218k
            break;
3172
218k
          }
3173
1.74M
        }
3174
502k
        if (!isPatchBorder[0]) {
3175
284k
          workLimiterBandTable[loLimIndex] = highSubband;
3176
284k
          nBands--;
3177
284k
        }
3178
502k
      }
3179
1.58M
      loLimIndex = hiLimIndex;
3180
1.58M
      hiLimIndex++;
3181
1.58M
    }
3182
418k
    shellsort(workLimiterBandTable, tempNoLim + 1);
3183
3184
    /* Test if algorithm exceeded maximum allowed limiterbands */
3185
418k
    if (nBands > MAX_NUM_LIMITERS || nBands <= 0) {
3186
4.69k
      return SBRDEC_UNSUPPORTED_CONFIG;
3187
4.69k
    }
3188
3189
    /* Restrict maximum value of limiter band table */
3190
413k
    if (workLimiterBandTable[tempNoLim] > highSubband) {
3191
623
      return SBRDEC_UNSUPPORTED_CONFIG;
3192
623
    }
3193
3194
    /* Copy limiterbands from working buffer into final destination */
3195
2.12M
    for (k = 0; k <= nBands; k++) {
3196
1.71M
      limiterBandTable[k] = workLimiterBandTable[k];
3197
1.71M
    }
3198
412k
  }
3199
425k
  *noLimiterBands = nBands;
3200
3201
425k
  return SBRDEC_OK;
3202
430k
}