Coverage Report

Created: 2025-07-01 06:21

/src/aac/libSBRenc/src/env_est.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 - 2020 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 encoder library ******************************
96
97
   Author(s):
98
99
   Description:
100
101
*******************************************************************************/
102
103
#include "env_est.h"
104
#include "tran_det.h"
105
106
#include "qmf.h"
107
108
#include "fram_gen.h"
109
#include "bit_sbr.h"
110
#include "cmondata.h"
111
#include "sbrenc_ram.h"
112
113
#include "genericStds.h"
114
115
#define QUANT_ERROR_THRES 200
116
#define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */
117
#define MAX_NRG_SLOTS_LD 16
118
119
static const UCHAR panTable[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24},
120
                                      {0, 2, 4, 8, 12, 0, 0, 0, 0}};
121
static const UCHAR maxIndex[2] = {9, 5};
122
123
/******************************************************************************
124
 Functionname:  FDKsbrEnc_GetTonality
125
******************************************************************************/
126
/***************************************************************************/
127
/*!
128
129
  \brief      Calculates complete energy per band from the energy values
130
              of the QMF subsamples.
131
132
  \brief      quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas()
133
  \brief      noEstPerFrame - number of estimations per frame
134
  \brief      startIndex - start index for the quota matrix
135
  \brief      Energies - energy matrix
136
  \brief      startBand - start band
137
  \brief      stopBand - number of QMF bands
138
  \brief      numberCols - number of QMF subsamples
139
140
  \return     mean tonality of the 5 bands with the highest energy
141
              scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT
142
143
****************************************************************************/
144
static FIXP_DBL FDKsbrEnc_GetTonality(const FIXP_DBL *const *quotaMatrix,
145
                                      const INT noEstPerFrame,
146
                                      const INT startIndex,
147
                                      const FIXP_DBL *const *Energies,
148
                                      const UCHAR startBand, const INT stopBand,
149
0
                                      const INT numberCols) {
150
0
  UCHAR b, e, k;
151
0
  INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = {-1, -1, -1, -1, -1};
152
0
  FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = {
153
0
      FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
154
0
      FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
155
0
  FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
156
0
  UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
157
0
  FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = {
158
0
      FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
159
0
      FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
160
0
  FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
161
0
  FIXP_DBL energyBand[64];
162
0
  INT maxNEnergyValues; /* max. number of max. energy values */
163
164
  /*** Sum up energies for each band ***/
165
0
  FDK_ASSERT(numberCols == 15 || numberCols == 16);
166
  /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the
167
      energyBands are initialized with the [15]th column.
168
      The rest of the column energies are added in the next step.   */
169
0
  if (numberCols == 15) {
170
0
    for (b = startBand; b < stopBand; b++) {
171
0
      energyBand[b] = FL2FXCONST_DBL(0.0f);
172
0
    }
173
0
  } else {
174
0
    for (b = startBand; b < stopBand; b++) {
175
0
      energyBand[b] = Energies[15][b] >> 4;
176
0
    }
177
0
  }
178
179
0
  for (k = 0; k < 15; k++) {
180
0
    for (b = startBand; b < stopBand; b++) {
181
0
      energyBand[b] += Energies[k][b] >> 4;
182
0
    }
183
0
  }
184
185
  /*** Determine 5 highest band-energies ***/
186
0
  maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand - startBand);
187
188
  /* Get min. value in energyMax array */
189
0
  energyMaxMin = energyMax[0] = energyBand[startBand];
190
0
  no_enMaxBand[0] = startBand;
191
0
  posEnergyMaxMin = 0;
192
0
  for (k = 1; k < maxNEnergyValues; k++) {
193
0
    energyMax[k] = energyBand[startBand + k];
194
0
    no_enMaxBand[k] = startBand + k;
195
0
    if (energyMaxMin > energyMax[k]) {
196
0
      energyMaxMin = energyMax[k];
197
0
      posEnergyMaxMin = k;
198
0
    }
199
0
  }
200
201
0
  for (b = startBand + maxNEnergyValues; b < stopBand; b++) {
202
0
    if (energyBand[b] > energyMaxMin) {
203
0
      energyMax[posEnergyMaxMin] = energyBand[b];
204
0
      no_enMaxBand[posEnergyMaxMin] = b;
205
206
      /* Again, get min. value in energyMax array */
207
0
      energyMaxMin = energyMax[0];
208
0
      posEnergyMaxMin = 0;
209
0
      for (k = 1; k < maxNEnergyValues; k++) {
210
0
        if (energyMaxMin > energyMax[k]) {
211
0
          energyMaxMin = energyMax[k];
212
0
          posEnergyMaxMin = k;
213
0
        }
214
0
      }
215
0
    }
216
0
  }
217
  /*** End determine 5 highest band-energies ***/
218
219
  /* Get tonality values for 5 highest energies */
220
0
  for (e = 0; e < maxNEnergyValues; e++) {
221
0
    tonalityBand[e] = FL2FXCONST_DBL(0.0f);
222
0
    for (k = 0; k < noEstPerFrame; k++) {
223
0
      tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
224
0
    }
225
0
    globalTonality +=
226
0
        tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
227
0
  }
228
229
0
  return globalTonality;
230
0
}
231
232
/***************************************************************************/
233
/*!
234
235
  \brief      Calculates energy form real and imaginary part of
236
              the QMF subsamples
237
238
  \return     none
239
240
****************************************************************************/
241
LNK_SECTION_CODE_L1
242
static void FDKsbrEnc_getEnergyFromCplxQmfData(
243
    FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
244
    FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
245
    FIXP_DBL **RESTRICT
246
        imagValues,   /*!< the imaginary part of the QMF subsamples */
247
    INT numberBands,  /*!< number of QMF bands */
248
    INT numberCols,   /*!< number of QMF subsamples */
249
    INT *qmfScale,    /*!< sclefactor of QMF subsamples */
250
    INT *energyScale) /*!< scalefactor of energies */
251
0
{
252
0
  int j, k;
253
0
  int scale;
254
0
  FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
255
256
  /* Get Scratch buffer */
257
0
  C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2)
258
259
  /* Get max possible scaling of QMF data */
260
0
  scale = DFRACT_BITS;
261
0
  for (k = 0; k < numberCols; k++) {
262
0
    scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
263
0
                                 getScalefactor(imagValues[k], numberBands)));
264
0
  }
265
266
  /* Tweak scaling stability for zero signal to non-zero signal transitions */
267
0
  if (scale >= DFRACT_BITS - 1) {
268
0
    scale = (FRACT_BITS - 1 - *qmfScale);
269
0
  }
270
  /* prevent scaling of QMF values to -1.f */
271
0
  scale = fixMax(0, scale - 1);
272
273
  /* Update QMF scale */
274
0
  *qmfScale += scale;
275
276
  /*
277
     Calculate energy of each time slot pair, max energy
278
     and shift QMF values as far as possible to the left.
279
   */
280
0
  {
281
0
    FIXP_DBL *nrgValues = tmpNrg;
282
0
    for (k = 0; k < numberCols; k += 2) {
283
      /* Load band vector addresses of 2 consecutive timeslots */
284
0
      FIXP_DBL *RESTRICT r0 = realValues[k];
285
0
      FIXP_DBL *RESTRICT i0 = imagValues[k];
286
0
      FIXP_DBL *RESTRICT r1 = realValues[k + 1];
287
0
      FIXP_DBL *RESTRICT i1 = imagValues[k + 1];
288
0
      for (j = 0; j < numberBands; j++) {
289
0
        FIXP_DBL energy;
290
0
        FIXP_DBL tr0, tr1, ti0, ti1;
291
292
        /* Read QMF values of 2 timeslots */
293
0
        tr0 = r0[j];
294
0
        tr1 = r1[j];
295
0
        ti0 = i0[j];
296
0
        ti1 = i1[j];
297
298
        /* Scale QMF Values and Calc Energy average of both timeslots */
299
0
        tr0 <<= scale;
300
0
        ti0 <<= scale;
301
0
        energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1;
302
303
0
        tr1 <<= scale;
304
0
        ti1 <<= scale;
305
0
        energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1;
306
307
        /* Write timeslot pair energy to scratch */
308
0
        *nrgValues++ = energy;
309
0
        max_val = fixMax(max_val, energy);
310
311
        /* Write back scaled QMF values */
312
0
        r0[j] = tr0;
313
0
        r1[j] = tr1;
314
0
        i0[j] = ti0;
315
0
        i1[j] = ti1;
316
0
      }
317
0
    }
318
0
  }
319
  /* energyScale: scalefactor energies of current frame */
320
0
  *energyScale =
321
0
      2 * (*qmfScale) -
322
0
      1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
323
324
  /* Scale timeslot pair energies and write to output buffer */
325
0
  scale = CountLeadingBits(max_val);
