Coverage Report

Created: 2025-11-24 06:13

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