Coverage Report

Created: 2025-07-11 06:50

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