326
0
  {
327
0
    FIXP_DBL *nrgValues = tmpNrg;
328
0
    for (k = 0; k<numberCols>> 1; k++) {
329
0
      scaleValues(energyValues[k], nrgValues, numberBands, scale);
330
0
      nrgValues += numberBands;
331
0
    }
332
0
    *energyScale += scale;
333
0
  }
334
335
  /* Free Scratch buffer */
336
0
  C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2)
337
0
}
338
339
LNK_SECTION_CODE_L1
340
static void FDKsbrEnc_getEnergyFromCplxQmfDataFull(
341
    FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */
342
    FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */
343
    FIXP_DBL **RESTRICT
344
        imagValues,   /*!< the imaginary part of the QMF subsamples */
345
    int numberBands,  /*!< number of QMF bands */
346
    int numberCols,   /*!< number of QMF subsamples */
347
    int *qmfScale,    /*!< scalefactor of QMF subsamples */
348
    int *energyScale) /*!< scalefactor of energies */
349
0
{
350
0
  int j, k;
351
0
  int scale;
352
0
  FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
353
354
  /* Get Scratch buffer */
355
0
  C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
356
357
0
  FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD);
358
0
  FDK_ASSERT(numberBands <= 64);
359
360
  /* Get max possible scaling of QMF data */
361
0
  scale = DFRACT_BITS;
362
0
  for (k = 0; k < numberCols; k++) {
363
0
    scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
364
0
                                 getScalefactor(imagValues[k], numberBands)));
365
0
  }
366
367
  /* Tweak scaling stability for zero signal to non-zero signal transitions */
368
0
  if (scale >= DFRACT_BITS - 1) {
369
0
    scale = (FRACT_BITS - 1 - *qmfScale);
370
0
  }
371
  /* prevent scaling of QFM values to -1.f */
372
0
  scale = fixMax(0, scale - 1);
373
374
  /* Update QMF scale */
375
0
  *qmfScale += scale;
376
377
  /*
378
     Calculate energy of each time slot pair, max energy
379
     and shift QMF values as far as possible to the left.
380
   */
381
0
  {
382
0
    FIXP_DBL *nrgValues = tmpNrg;
383
0
    for (k = 0; k < numberCols; k++) {
384
      /* Load band vector addresses of 1 timeslot */
385
0
      FIXP_DBL *RESTRICT r0 = realValues[k];
386
0
      FIXP_DBL *RESTRICT i0 = imagValues[k];
387
0
      for (j = 0; j < numberBands; j++) {
388
0
        FIXP_DBL energy;
389
0
        FIXP_DBL tr0, ti0;
390
391
        /* Read QMF values of 1 timeslot */
392
0
        tr0 = r0[j];
393
0
        ti0 = i0[j];
394
395
        /* Scale QMF Values and Calc Energy */
396
0
        tr0 <<= scale;
397
0
        ti0 <<= scale;
398
0
        energy = fPow2AddDiv2(fPow2Div2(tr0), ti0);
399
0
        *nrgValues++ = energy;
400
401
0
        max_val = fixMax(max_val, energy);
402
403
        /* Write back scaled QMF values */
404
0
        r0[j] = tr0;
405
0
        i0[j] = ti0;
406
0
      }
407
0
    }
408
0
  }
409
  /* energyScale: scalefactor energies of current frame */
410
0
  *energyScale =
411
0
      2 * (*qmfScale) -
412
0
      1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */
413
414
  /* Scale timeslot pair energies and write to output buffer */
415
0
  scale = CountLeadingBits(max_val);
416
0
  {
417
0
    FIXP_DBL *nrgValues = tmpNrg;
418
0
    for (k = 0; k < numberCols; k++) {
419
0
      scaleValues(energyValues[k], nrgValues, numberBands, scale);
420
0
      nrgValues += numberBands;
421
0
    }
422
0
    *energyScale += scale;
423
0
  }
424
425
  /* Free Scratch buffer */
426
0
  C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
427
0
}
428
429
/***************************************************************************/
430
/*!
431
432
  \brief  Quantisation of the panorama value (balance)
433
434
  \return the quantized pan value
435
436
****************************************************************************/
437
static INT mapPanorama(INT nrgVal,     /*! integer value of the energy */
438
                       INT ampRes,     /*! amplitude resolution [1.5/3dB] */
439
                       INT *quantError /*! quantization error of energy val*/
440
0
) {
441
0
  int i;
442
0
  INT min_val, val;
443
0
  UCHAR panIndex;
444
0
  INT sign;
445
446
0
  sign = nrgVal > 0 ? 1 : -1;
447
448
0
  nrgVal *= sign;
449
450
0
  min_val = FDK_INT_MAX;
451
0
  panIndex = 0;
452
0
  for (i = 0; i < maxIndex[ampRes]; i++) {
453
0
    val = fixp_abs((nrgVal - (INT)panTable[ampRes][i]));
454
455
0
    if (val < min_val) {
456
0
      min_val = val;
457
0
      panIndex = i;
458
0
    }
459
0
  }
460
461
0
  *quantError = min_val;
462
463
0
  return panTable[ampRes][maxIndex[ampRes] - 1] +
464
0
         sign * panTable[ampRes][panIndex];
465
0
}
466
467
/***************************************************************************/
468
/*!
469
470
  \brief  Quantisation of the noise floor levels
471
472
  \return void
473
474
****************************************************************************/
475
static void sbrNoiseFloorLevelsQuantisation(
476
    SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */
477
    FIXP_DBL *RESTRICT
478
        NoiseLevels, /*! the noise levels. Exponent = LD_DATA_SHIFT  */
479
    INT coupling     /*! the coupling flag */
480
0
) {
481
0
  INT i;
482
0
  INT tmp, dummy;
483
484
  /* Quantisation, similar to sfb quant... */
485
0
  for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
486
    /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] +
487
     * (PFLOAT)0.5); */
488
    /* 30>>LD_DATA_SHIFT = 0.46875 */
489
0
    if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) {
490
0
      tmp = 30;
491
0
    } else {
492
      /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/
493
      /* FRACT_BITS+ */                                 /* 6-1)));*/
494
      /* tmp = tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT); */ /* conversion to integer
495
                                                           happens here */
496
      /* rounding is done by shifting one bit less than necessary to the right,
497
       * adding '1' and then shifting the final bit */
498
0
      tmp = ((((INT)NoiseLevels[i]) >>
499
0
              (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */
500
0
      if (tmp != 0) tmp += 1;
501
0
    }
502
503
0
    if (coupling) {
504
0
      tmp = tmp < -30 ? -30 : tmp;
505
0
      tmp = mapPanorama(tmp, 1, &dummy);
506
0
    }
507
0
    iNoiseLevels[i] = tmp;
508
0
  }
509
0
}
510
511
/***************************************************************************/
512
/*!
513
514
  \brief  Calculation of noise floor for coupling
515
516
  \return void
517
518
****************************************************************************/
519
static void coupleNoiseFloor(
520
    FIXP_DBL *RESTRICT noise_level_left, /*! noise level left  (modified)*/
521
    FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/
522
0
) {
523
0
  FIXP_DBL cmpValLeft, cmpValRight;
524
0
  INT i;
525
0
  FIXP_DBL temp1, temp2;
526
527
0
  for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
528
    /* Calculation of the power function using ld64:
529
       z  = x^y;
530
       z' = CalcLd64(z) = y*CalcLd64(x)/64;
531
       z  = CalcInvLd64(z');
532
    */
533
0
    cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i];
534
0
    cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i];
535
536
0
    if (cmpValRight < FL2FXCONST_DBL(0.0f)) {
537
0
      temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
538
0
    } else {
539
0
      temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
540
0
      temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
541
0
                        1); /* INT to fract conversion of result, if input of
542
                               CalcInvLdData is positiv */
543
0
    }
544
545
0
    if (cmpValLeft < FL2FXCONST_DBL(0.0f)) {
546
0
      temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
547
0
    } else {
548
0
      temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
549
0
      temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
550
0
                        1); /* INT to fract conversion of result, if input of
551
                               CalcInvLdData is positiv */
552
0
    }
553
554
0
    if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
555
0
        (cmpValRight < FL2FXCONST_DBL(0.0f))) {
556
0
      noise_level_left[i] =
557
0
          NOISE_FLOOR_OFFSET_64 -
558
0
          (CalcLdData(
559
0
              ((temp1 >> 1) +
560
0
               (temp2 >> 1)))); /* no scaling needed! both values are dfract */
561
0
      noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
562
0
    }
563
564
0
    if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
565
0
        (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
566
0
      noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
567
0
                            (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) +
568
0
                             FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
569
0
      noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
570
0
    }
571
572
0
    if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
573
0
        (cmpValRight < FL2FXCONST_DBL(0.0f))) {
574
0
      noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
575
0
                            (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) +
576
0
                             FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
577
0
      noise_level_right[i] =
578
0
          (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1);
579
0
    }
580
581
0
    if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
582
0
        (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
583
0
      noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
584
0
                            (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) +
585
0
                             FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
586
0
      noise_level_right[i] = CalcLdData(temp2) -
587
0
                             (CalcLdData(temp1) +
588
0
                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
589
0
    }
590
0
  }
591
0
}
592
593
/***************************************************************************/
594
/*!
595
596
  \brief  Calculation of energy starting in lower band (li) up to upper band
597
(ui) over slots (start_pos) to (stop_pos)
598
599
  \return void
600
601
****************************************************************************/
602
603
static FIXP_DBL getEnvSfbEnergy(
604
    INT li,             /*! lower band */
605
    INT ui,             /*! upper band */
606
    INT start_pos,      /*! start slot */
607
    INT stop_pos,       /*! stop slot */
608
    INT border_pos,     /*! slots scaling border */
609
    FIXP_DBL **YBuffer, /*! sfb energy buffer */
610
    INT YBufferSzShift, /*! Energy buffer index scale */
611
    INT scaleNrg0,      /*! scaling of lower slots */
612
    INT scaleNrg1)      /*! scaling of upper slots */
613
0
{
614
  /* use dynamic scaling for outer energy loop;
615
     energies are critical and every bit is important */
616
0
  int sc0, sc1, k, l;
617
618
0
  FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2;
619
0
  INT dynScale, dynScale1, dynScale2;
620
0
  if (ui - li == 0)
621
0
    dynScale = DFRACT_BITS - 1;
622
0
  else
623
0
    dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT);
624
625
0
  sc0 = fixMin(scaleNrg0, Y_NRG_SCALE);
626
0
  sc1 = fixMin(scaleNrg1, Y_NRG_SCALE);
627
  /* dynScale{1,2} is set such that the right shift below is positive */
628
0
  dynScale1 = fixMin((scaleNrg0 - sc0), dynScale);
629
0
  dynScale2 = fixMin((scaleNrg1 - sc1), dynScale);
630
0
  nrgSum = accu1 = accu2 = (FIXP_DBL)0;
631
632
0
  for (k = li; k < ui; k++) {
633
0
    nrg1 = nrg2 = (FIXP_DBL)0;
634
0
    for (l = start_pos; l < border_pos; l++) {
635
0
      nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0;
636
0
    }
637
0
    for (; l < stop_pos; l++) {
638
0
      nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1;
639
0
    }
640
0
    accu1 += (nrg1 >> dynScale1);
641
0
    accu2 += (nrg2 >> dynScale2);
642
0
  }
643
  /* This shift factor is always positive. See comment above. */
644
0
  nrgSum +=
645
0
      (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) +
646
0
      (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1)));
647
648
0
  return nrgSum;
649
0
}
650
651
/***************************************************************************/
652
/*!
653
654
  \brief  Energy compensation in missing harmonic mode
655
656
  \return void
657
658
****************************************************************************/
659
0
static FIXP_DBL mhLoweringEnergy(FIXP_DBL nrg, INT M) {
660
  /*
661
     Compensating for the fact that we in the decoder map the "average energy to
662
     every QMF band, and use this when we calculate the boost-factor. Since the
663
     mapped energy isn't the average energy but the maximum energy in case of
664
     missing harmonic creation, we will in the boost function calculate that too
665
     much limiting has been applied and hence we will boost the signal although
666
     it isn't called for. Hence we need to compensate for this by lowering the
667
     transmitted energy values for the sines so they will get the correct level
668
     after the boost is applied.
669
  */
670
0
  if (M > 2) {
671
0
    INT tmpScale;
672
0
    tmpScale = CountLeadingBits(nrg);
673
0
    nrg <<= tmpScale;
674
0
    nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost
675
                                                       is 1.584893, so the
676
                                                       maximum attenuation
677
                                                       should be
678
                                                       square(1/1.584893) =
679
                                                       0.398107267 */
680
0
    nrg >>= tmpScale;
681
0
  } else {
682
0
    if (M > 1) {
683
0
      nrg >>= 1;
684
0
    }
685
0
  }
686
687
0
  return nrg;
688
0
}
689
690
/***************************************************************************/
691
/*!
692
693
  \brief  Energy compensation in none missing harmonic mode
694
695
  \return void
696
697
****************************************************************************/
698
static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum,
699
0
                                  const INT nrgSum_scale, const INT M) {
700
0
  if (nrg > FL2FXCONST_DBL(0)) {
701
0
    int sc = 0;
702
    /* gain = nrgSum / (nrg*(M+1)) */
703
0
    FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1));
704
0
    sc += nrgSum_scale;
705
706
    /* reduce nrg if gain smaller 1.f */
707
0
    if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) {
708
0
      nrg = fMult(scaleValue(gain, sc), nrg);
709
0
    }
710
0
  }
711
0
  return nrg;
712
0
}
713
714
/***************************************************************************/
715
/*!
716
717
  \brief  calculates the envelope values from the energies, depending on
718
          framing and stereo mode
719
720
  \return void
721
722
****************************************************************************/
723
static void calculateSbrEnvelope(
724
    FIXP_DBL **RESTRICT YBufferLeft,  /*! energy buffer left */
725
    FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */
726
    int *RESTRICT YBufferScaleLeft,   /*! scale energy buffer left */
727
    int *RESTRICT YBufferScaleRight,  /*! scale energy buffer right */
728
    const SBR_FRAME_INFO *frame_info, /*! frame info vector */
729
    SCHAR *RESTRICT sfb_nrgLeft,      /*! sfb energy buffer left */
730
    SCHAR *RESTRICT sfb_nrgRight,     /*! sfb energy buffer right */
731
    HANDLE_SBR_CONFIG_DATA h_con,     /*! handle to config data   */
732
    HANDLE_ENV_CHANNEL h_sbr,         /*! envelope channel handle */
733
    SBR_STEREO_MODE stereoMode,       /*! stereo coding mode */
734
    INT *maxQuantError, /*! maximum quantization error, for panorama. */
735
    int YBufferSzShift) /*! Energy buffer index scale */
736
737
0
{
738
0
  int env, j, m = 0;
739
0
  INT no_of_bands, start_pos, stop_pos, li, ui;
740
0
  FREQ_RES freq_res;
741
742
0
  INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res;
743
0
  INT oneBitLess = 0;
744
0
  if (ca == 2)
745
0
    oneBitLess =
746
0
        1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
747
748
0
  INT quantError;
749
0
  INT nEnvelopes = frame_info->nEnvelopes;
750
0
  INT short_env = frame_info->shortEnv - 1;
751
0
  INT timeStep = h_sbr->sbrExtractEnvelope.time_step;
752
0
  INT commonScale, scaleLeft0, scaleLeft1;
753
0
  INT scaleRight0 = 0, scaleRight1 = 0;
754
755
0
  commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]);
756
757
0
  if (stereoMode == SBR_COUPLING) {
758
0
    commonScale = fixMin(commonScale, YBufferScaleRight[0]);
759
0
    commonScale = fixMin(commonScale, YBufferScaleRight[1]);
760
0
  }
761
762
0
  commonScale = commonScale - 7;
763
764
0
  scaleLeft0 = YBufferScaleLeft[0] - commonScale;
765
0
  scaleLeft1 = YBufferScaleLeft[1] - commonScale;
766
0
  FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0));
767
768
0
  if (stereoMode == SBR_COUPLING) {
769
0
    scaleRight0 = YBufferScaleRight[0] - commonScale;
770
0
    scaleRight1 = YBufferScaleRight[1] - commonScale;
771
0
    FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0));
772
0
    *maxQuantError = 0;
773
0
  }
774
775
0
  for (env = 0; env < nEnvelopes; env++) {
776
0
    FIXP_DBL pNrgLeft[32];
777
0
    FIXP_DBL pNrgRight[32];
778
0
    int envNrg_scale;
779
0
    FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f);
780
0
    FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f);
781
0
    int missingHarmonic[32];
782
0
    int count[32];
783
784
0
    start_pos = timeStep * frame_info->borders[env];
785
0
    stop_pos = timeStep * frame_info->borders[env + 1];
786
0
    freq_res = frame_info->freqRes[env];
787
0
    no_of_bands = h_con->nSfb[freq_res];
788
0
    envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands);
789
0
    if (env == short_env) {
790
0
      j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short
791
                                envelopes (envelopes just before transients) */
792
0
      if ((stop_pos - start_pos - j) > 0) {
793
0
        stop_pos = stop_pos - j;
794
0
      }
795
0
    }
796
0
    for (j = 0; j < no_of_bands; j++) {
797
0
      FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f);
798
0
      FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f);
799
800
0
      li = h_con->freqBandTable[freq_res][j];
801
0
      ui = h_con->freqBandTable[freq_res][j + 1];
802
803
0
      if (freq_res == FREQ_RES_HIGH) {
804
0
        if (j == 0 && ui - li > 1) {
805
0
          li++;
806
0
        }
807
0
      } else {
808
0
        if (j == 0 && ui - li > 2) {
809
0
          li++;
810
0
        }
811
0
      }
812
813
      /*
814
        Find out whether a sine will be missing in the scale-factor
815
        band that we're currently processing.
816
      */
817
0
      missingHarmonic[j] = 0;
818
819
0
      if (h_sbr->encEnvData.addHarmonicFlag) {
820
0
        if (freq_res == FREQ_RES_HIGH) {
821
0
          if (h_sbr->encEnvData
822
0
                  .addHarmonic[j]) { /*A missing sine in the current band*/
823
0
            missingHarmonic[j] = 1;
824
0
          }
825
0
        } else {
826
0
          INT i;
827
0
          INT startBandHigh = 0;
828
0
          INT stopBandHigh = 0;
829
830
0
          while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] <
831
0
                 h_con->freqBandTable[FREQ_RES_LOW][j])
832
0
            startBandHigh++;
833
0
          while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] <
834
0
                 h_con->freqBandTable[FREQ_RES_LOW][j + 1])
835
0
            stopBandHigh++;
836
837
0
          for (i = startBandHigh; i < stopBandHigh; i++) {
838
0
            if (h_sbr->encEnvData.addHarmonic[i]) {
839
0
              missingHarmonic[j] = 1;
840
0
            }
841
0
          }
842
0
        }
843
0
      }
844
845
      /*
846
        If a sine is missing in a scalefactorband, with more than one qmf
847
        channel use the nrg from the channel with the largest nrg rather than
848
        the mean. Compensate for the boost calculation in the decdoder.
849
      */
850
0
      int border_pos =
851
0
          fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset
852
0
                               << YBufferSzShift);
853
854
0
      if (missingHarmonic[j]) {
855
0
        int k;
856
0
        count[j] = stop_pos - start_pos;
857
0
        nrgLeft = FL2FXCONST_DBL(0.0f);
858
859
0
        for (k = li; k < ui; k++) {
860
0
          FIXP_DBL tmpNrg;
861
0
          tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
862
0
                                   YBufferLeft, YBufferSzShift, scaleLeft0,
863
0
                                   scaleLeft1);
864
865
0
          nrgLeft = fixMax(nrgLeft, tmpNrg);
866
0
        }
867
868
        /* Energy lowering compensation */
869
0
        nrgLeft = mhLoweringEnergy(nrgLeft, ui - li);
870
871
0
        if (stereoMode == SBR_COUPLING) {
872
0
          nrgRight = FL2FXCONST_DBL(0.0f);
873
874
0
          for (k = li; k < ui; k++) {
875
0
            FIXP_DBL tmpNrg;
876
0
            tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
877
0
                                     YBufferRight, YBufferSzShift, scaleRight0,
878
0
                                     scaleRight1);
879
880
0
            nrgRight = fixMax(nrgRight, tmpNrg);
881
0
          }
882
883
          /* Energy lowering compensation */
884
0
          nrgRight = mhLoweringEnergy(nrgRight, ui - li);
885
0
        }
886
0
      } /* end missingHarmonic */
887
0
      else {
888
0
        count[j] = (stop_pos - start_pos) * (ui - li);
889
890
0
        nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
891
0
                                  YBufferLeft, YBufferSzShift, scaleLeft0,
892
0
                                  scaleLeft1);
893
894
0
        if (stereoMode == SBR_COUPLING) {
895
0
          nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
896
0
                                     YBufferRight, YBufferSzShift, scaleRight0,
897
0
                                     scaleRight1);
898
0
        }
899
0
      } /* !missingHarmonic */
900
901
      /* save energies */
902
0
      pNrgLeft[j] = nrgLeft;
903
0
      pNrgRight[j] = nrgRight;
904
0
      envNrgLeft += (nrgLeft >> envNrg_scale);
905
0
      envNrgRight += (nrgRight >> envNrg_scale);
906
0
    } /* j */
907
908
0
    for (j = 0; j < no_of_bands; j++) {
909
0
      FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f);
910
0
      FIXP_DBL nrgLeft = pNrgLeft[j];
911
0
      FIXP_DBL nrgRight = pNrgRight[j];
912
913
      /* None missing harmonic Energy lowering compensation */
914
0
      if (!missingHarmonic[j] && h_sbr->fLevelProtect) {
915
        /* in case of missing energy in base band,
916
           reduce reference energy to prevent overflows in decoder output */
917
0
        nrgLeft =
918
0
            nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands);
919
0
        if (stereoMode == SBR_COUPLING) {
920
0
          nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale,
921
0
                                       no_of_bands);
922
0
        }
923
0
      }
924
925
0
      if (stereoMode == SBR_COUPLING) {
926
        /* calc operation later with log */
927
0
        nrgLeft2 = nrgLeft;
928
0
        nrgLeft = (nrgRight + nrgLeft) >> 1;
929
0
      }
930
931
      /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */
932
      /* If nrgLeft == 0 then the Log calculations below do fail. */
933
0
      if (nrgLeft > FL2FXCONST_DBL(0.0f)) {
934
0
        FIXP_DBL tmp0, tmp1, tmp2, tmp3;
935
0
        INT tmpScale;
936
937
0
        tmpScale = CountLeadingBits(nrgLeft);
938
0
        nrgLeft = nrgLeft << tmpScale;
939
940
0
        tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */
941
0
        tmp1 = ((FIXP_DBL)(commonScale + tmpScale))
942
0
               << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */
943
0
        tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1);
944
0
        tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */
945
0
        tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >>
946
0
               1; /* scaled by 1/64 */
947
948
0
        nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1);
949
0
      } else {
950
0
        nrgLeft = FL2FXCONST_DBL(-1.0f);
951
0
      }
952
953
      /* ld64 to integer conversion */
954
0
      nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)),
955
0
                       (FL2FXCONST_DBL(0.5f) >> oneBitLess));
956
0
      nrgLeft = (FIXP_DBL)(LONG)nrgLeft >>
957
0
                (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1);
958
0
      sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */
959
960
0
      if (stereoMode == SBR_COUPLING) {
961
0
        FIXP_DBL scaleFract;
962
0
        int sc0, sc1;
963
964
0
        nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2);
965
0
        nrgRight = fixMax((FIXP_DBL)0x1, nrgRight);
966
967
0
        sc0 = CountLeadingBits(nrgLeft2);
968
0
        sc1 = CountLeadingBits(nrgRight);
969
970
0
        scaleFract =
971
0
            ((FIXP_DBL)(sc0 - sc1))
972
0
            << (DFRACT_BITS - 1 -
973
0
                LD_DATA_SHIFT); /* scale value in ld64 representation */
974
0
        nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) -
975
0
                   scaleFract;
976
977
        /* ld64 to integer conversion */
978
0
        nrgRight = (FIXP_DBL)(LONG)(nrgRight) >>
979
0
                   (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess);
980
0
        nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */
981
982
0
        sfb_nrgRight[m] = mapPanorama(
983
0
            nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError);
984
985
0
        *maxQuantError = fixMax(quantError, *maxQuantError);
986
0
      }
987
988
0
      m++;
989
0
    } /* j */
990
991
    /* Do energy compensation for sines that are present in two
992
        QMF-bands in the original, but will only occur in one band in
993
        the decoder due to the synthetic sine coding.*/
994
0
    if (h_con->useParametricCoding) {
995
0
      m -= no_of_bands;
996
0
      for (j = 0; j < no_of_bands; j++) {
997
0
        if (freq_res == FREQ_RES_HIGH &&
998
0
            h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) {
999
0
          sfb_nrgLeft[m] -=
1000
0
              (ca *
1001
0
               fixp_abs(
1002
0
                   (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j]));
1003
0
        }
1004
0
        sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]);
1005
0
        m++;
1006
0
      }
1007
0
    } /* useParametricCoding */
1008
1009
0
  } /* env loop */
1010
0
}
1011
1012
/***************************************************************************/
1013
/*!
1014
1015
  \brief  calculates the noise floor and the envelope values from the
1016
          energies, depending on framing and stereo mode
1017
1018
  FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
1019
  envelope and the noise floor. The function includes the following processes:
1020
1021
  -Analysis subband filtering.
1022
  -Encoding SA and pan parameters (if enabled).
1023
  -Transient detection.
1024
1025
****************************************************************************/
1026
1027
LNK_SECTION_CODE_L1
1028
void FDKsbrEnc_extractSbrEnvelope1(
1029
    HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data   */
1030
    HANDLE_SBR_HEADER_DATA sbrHeaderData,
1031
    HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL hEnvChan,
1032
    HANDLE_COMMON_DATA hCmonData, SBR_ENV_TEMP_DATA *eData,
1033
0
    SBR_FRAME_TEMP_DATA *fData) {
1034
0
  HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
1035
1036
0
  if (sbrExtrEnv->YBufferSzShift == 0)
1037
0
    FDKsbrEnc_getEnergyFromCplxQmfDataFull(
1038
0
        &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
1039
0
        sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
1040
0
        sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
1041
0
        sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
1042
0
  else
1043
0
    FDKsbrEnc_getEnergyFromCplxQmfData(
1044
0
        &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
1045
0
        sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
1046
0
        sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
1047
0
        sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
1048
1049
  /* Energie values =
1050
   * sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset][x].floatVal *
1051
   * (1<<2*7-sbrExtrEnv->YBufferScale[1]) */
1052
1053
  /*
1054
    Precalculation of Tonality Quotas  COEFF Transform OK
1055
  */
1056
0
  FDKsbrEnc_CalculateTonalityQuotas(
1057
0
      &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer,
1058
0
      h_con->freqBandTable[HI][h_con->nSfb[HI]], hEnvChan->qmfScale);
1059
1060
0
  if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1061
0
    FIXP_DBL tonality = FDKsbrEnc_GetTonality(
1062
0
        hEnvChan->TonCorr.quotaMatrix,
1063
0
        hEnvChan->TonCorr.numberOfEstimatesPerFrame,
1064
0
        hEnvChan->TonCorr.startIndexMatrix,
1065
0
        sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
1066
0
        h_con->freqBandTable[HI][0] + 1, h_con->noQmfBands,
1067
0
        sbrExtrEnv->no_cols);
1068
1069
0
    hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
1070
0
    hEnvChan->encEnvData.ton_HF[0] = tonality;
1071
1072
    /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
1073
0
    hEnvChan->encEnvData.global_tonality =
1074
0
        (hEnvChan->encEnvData.ton_HF[0] >> 1) +
1075
0
        (hEnvChan->encEnvData.ton_HF[1] >> 1);
1076
0
  }
1077
1078
  /*
1079
    Transient detection COEFF Transform OK
1080
  */
1081
1082
0
  if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1083
0
    FDKsbrEnc_fastTransientDetect(&hEnvChan->sbrFastTransientDetector,
1084
0
                                  sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
1085
0
                                  sbrExtrEnv->YBufferWriteOffset,
1086
0
                                  eData->transient_info);
1087
1088
0
  } else {
1089
0
    FDKsbrEnc_transientDetect(
1090
0
        &hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer,
1091
0
        sbrExtrEnv->YBufferScale, eData->transient_info,
1092
0
        sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift,
1093
0
        sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot);
1094
0
  }
1095
1096
  /*
1097
    Generate flags for 2 env in a FIXFIX-frame.
1098
    Remove this function to get always 1 env per FIXFIX-frame.
1099
  */
1100
1101
  /*
1102
    frame Splitter COEFF Transform OK
1103
  */
1104
0
  FDKsbrEnc_frameSplitter(
1105
0
      sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
1106
0
      &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1],
1107
0
      eData->transient_info, sbrExtrEnv->YBufferWriteOffset,
1108
0
      sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step,
1109
0
      sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality);
1110
0
}
1111
1112
/***************************************************************************/
1113
/*!
1114
1115
  \brief  calculates the noise floor and the envelope values from the
1116
          energies, depending on framing and stereo mode
1117
1118
  FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the
1119
  envelope and the noise floor. The function includes the following processes:
1120
1121
  -Determine time/frequency division of current granule.
1122
  -Sending transient info to bitstream.
1123
  -Set amp_res to 1.5 dB if the current frame contains only one envelope.
1124
  -Lock dynamic bandwidth frequency change if the next envelope not starts on a
1125
  frame boundary.
1126
  -MDCT transposer (needed to detect where harmonics will be missing).
1127
  -Spectrum Estimation (used for pulse train and missing harmonics detection).
1128
  -Pulse train detection.
1129
  -Inverse Filtering detection.
1130
  -Waveform Coding.
1131
  -Missing Harmonics detection.
1132
  -Extract envelope of current frame.
1133
  -Noise floor estimation.
1134
  -Noise floor quantisation and coding.
1135
  -Encode envelope of current frame.
1136
  -Send the encoded data to the bitstream.
1137
  -Write to bitstream.
1138
1139
****************************************************************************/
1140
1141
LNK_SECTION_CODE_L1
1142
void FDKsbrEnc_extractSbrEnvelope2(
1143
    HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data   */
1144
    HANDLE_SBR_HEADER_DATA sbrHeaderData,
1145
    HANDLE_PARAMETRIC_STEREO hParametricStereo,
1146
    HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL h_envChan0,
1147
    HANDLE_ENV_CHANNEL h_envChan1, HANDLE_COMMON_DATA hCmonData,
1148
0
    SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) {
1149
0
  HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1};
1150
0
  int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift;
1151
1152
0
  SBR_STEREO_MODE stereoMode = h_con->stereoMode;
1153
0
  int nChannels = h_con->nChannels;
1154
0
  const int *v_tuning;
1155
0
  static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0};
1156
1157
0
  static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0};
1158
1159
0
  if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
1160
0
    v_tuning = v_tuningELD;
1161
0
  else
1162
0
    v_tuning = v_tuningHEAAC;
1163
1164
  /*
1165
    Select stereo mode.
1166
  */
1167
0
  if (stereoMode == SBR_COUPLING) {
1168
0
    if (eData[0].transient_info[1] && eData[1].transient_info[1]) {
1169
0
      eData[0].transient_info[0] =
1170
0
          fixMin(eData[1].transient_info[0], eData[0].transient_info[0]);
1171
0
      eData[1].transient_info[0] = eData[0].transient_info[0];
1172
0
    } else {
1173
0
      if (eData[0].transient_info[1] && !eData[1].transient_info[1]) {
1174
0
        eData[1].transient_info[0] = eData[0].transient_info[0];
1175
0
      } else {
1176
0
        if (!eData[0].transient_info[1] && eData[1].transient_info[1])
1177
0
          eData[0].transient_info[0] = eData[1].transient_info[0];
1178
0
        else {
1179
0
          eData[0].transient_info[0] =
1180
0
              fixMax(eData[1].transient_info[0], eData[0].transient_info[0]);
1181
0
          eData[1].transient_info[0] = eData[0].transient_info[0];
1182
0
        }
1183
0
      }
1184
0
    }
1185
0
  }
1186
1187
  /*
1188
    Determine time/frequency division of current granule
1189
  */
1190
0
  eData[0].frame_info = FDKsbrEnc_frameInfoGenerator(
1191
0
      &h_envChan[0]->SbrEnvFrame, eData[0].transient_info,
1192
0
      sbrBitstreamData->rightBorderFIX,
1193
0
      h_envChan[0]->sbrExtractEnvelope.pre_transient_info,
1194
0
      h_envChan[0]->encEnvData.ldGrid, v_tuning);
1195
1196
0
  h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
1197
1198
  /* AAC LD patch for transient prediction */
1199
0
  if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) {
1200
    /* if next frame will start with transient, set shortEnv to
1201
     * numEnvelopes(shortend Envelope = shortEnv-1)*/
1202
0
    h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv =
1203
0
        h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
1204
0
  }
1205
1206
0
  switch (stereoMode) {
1207
0
    case SBR_LEFT_RIGHT:
1208
0
    case SBR_SWITCH_LRC:
1209
0
      eData[1].frame_info = FDKsbrEnc_frameInfoGenerator(
1210
0
          &h_envChan[1]->SbrEnvFrame, eData[1].transient_info,
1211
0
          sbrBitstreamData->rightBorderFIX,
1212
0
          h_envChan[1]->sbrExtractEnvelope.pre_transient_info,
1213
0
          h_envChan[1]->encEnvData.ldGrid, v_tuning);
1214
1215
0
      h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid;
1216
1217
0
      if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) {
1218
        /* if next frame will start with transient, set shortEnv to
1219
         * numEnvelopes(shortend Envelope = shortEnv-1)*/
1220
0
        h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv =
1221
0
            h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
1222
0
      }
1223
1224
      /* compare left and right frame_infos */
1225
0
      if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) {
1226
0
        stereoMode = SBR_LEFT_RIGHT;
1227
0
      } else {
1228
0
        for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) {
1229
0
          if (eData[0].frame_info->borders[i] !=
1230
0
              eData[1].frame_info->borders[i]) {
1231
0
            stereoMode = SBR_LEFT_RIGHT;
1232
0
            break;
1233
0
          }
1234
0
        }
1235
0
        for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) {
1236
0
          if (eData[0].frame_info->freqRes[i] !=
1237
0
              eData[1].frame_info->freqRes[i]) {
1238
0
            stereoMode = SBR_LEFT_RIGHT;
1239
0
            break;
1240
0
          }
1241
0
        }
1242
0
        if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) {
1243
0
          stereoMode = SBR_LEFT_RIGHT;
1244
0
        }
1245
0
      }
1246
0
      break;
1247
0
    case SBR_COUPLING:
1248
0
      eData[1].frame_info = eData[0].frame_info;
1249
0
      h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
1250
0
      break;
1251
0
    case SBR_MONO:
1252
      /* nothing to do */
1253
0
      break;
1254
0
    default:
1255
0
      FDK_ASSERT(0);
1256
0
  }
1257
1258
0
  for (ch = 0; ch < nChannels; ch++) {
1259
0
    HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch];
1260
0
    HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
1261
0
    SBR_ENV_TEMP_DATA *ed = &eData[ch];
1262
1263
    /*
1264
       Send transient info to bitstream and store for next call
1265
    */
1266
0
    sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */
1267
0
    sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
1268
0
    hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
1269
0
        ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
1270
0
    hEnvChan->encEnvData.currentAmpResFF = (AMP_RES)h_con->initAmpResFF;
1271
1272
    /*
1273
      Check if the current frame is divided into one envelope only. If so, set
1274
      the amplitude resolution to 1.5 dB, otherwise may set back to chosen value
1275
    */
1276
0
    if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
1277
0
        (ed->nEnvelopes == 1)) {
1278
0
      AMP_RES currentAmpResFF = SBR_AMP_RES_1_5;
1279
0
      if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1280
        /* Note: global_tonality_float_value ==
1281
           ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
1282
                 threshold_float_value ==
1283
           ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0)));
1284
         */
1285
        /* decision of SBR_AMP_RES */
1286
0
        if (fIsLessThan(/* global_tonality > threshold ? */
1287
0
                        h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
1288
0
                        hEnvChan->encEnvData.global_tonality,
1289
0
                        RELAXATION_SHIFT + 2)) {
1290
0
          hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
1291
0
        } else {
1292
0
          hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
1293
0
        }
1294
0
        currentAmpResFF = hEnvChan->encEnvData.currentAmpResFF;
1295
0
      }
1296
1297
0
      if (currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
1298
0
        FDKsbrEnc_InitSbrHuffmanTables(
1299
0
            &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1300
0
            &hEnvChan->sbrCodeNoiseFloor, currentAmpResFF);
1301
0
      }
1302
0
    } else {
1303
0
      if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
1304
0
        FDKsbrEnc_InitSbrHuffmanTables(
1305
0
            &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1306
0
            &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res);
1307
0
      }
1308
0
    }
1309
1310
0
    if (!clearOutput) {
1311
      /*
1312
        Tonality correction parameter extraction (inverse filtering level, noise
1313
        floor additional sines).
1314
      */
1315
0
      FDKsbrEnc_TonCorrParamExtr(
1316
0
          &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec,
1317
0
          ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag,
1318
0
          hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation,
1319
0
          ed->frame_info, ed->transient_info, h_con->freqBandTable[HI],
1320
0
          h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode,
1321
0
          h_con->sbrSyntaxFlags);
1322
0
    }
1323
1324
    /* Low energy in low band fix */
1325
0
    if (hEnvChan->sbrTransientDetector.prevLowBandEnergy <
1326
0
            hEnvChan->sbrTransientDetector.prevHighBandEnergy &&
1327
0
        hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
1328
        /* The fix needs the non-fast transient detector running.
1329
           It sets prevLowBandEnergy and prevHighBandEnergy.      */
1330
0
        && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) {
1331
0
      hEnvChan->fLevelProtect = 1;
1332
1333
0
      for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1334
0
        hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
1335
0
    } else {
1336
0
      hEnvChan->fLevelProtect = 0;
1337
0
    }
1338
1339
0
    hEnvChan->encEnvData.sbr_invf_mode =
1340
0
        hEnvChan->encEnvData.sbr_invf_mode_vec[0];
1341
1342
0
    hEnvChan->encEnvData.noOfnoisebands =
1343
0
        hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
1344
1345
0
  } /* ch */
1346
1347
  /*
1348
     Save number of scf bands per envelope
1349
   */
1350
0
  for (ch = 0; ch < nChannels; ch++) {
1351
0
    for (i = 0; i < eData[ch].nEnvelopes; i++) {
1352
0
      h_envChan[ch]->encEnvData.noScfBands[i] =
1353
0
          (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH
1354
0
               ? h_con->nSfb[FREQ_RES_HIGH]
1355
0
               : h_con->nSfb[FREQ_RES_LOW]);
1356
0
    }
1357
0
  }
1358
1359
0
  if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY &&
1360
0
      stereoMode == SBR_SWITCH_LRC &&
1361
0
      h_envChan[0]->encEnvData.currentAmpResFF !=
1362
0
          h_envChan[1]->encEnvData.currentAmpResFF) {
1363
0
    stereoMode = SBR_LEFT_RIGHT;
1364
0
  }
1365
1366
  /*
1367
    Extract envelope of current frame.
1368
  */
1369
0
  switch (stereoMode) {
1370
0
    case SBR_MONO:
1371
0
      calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1372
0
                           h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1373
0
                           eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1374
0
                           h_envChan[0], SBR_MONO, NULL, YSzShift);
1375
0
      break;
1376
0
    case SBR_LEFT_RIGHT:
1377
0
      calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1378
0
                           h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1379
0
                           eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1380
0
                           h_envChan[0], SBR_MONO, NULL, YSzShift);
1381
0
      calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1382
0
                           h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1383
0
                           eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1384
0
                           h_envChan[1], SBR_MONO, NULL, YSzShift);
1385
0
      break;
1386
0
    case SBR_COUPLING:
1387
0
      calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1388
0
                           h_envChan[1]->sbrExtractEnvelope.YBuffer,
1389
0
                           h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1390
0
                           h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1391
0
                           eData[0].frame_info, eData[0].sfb_nrg,
1392
0
                           eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING,
1393
0
                           &fData->maxQuantError, YSzShift);
1394
0
      break;
1395
0
    case SBR_SWITCH_LRC:
1396
0
      calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1397
0
                           h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1398
0
                           eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1399
0
                           h_envChan[0], SBR_MONO, NULL, YSzShift);
1400
0
      calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1401
0
                           h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1402
0
                           eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1403
0
                           h_envChan[1], SBR_MONO, NULL, YSzShift);
1404
0
      calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1405
0
                           h_envChan[1]->sbrExtractEnvelope.YBuffer,
1406
0
                           h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1407
0
                           h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1408
0
                           eData[0].frame_info, eData[0].sfb_nrg_coupling,
1409
0
                           eData[1].sfb_nrg_coupling, h_con, h_envChan[0],
1410
0
                           SBR_COUPLING, &fData->maxQuantError, YSzShift);
1411
0
      break;
1412
0
  }
1413
1414
  /*
1415
    Noise floor quantisation and coding.
1416
  */
1417
1418
0
  switch (stereoMode) {
1419
0
    case SBR_MONO:
1420
0
      sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1421
0
                                      0);
1422
1423
0
      FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1424
0
                             &h_envChan[0]->sbrCodeNoiseFloor,
1425
0
                             h_envChan[0]->encEnvData.domain_vec_noise, 0,
1426
0
                             (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1427
0
                             sbrBitstreamData->HeaderActive);
1428
1429
0
      break;
1430
0
    case SBR_LEFT_RIGHT:
1431
0
      sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1432
0
                                      0);
1433
1434
0
      FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1435
0
                             &h_envChan[0]->sbrCodeNoiseFloor,
1436
0
                             h_envChan[0]->encEnvData.domain_vec_noise, 0,
1437
0
                             (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1438
0
                             sbrBitstreamData->HeaderActive);
1439
1440
0
      sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1441
0
                                      0);
1442
1443
0
      FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1444
0
                             &h_envChan[1]->sbrCodeNoiseFloor,
1445
0
                             h_envChan[1]->encEnvData.domain_vec_noise, 0,
1446
0
                             (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1447
0
                             sbrBitstreamData->HeaderActive);
1448
1449
0
      break;
1450
1451
0
    case SBR_COUPLING:
1452
0
      coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1453
1454
0
      sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1455
0
                                      0);
1456
1457
0
      FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1458
0
                             &h_envChan[0]->sbrCodeNoiseFloor,
1459
0
                             h_envChan[0]->encEnvData.domain_vec_noise, 1,
1460
0
                             (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1461
0
                             sbrBitstreamData->HeaderActive);
1462
1463
0
      sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1464
0
                                      1);
1465
1466
0
      FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1467
0
                             &h_envChan[1]->sbrCodeNoiseFloor,
1468
0
                             h_envChan[1]->encEnvData.domain_vec_noise, 1,
1469
0
                             (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1470
0
                             sbrBitstreamData->HeaderActive);
1471
1472
0
      break;
1473
0
    case SBR_SWITCH_LRC:
1474
0
      sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1475
0
                                      0);
1476
0
      sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1477
0
                                      0);
1478
0
      coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1479
0
      sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,
1480
0
                                      eData[0].noiseFloor, 0);
1481
0
      sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,
1482
0
                                      eData[1].noiseFloor, 1);
1483
0
      break;
1484
0
  }
1485
1486
  /*
1487
    Encode envelope of current frame.
1488
  */
1489
0
  switch (stereoMode) {
1490
0
    case SBR_MONO:
1491
0
      sbrHeaderData->coupling = 0;
1492
0
      h_envChan[0]->encEnvData.balance = 0;
1493
0
      FDKsbrEnc_codeEnvelope(
1494
0
          eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1495
0
          &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1496
0
          sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1497
0
          sbrBitstreamData->HeaderActive);
1498
0
      break;
1499
0
    case SBR_LEFT_RIGHT:
1500
0
      sbrHeaderData->coupling = 0;
1501
1502
0
      h_envChan[0]->encEnvData.balance = 0;
1503
0
      h_envChan[1]->encEnvData.balance = 0;
1504
1505
0
      FDKsbrEnc_codeEnvelope(
1506
0
          eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1507
0
          &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1508
0
          sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1509
0
          sbrBitstreamData->HeaderActive);
1510
0
      FDKsbrEnc_codeEnvelope(
1511
0
          eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1512
0
          &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1513
0
          sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0,
1514
0
          sbrBitstreamData->HeaderActive);
1515
0
      break;
1516
0
    case SBR_COUPLING:
1517
0
      sbrHeaderData->coupling = 1;
1518
0
      h_envChan[0]->encEnvData.balance = 0;
1519
0
      h_envChan[1]->encEnvData.balance = 1;
1520
1521
0
      FDKsbrEnc_codeEnvelope(
1522
0
          eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1523
0
          &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1524
0
          sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1525
0
          sbrBitstreamData->HeaderActive);
1526
0
      FDKsbrEnc_codeEnvelope(
1527
0
          eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1528
0
          &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1529
0
          sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1,
1530
0
          sbrBitstreamData->HeaderActive);
1531
0
      break;
1532
0
    case SBR_SWITCH_LRC: {
1533
0
      INT payloadbitsLR;
1534
0
      INT payloadbitsCOUPLING;
1535
1536
0
      SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
1537
0
      SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
1538
0
      INT upDateNrgTemp[MAX_NUM_CHANNELS];
1539
0
      INT upDateNoiseTemp[MAX_NUM_CHANNELS];
1540
0
      INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1541
0
      INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1542
1543
0
      INT tempFlagRight = 0;
1544
0
      INT tempFlagLeft = 0;
1545
1546
      /*
1547
         Store previous values, in order to be able to "undo" what is being
1548
         done.
1549
      */
1550
1551
0
      for (ch = 0; ch < nChannels; ch++) {
1552
0
        FDKmemcpy(sfbNrgPrevTemp[ch],
1553
0
                  h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1554
0
                  MAX_FREQ_COEFFS * sizeof(SCHAR));
1555
1556
0
        FDKmemcpy(noisePrevTemp[ch],
1557
0
                  h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1558
0
                  MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1559
1560
0
        upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
1561
0
        upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
1562
1563
        /*
1564
          forbid time coding in the first envelope in case of a different
1565
          previous stereomode
1566
        */
1567
0
        if (sbrHeaderData->prev_coupling) {
1568
0
          h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1569
0
          h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1570
0
        }
1571
0
      } /* ch */
1572
1573
      /*
1574
         Code ordinary Left/Right stereo
1575
      */
1576
0
      FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1577
0
                             &h_envChan[0]->sbrCodeEnvelope,
1578
0
                             h_envChan[0]->encEnvData.domain_vec, 0,
1579
0
                             eData[0].frame_info->nEnvelopes, 0,
1580
0
                             sbrBitstreamData->HeaderActive);
1581
0
      FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1582
0
                             &h_envChan[1]->sbrCodeEnvelope,
1583
0
                             h_envChan[1]->encEnvData.domain_vec, 0,
1584
0
                             eData[1].frame_info->nEnvelopes, 0,
1585
0
                             sbrBitstreamData->HeaderActive);
1586
1587
0
      c = 0;
1588
0
      for (i = 0; i < eData[0].nEnvelopes; i++) {
1589
0
        for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1590
0
          h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
1591
0
          h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
1592
0
          c++;
1593
0
        }
1594
0
      }
1595
1596
0
      FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1597
0
                             &h_envChan[0]->sbrCodeNoiseFloor,
1598
0
                             h_envChan[0]->encEnvData.domain_vec_noise, 0,
1599
0
                             (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1600
0
                             sbrBitstreamData->HeaderActive);
1601
1602
0
      for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1603
0
        h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
1604
1605
0
      FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1606
0
                             &h_envChan[1]->sbrCodeNoiseFloor,
1607
0
                             h_envChan[1]->encEnvData.domain_vec_noise, 0,
1608
0
                             (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1609
0
                             sbrBitstreamData->HeaderActive);
1610
1611
0
      for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1612
0
        h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
1613
1614
0
      sbrHeaderData->coupling = 0;
1615
0
      h_envChan[0]->encEnvData.balance = 0;
1616
0
      h_envChan[1]->encEnvData.balance = 0;
1617
1618
0
      payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement(
1619
0
          sbrHeaderData, hParametricStereo, sbrBitstreamData,
1620
0
          &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1621
0
          h_con->sbrSyntaxFlags);
1622
1623
      /*
1624
        swap saved stored with current values
1625
      */
1626
0
      for (ch = 0; ch < nChannels; ch++) {
1627
0
        INT itmp;
1628
0
        for (i = 0; i < MAX_FREQ_COEFFS; i++) {
1629
          /*
1630
            swap sfb energies
1631
          */
1632
0
          itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
1633
0
          h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] =
1634
0
              sfbNrgPrevTemp[ch][i];
1635
0
          sfbNrgPrevTemp[ch][i] = itmp;
1636
0
        }
1637
0
        for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) {
1638
          /*
1639
            swap noise energies
1640
          */
1641
0
          itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
1642
0
          h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] =
1643
0
              noisePrevTemp[ch][i];
1644
0
          noisePrevTemp[ch][i] = itmp;
1645
0
        }
1646
        /* swap update flags */
1647
0
        itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
1648
0
        h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1649
0
        upDateNrgTemp[ch] = itmp;
1650
1651
0
        itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
1652
0
        h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1653
0
        upDateNoiseTemp[ch] = itmp;
1654
1655
        /*
1656
            save domain vecs
1657
        */
1658
0
        FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec,
1659
0
                  sizeof(INT) * MAX_ENVELOPES);
1660
0
        FDKmemcpy(domainVecNoiseTemp[ch],
1661
0
                  h_envChan[ch]->encEnvData.domain_vec_noise,
1662
0
                  sizeof(INT) * MAX_ENVELOPES);
1663
1664
        /*
1665
          forbid time coding in the first envelope in case of a different
1666
          previous stereomode
1667
        */
1668
1669
0
        if (!sbrHeaderData->prev_coupling) {
1670
0
          h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1671
0
          h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1672
0
        }
1673
0
      } /* ch */
1674
1675
      /*
1676
         Coupling
1677
       */
1678
1679
0
      FDKsbrEnc_codeEnvelope(
1680
0
          eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
1681
0
          &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1682
0
          1, eData[0].frame_info->nEnvelopes, 0,
1683
0
          sbrBitstreamData->HeaderActive);
1684
1685
0
      FDKsbrEnc_codeEnvelope(
1686
0
          eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
1687
0
          &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1688
0
          1, eData[1].frame_info->nEnvelopes, 1,
1689
0
          sbrBitstreamData->HeaderActive);
1690
1691
0
      c = 0;
1692
0
      for (i = 0; i < eData[0].nEnvelopes; i++) {
1693
0
        for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1694
0
          h_envChan[0]->encEnvData.ienvelope[i][j] =
1695
0
              eData[0].sfb_nrg_coupling[c];
1696
0
          h_envChan[1]->encEnvData.ienvelope[i][j] =
1697
0
              eData[1].sfb_nrg_coupling[c];
1698
0
          c++;
1699
0
        }
1700
0
      }
1701
1702
0
      FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res,
1703
0
                             &h_envChan[0]->sbrCodeNoiseFloor,
1704
0
                             h_envChan[0]->encEnvData.domain_vec_noise, 1,
1705
0
                             (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1706
0
                             sbrBitstreamData->HeaderActive);
1707
1708
0
      for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1709
0
        h_envChan[0]->encEnvData.sbr_noise_levels[i] =
1710
0
            eData[0].noise_level_coupling[i];
1711
1712
0
      FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res,
1713
0
                             &h_envChan[1]->sbrCodeNoiseFloor,
1714
0
                             h_envChan[1]->encEnvData.domain_vec_noise, 1,
1715
0
                             (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1716
0
                             sbrBitstreamData->HeaderActive);
1717
1718
0
      for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1719
0
        h_envChan[1]->encEnvData.sbr_noise_levels[i] =
1720
0
            eData[1].noise_level_coupling[i];
1721
1722
0
      sbrHeaderData->coupling = 1;
1723
1724
0
      h_envChan[0]->encEnvData.balance = 0;
1725
0
      h_envChan[1]->encEnvData.balance = 1;
1726
1727
0
      tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
1728
0
      tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
1729
1730
0
      payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement(
1731
0
          sbrHeaderData, hParametricStereo, sbrBitstreamData,
1732
0
          &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1733
0
          h_con->sbrSyntaxFlags);
1734
1735
0
      h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
1736
0
      h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
1737
1738
0
      if (payloadbitsCOUPLING < payloadbitsLR) {
1739
        /*
1740
          copy coded coupling envelope and noise data to l/r
1741
        */
1742
0
        for (ch = 0; ch < nChannels; ch++) {
1743
0
          SBR_ENV_TEMP_DATA *ed = &eData[ch];
1744
0
          FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling,
1745
0
                    MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR));
1746
0
          FDKmemcpy(ed->noise_level, ed->noise_level_coupling,
1747
0
                    MAX_NUM_NOISE_VALUES * sizeof(SCHAR));
1748
0
        }
1749
1750
0
        sbrHeaderData->coupling = 1;
1751
0
        h_envChan[0]->encEnvData.balance = 0;
1752
0
        h_envChan[1]->encEnvData.balance = 1;
1753
0
      } else {
1754
        /*
1755
          restore saved l/r items
1756
        */
1757
0
        for (ch = 0; ch < nChannels; ch++) {
1758
0
          FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1759
0
                    sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR));
1760
1761
0
          h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1762
1763
0
          FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1764
0
                    noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1765
1766
0
          FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch],
1767
0
                    sizeof(INT) * MAX_ENVELOPES);
1768
0
          FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise,
1769
0
                    domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES);
1770
1771
0
          h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1772
0
        }
1773
1774
0
        sbrHeaderData->coupling = 0;
1775
0
        h_envChan[0]->encEnvData.balance = 0;
1776
0
        h_envChan[1]->encEnvData.balance = 0;
1777
0
      }
1778
0
    } break;
1779
0
  } /* switch */
1780
1781
  /* tell the envelope encoders how long it has been, since we last sent
1782
     a frame starting with a dF-coded envelope */
1783
0
  if (stereoMode == SBR_MONO) {
1784
0
    if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
1785
0
      h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1786
0
    else
1787
0
      h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1788
0
  } else {
1789
0
    if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
1790
0
        h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
1791
0
      h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1792
0
      h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
1793
0
    } else {
1794
0
      h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1795
0
      h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1796
0
    }
1797
0
  }
1798
1799
  /*
1800
    Send the encoded data to the bitstream
1801
  */
1802
0
  for (ch = 0; ch < nChannels; ch++) {
1803
0
    SBR_ENV_TEMP_DATA *ed = &eData[ch];
1804
0
    c = 0;
1805
0
    for (i = 0; i < ed->nEnvelopes; i++) {
1806
0
      for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
1807
0
        h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
1808
1809
0
        c++;
1810
0
      }
1811
0
    }
1812
0
    for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
1813
0
      h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
1814
0
    }
1815
0
  } /* ch */
1816
1817
  /*
1818
    Write bitstream
1819
  */
1820
0
  if (nChannels == 2) {
1821
0
    FDKsbrEnc_WriteEnvChannelPairElement(
1822
0
        sbrHeaderData, hParametricStereo, sbrBitstreamData,
1823
0
        &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1824
0
        h_con->sbrSyntaxFlags);
1825
0
  } else {
1826
0
    FDKsbrEnc_WriteEnvSingleChannelElement(
1827
0
        sbrHeaderData, hParametricStereo, sbrBitstreamData,
1828
0
        &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags);
1829
0
  }
1830
1831
  /*
1832
   * Update buffers.
1833
   */
1834
0
  for (ch = 0; ch < nChannels; ch++) {
1835
0
    int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >>
1836
0
                        h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
1837
0
    for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
1838
0
      FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
1839
0
                h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
1840
0
                sizeof(FIXP_DBL) * 64);
1841
0
    }
1842
0
    h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] =
1843
0
        h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
1844
0
  }
1845
1846
0
  sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
1847
0
}
1848
1849
/***************************************************************************/
1850
/*!
1851
1852
  \brief  creates an envelope extractor handle
1853
1854
  \return error status
1855
1856
****************************************************************************/
1857
INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
1858
                                       INT channel, INT chInEl,
1859
0
                                       UCHAR *dynamic_RAM) {
1860
0
  INT i;
1861
0
  FIXP_DBL *rBuffer, *iBuffer;
1862
0
  INT n;
1863
0
  FIXP_DBL *YBufferDyn;
1864
1865
0
  FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE));
1866
1867
0
  if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) {
1868
0
    goto bail;
1869
0
  }
1870
1871
0
  for (i = 0; i < (32 >> 1); i++) {
1872
0
    hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64);
1873
0
  }
1874
0
  YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1875
0
  for (n = 0; i < 32; i++, n++) {
1876
0
    hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1877
0
  }
1878
1879
0
  rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
1880
0
  iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
1881
1882
0
  for (i = 0; i < 32; i++) {
1883
0
    hSbrCut->rBuffer[i] = rBuffer + (i * 64);
1884
0
    hSbrCut->iBuffer[i] = iBuffer + (i * 64);
1885
0
  }
1886
1887
0
  return 0;
1888
1889
0
bail:
1890
0
  FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut);
1891
1892
0
  return -1;
1893
0
}
1894
1895
/***************************************************************************/
1896
/*!
1897
1898
  \brief  Initialize an envelope extractor instance.
1899
1900
  \return error status
1901
1902
****************************************************************************/
1903
INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
1904
                                     int no_cols, int no_rows, int start_index,
1905
                                     int time_slots, int time_step,
1906
                                     int tran_off, ULONG statesInitFlag,
1907
                                     int chInEl, UCHAR *dynamic_RAM,
1908
0
                                     UINT sbrSyntaxFlags) {
1909
0
  int YBufferLength, rBufferLength;
1910
0
  int i;
1911
1912
0
  if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1913
0
    int off = TRANSIENT_OFFSET_LD;
1914
0
    hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step;
1915
0
  } else {
1916
0
    hSbrCut->YBufferWriteOffset = tran_off * time_step;
1917
0
  }
1918
0
  hSbrCut->rBufferReadOffset = 0;
1919
1920
0
  YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
1921
0
  rBufferLength = no_cols;
1922
1923
0
  hSbrCut->pre_transient_info[0] = 0;
1924
0
  hSbrCut->pre_transient_info[1] = 0;
1925
1926
0
  hSbrCut->no_cols = no_cols;
1927
0
  hSbrCut->no_rows = no_rows;
1928
0
  hSbrCut->start_index = start_index;
1929
1930
0
  hSbrCut->time_slots = time_slots;
1931
0
  hSbrCut->time_step = time_step;
1932
1933
0
  FDK_ASSERT(no_rows <= 64);
1934
1935
  /* Use half the Energy values if time step is 2 or greater */
1936
0
  if (time_step >= 2)
1937
0
    hSbrCut->YBufferSzShift = 1;
1938
0
  else
1939
0
    hSbrCut->YBufferSzShift = 0;
1940
1941
0
  YBufferLength >>= hSbrCut->YBufferSzShift;
1942
0
  hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
1943
1944
0
  FDK_ASSERT(YBufferLength <= 32);
1945
1946
0
  FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1947
0
  INT n = 0;
1948
0
  for (i = (32 >> 1); i < 32; i++, n++) {
1949
0
    hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1950
0
  }
1951
1952
0
  if (statesInitFlag) {
1953
0
    for (i = 0; i < YBufferLength; i++) {
1954
0
      FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL));
1955
0
    }
1956
0
  }
1957
1958
0
  for (i = 0; i < rBufferLength; i++) {
1959
0
    FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL));
1960
0
    FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL));
1961
0
  }
1962
1963
0
  FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
1964
1965
0
  if (statesInitFlag) {
1966
0
    hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1;
1967
0
  }
1968
1969
0
  return (0);
1970
0
}
1971
1972
/***************************************************************************/
1973
/*!
1974
1975
  \brief  deinitializes an envelope extractor handle
1976
1977
  \return void
1978
1979
****************************************************************************/
1980
1981
0
void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) {
1982
0
  if (hSbrCut) {
1983
0
    FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
1984
0
  }
1985
0
}
1986
1987
0
INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) {
1988
0
  return hSbr->no_rows *
1989
0
         ((hSbr->YBufferWriteOffset) *
1990
0
              2 /* mult 2 because nrg's are grouped half */
1991
0
          - hSbr->rBufferReadOffset); /* in reference hold half spec and calc
1992
                                         nrg's on overlapped spec */
1993
0
}