• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ****************************************************************************/
FDKsbrEnc_GetTonality(const FIXP_DBL * const * quotaMatrix,const INT noEstPerFrame,const INT startIndex,const FIXP_DBL * const * Energies,const UCHAR startBand,const INT stopBand,const INT numberCols)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                                       const INT numberCols) {
150   UCHAR b, e, k;
151   INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = {-1, -1, -1, -1, -1};
152   FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = {
153       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
154       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
155   FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */
156   UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */
157   FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = {
158       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f),
159       FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)};
160   FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f);
161   FIXP_DBL energyBand[64];
162   INT maxNEnergyValues; /* max. number of max. energy values */
163 
164   /*** Sum up energies for each band ***/
165   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   if (numberCols == 15) {
170     for (b = startBand; b < stopBand; b++) {
171       energyBand[b] = FL2FXCONST_DBL(0.0f);
172     }
173   } else {
174     for (b = startBand; b < stopBand; b++) {
175       energyBand[b] = Energies[15][b] >> 4;
176     }
177   }
178 
179   for (k = 0; k < 15; k++) {
180     for (b = startBand; b < stopBand; b++) {
181       energyBand[b] += Energies[k][b] >> 4;
182     }
183   }
184 
185   /*** Determine 5 highest band-energies ***/
186   maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand - startBand);
187 
188   /* Get min. value in energyMax array */
189   energyMaxMin = energyMax[0] = energyBand[startBand];
190   no_enMaxBand[0] = startBand;
191   posEnergyMaxMin = 0;
192   for (k = 1; k < maxNEnergyValues; k++) {
193     energyMax[k] = energyBand[startBand + k];
194     no_enMaxBand[k] = startBand + k;
195     if (energyMaxMin > energyMax[k]) {
196       energyMaxMin = energyMax[k];
197       posEnergyMaxMin = k;
198     }
199   }
200 
201   for (b = startBand + maxNEnergyValues; b < stopBand; b++) {
202     if (energyBand[b] > energyMaxMin) {
203       energyMax[posEnergyMaxMin] = energyBand[b];
204       no_enMaxBand[posEnergyMaxMin] = b;
205 
206       /* Again, get min. value in energyMax array */
207       energyMaxMin = energyMax[0];
208       posEnergyMaxMin = 0;
209       for (k = 1; k < maxNEnergyValues; k++) {
210         if (energyMaxMin > energyMax[k]) {
211           energyMaxMin = energyMax[k];
212           posEnergyMaxMin = k;
213         }
214       }
215     }
216   }
217   /*** End determine 5 highest band-energies ***/
218 
219   /* Get tonality values for 5 highest energies */
220   for (e = 0; e < maxNEnergyValues; e++) {
221     tonalityBand[e] = FL2FXCONST_DBL(0.0f);
222     for (k = 0; k < noEstPerFrame; k++) {
223       tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1;
224     }
225     globalTonality +=
226         tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */
227   }
228 
229   return globalTonality;
230 }
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
FDKsbrEnc_getEnergyFromCplxQmfData(FIXP_DBL ** RESTRICT energyValues,FIXP_DBL ** RESTRICT realValues,FIXP_DBL ** RESTRICT imagValues,INT numberBands,INT numberCols,INT * qmfScale,INT * energyScale)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 {
252   int j, k;
253   int scale;
254   FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
255 
256   /* Get Scratch buffer */
257   C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2)
258 
259   /* Get max possible scaling of QMF data */
260   scale = DFRACT_BITS;
261   for (k = 0; k < numberCols; k++) {
262     scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
263                                  getScalefactor(imagValues[k], numberBands)));
264   }
265 
266   /* Tweak scaling stability for zero signal to non-zero signal transitions */
267   if (scale >= DFRACT_BITS - 1) {
268     scale = (FRACT_BITS - 1 - *qmfScale);
269   }
270   /* prevent scaling of QMF values to -1.f */
271   scale = fixMax(0, scale - 1);
272 
273   /* Update QMF scale */
274   *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   {
281     FIXP_DBL *nrgValues = tmpNrg;
282     for (k = 0; k < numberCols; k += 2) {
283       /* Load band vector addresses of 2 consecutive timeslots */
284       FIXP_DBL *RESTRICT r0 = realValues[k];
285       FIXP_DBL *RESTRICT i0 = imagValues[k];
286       FIXP_DBL *RESTRICT r1 = realValues[k + 1];
287       FIXP_DBL *RESTRICT i1 = imagValues[k + 1];
288       for (j = 0; j < numberBands; j++) {
289         FIXP_DBL energy;
290         FIXP_DBL tr0, tr1, ti0, ti1;
291 
292         /* Read QMF values of 2 timeslots */
293         tr0 = r0[j];
294         tr1 = r1[j];
295         ti0 = i0[j];
296         ti1 = i1[j];
297 
298         /* Scale QMF Values and Calc Energy average of both timeslots */
299         tr0 <<= scale;
300         ti0 <<= scale;
301         energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1;
302 
303         tr1 <<= scale;
304         ti1 <<= scale;
305         energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1;
306 
307         /* Write timeslot pair energy to scratch */
308         *nrgValues++ = energy;
309         max_val = fixMax(max_val, energy);
310 
311         /* Write back scaled QMF values */
312         r0[j] = tr0;
313         r1[j] = tr1;
314         i0[j] = ti0;
315         i1[j] = ti1;
316       }
317     }
318   }
319   /* energyScale: scalefactor energies of current frame */
320   *energyScale =
321       2 * (*qmfScale) -
322       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   scale = CountLeadingBits(max_val);
326   {
327     FIXP_DBL *nrgValues = tmpNrg;
328     for (k = 0; k<numberCols>> 1; k++) {
329       scaleValues(energyValues[k], nrgValues, numberBands, scale);
330       nrgValues += numberBands;
331     }
332     *energyScale += scale;
333   }
334 
335   /* Free Scratch buffer */
336   C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2)
337 }
338 
339 LNK_SECTION_CODE_L1
FDKsbrEnc_getEnergyFromCplxQmfDataFull(FIXP_DBL ** RESTRICT energyValues,FIXP_DBL ** RESTRICT realValues,FIXP_DBL ** RESTRICT imagValues,int numberBands,int numberCols,int * qmfScale,int * energyScale)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 {
350   int j, k;
351   int scale;
352   FIXP_DBL max_val = FL2FXCONST_DBL(0.0f);
353 
354   /* Get Scratch buffer */
355   C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
356 
357   FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD);
358   FDK_ASSERT(numberBands <= 64);
359 
360   /* Get max possible scaling of QMF data */
361   scale = DFRACT_BITS;
362   for (k = 0; k < numberCols; k++) {
363     scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands),
364                                  getScalefactor(imagValues[k], numberBands)));
365   }
366 
367   /* Tweak scaling stability for zero signal to non-zero signal transitions */
368   if (scale >= DFRACT_BITS - 1) {
369     scale = (FRACT_BITS - 1 - *qmfScale);
370   }
371   /* prevent scaling of QFM values to -1.f */
372   scale = fixMax(0, scale - 1);
373 
374   /* Update QMF scale */
375   *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   {
382     FIXP_DBL *nrgValues = tmpNrg;
383     for (k = 0; k < numberCols; k++) {
384       /* Load band vector addresses of 1 timeslot */
385       FIXP_DBL *RESTRICT r0 = realValues[k];
386       FIXP_DBL *RESTRICT i0 = imagValues[k];
387       for (j = 0; j < numberBands; j++) {
388         FIXP_DBL energy;
389         FIXP_DBL tr0, ti0;
390 
391         /* Read QMF values of 1 timeslot */
392         tr0 = r0[j];
393         ti0 = i0[j];
394 
395         /* Scale QMF Values and Calc Energy */
396         tr0 <<= scale;
397         ti0 <<= scale;
398         energy = fPow2AddDiv2(fPow2Div2(tr0), ti0);
399         *nrgValues++ = energy;
400 
401         max_val = fixMax(max_val, energy);
402 
403         /* Write back scaled QMF values */
404         r0[j] = tr0;
405         i0[j] = ti0;
406       }
407     }
408   }
409   /* energyScale: scalefactor energies of current frame */
410   *energyScale =
411       2 * (*qmfScale) -
412       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   scale = CountLeadingBits(max_val);
416   {
417     FIXP_DBL *nrgValues = tmpNrg;
418     for (k = 0; k < numberCols; k++) {
419       scaleValues(energyValues[k], nrgValues, numberBands, scale);
420       nrgValues += numberBands;
421     }
422     *energyScale += scale;
423   }
424 
425   /* Free Scratch buffer */
426   C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64)
427 }
428 
429 /***************************************************************************/
430 /*!
431 
432   \brief  Quantisation of the panorama value (balance)
433 
434   \return the quantized pan value
435 
436 ****************************************************************************/
mapPanorama(INT nrgVal,INT ampRes,INT * quantError)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 ) {
441   int i;
442   INT min_val, val;
443   UCHAR panIndex;
444   INT sign;
445 
446   sign = nrgVal > 0 ? 1 : -1;
447 
448   nrgVal *= sign;
449 
450   min_val = FDK_INT_MAX;
451   panIndex = 0;
452   for (i = 0; i < maxIndex[ampRes]; i++) {
453     val = fixp_abs((nrgVal - (INT)panTable[ampRes][i]));
454 
455     if (val < min_val) {
456       min_val = val;
457       panIndex = i;
458     }
459   }
460 
461   *quantError = min_val;
462 
463   return panTable[ampRes][maxIndex[ampRes] - 1] +
464          sign * panTable[ampRes][panIndex];
465 }
466 
467 /***************************************************************************/
468 /*!
469 
470   \brief  Quantisation of the noise floor levels
471 
472   \return void
473 
474 ****************************************************************************/
sbrNoiseFloorLevelsQuantisation(SCHAR * RESTRICT iNoiseLevels,FIXP_DBL * RESTRICT NoiseLevels,INT coupling)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 ) {
481   INT i;
482   INT tmp, dummy;
483 
484   /* Quantisation, similar to sfb quant... */
485   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     if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) {
490       tmp = 30;
491     } 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       tmp = ((((INT)NoiseLevels[i]) >>
499               (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */
500       if (tmp != 0) tmp += 1;
501     }
502 
503     if (coupling) {
504       tmp = tmp < -30 ? -30 : tmp;
505       tmp = mapPanorama(tmp, 1, &dummy);
506     }
507     iNoiseLevels[i] = tmp;
508   }
509 }
510 
511 /***************************************************************************/
512 /*!
513 
514   \brief  Calculation of noise floor for coupling
515 
516   \return void
517 
518 ****************************************************************************/
coupleNoiseFloor(FIXP_DBL * RESTRICT noise_level_left,FIXP_DBL * RESTRICT noise_level_right)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 ) {
523   FIXP_DBL cmpValLeft, cmpValRight;
524   INT i;
525   FIXP_DBL temp1, temp2;
526 
527   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     cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i];
534     cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i];
535 
536     if (cmpValRight < FL2FXCONST_DBL(0.0f)) {
537       temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
538     } else {
539       temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]);
540       temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
541                         1); /* INT to fract conversion of result, if input of
542                                CalcInvLdData is positiv */
543     }
544 
545     if (cmpValLeft < FL2FXCONST_DBL(0.0f)) {
546       temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
547     } else {
548       temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]);
549       temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT -
550                         1); /* INT to fract conversion of result, if input of
551                                CalcInvLdData is positiv */
552     }
553 
554     if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
555         (cmpValRight < FL2FXCONST_DBL(0.0f))) {
556       noise_level_left[i] =
557           NOISE_FLOOR_OFFSET_64 -
558           (CalcLdData(
559               ((temp1 >> 1) +
560                (temp2 >> 1)))); /* no scaling needed! both values are dfract */
561       noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
562     }
563 
564     if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
565         (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
566       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
567                             (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) +
568                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
569       noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1);
570     }
571 
572     if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) &&
573         (cmpValRight < FL2FXCONST_DBL(0.0f))) {
574       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
575                             (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) +
576                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
577       noise_level_right[i] =
578           (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1);
579     }
580 
581     if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) &&
582         (cmpValRight >= FL2FXCONST_DBL(0.0f))) {
583       noise_level_left[i] = NOISE_FLOOR_OFFSET_64 -
584                             (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) +
585                              FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
586       noise_level_right[i] = CalcLdData(temp2) -
587                              (CalcLdData(temp1) +
588                               FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */
589     }
590   }
591 }
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 
getEnvSfbEnergy(INT li,INT ui,INT start_pos,INT stop_pos,INT border_pos,FIXP_DBL ** YBuffer,INT YBufferSzShift,INT scaleNrg0,INT scaleNrg1)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 {
614   /* use dynamic scaling for outer energy loop;
615      energies are critical and every bit is important */
616   int sc0, sc1, k, l;
617 
618   FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2;
619   INT dynScale, dynScale1, dynScale2;
620   if (ui - li == 0)
621     dynScale = DFRACT_BITS - 1;
622   else
623     dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT);
624 
625   sc0 = fixMin(scaleNrg0, Y_NRG_SCALE);
626   sc1 = fixMin(scaleNrg1, Y_NRG_SCALE);
627   /* dynScale{1,2} is set such that the right shift below is positive */
628   dynScale1 = fixMin((scaleNrg0 - sc0), dynScale);
629   dynScale2 = fixMin((scaleNrg1 - sc1), dynScale);
630   nrgSum = accu1 = accu2 = (FIXP_DBL)0;
631 
632   for (k = li; k < ui; k++) {
633     nrg1 = nrg2 = (FIXP_DBL)0;
634     for (l = start_pos; l < border_pos; l++) {
635       nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0;
636     }
637     for (; l < stop_pos; l++) {
638       nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1;
639     }
640     accu1 += (nrg1 >> dynScale1);
641     accu2 += (nrg2 >> dynScale2);
642   }
643   /* This shift factor is always positive. See comment above. */
644   nrgSum +=
645       (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) +
646       (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1)));
647 
648   return nrgSum;
649 }
650 
651 /***************************************************************************/
652 /*!
653 
654   \brief  Energy compensation in missing harmonic mode
655 
656   \return void
657 
658 ****************************************************************************/
mhLoweringEnergy(FIXP_DBL nrg,INT M)659 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   if (M > 2) {
671     INT tmpScale;
672     tmpScale = CountLeadingBits(nrg);
673     nrg <<= tmpScale;
674     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     nrg >>= tmpScale;
681   } else {
682     if (M > 1) {
683       nrg >>= 1;
684     }
685   }
686 
687   return nrg;
688 }
689 
690 /***************************************************************************/
691 /*!
692 
693   \brief  Energy compensation in none missing harmonic mode
694 
695   \return void
696 
697 ****************************************************************************/
nmhLoweringEnergy(FIXP_DBL nrg,const FIXP_DBL nrgSum,const INT nrgSum_scale,const INT M)698 static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum,
699                                   const INT nrgSum_scale, const INT M) {
700   if (nrg > FL2FXCONST_DBL(0)) {
701     int sc = 0;
702     /* gain = nrgSum / (nrg*(M+1)) */
703     FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1));
704     sc += nrgSum_scale;
705 
706     /* reduce nrg if gain smaller 1.f */
707     if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) {
708       nrg = fMult(scaleValue(gain, sc), nrg);
709     }
710   }
711   return nrg;
712 }
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 ****************************************************************************/
calculateSbrEnvelope(FIXP_DBL ** RESTRICT YBufferLeft,FIXP_DBL ** RESTRICT YBufferRight,int * RESTRICT YBufferScaleLeft,int * RESTRICT YBufferScaleRight,const SBR_FRAME_INFO * frame_info,SCHAR * RESTRICT sfb_nrgLeft,SCHAR * RESTRICT sfb_nrgRight,HANDLE_SBR_CONFIG_DATA h_con,HANDLE_ENV_CHANNEL h_sbr,SBR_STEREO_MODE stereoMode,INT * maxQuantError,int YBufferSzShift)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 {
738   int env, j, m = 0;
739   INT no_of_bands, start_pos, stop_pos, li, ui;
740   FREQ_RES freq_res;
741 
742   INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res;
743   INT oneBitLess = 0;
744   if (ca == 2)
745     oneBitLess =
746         1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */
747 
748   INT quantError;
749   INT nEnvelopes = frame_info->nEnvelopes;
750   INT short_env = frame_info->shortEnv - 1;
751   INT timeStep = h_sbr->sbrExtractEnvelope.time_step;
752   INT commonScale, scaleLeft0, scaleLeft1;
753   INT scaleRight0 = 0, scaleRight1 = 0;
754 
755   commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]);
756 
757   if (stereoMode == SBR_COUPLING) {
758     commonScale = fixMin(commonScale, YBufferScaleRight[0]);
759     commonScale = fixMin(commonScale, YBufferScaleRight[1]);
760   }
761 
762   commonScale = commonScale - 7;
763 
764   scaleLeft0 = YBufferScaleLeft[0] - commonScale;
765   scaleLeft1 = YBufferScaleLeft[1] - commonScale;
766   FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0));
767 
768   if (stereoMode == SBR_COUPLING) {
769     scaleRight0 = YBufferScaleRight[0] - commonScale;
770     scaleRight1 = YBufferScaleRight[1] - commonScale;
771     FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0));
772     *maxQuantError = 0;
773   }
774 
775   for (env = 0; env < nEnvelopes; env++) {
776     FIXP_DBL pNrgLeft[32];
777     FIXP_DBL pNrgRight[32];
778     int envNrg_scale;
779     FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f);
780     FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f);
781     int missingHarmonic[32];
782     int count[32];
783 
784     start_pos = timeStep * frame_info->borders[env];
785     stop_pos = timeStep * frame_info->borders[env + 1];
786     freq_res = frame_info->freqRes[env];
787     no_of_bands = h_con->nSfb[freq_res];
788     envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands);
789     if (env == short_env) {
790       j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short
791                                 envelopes (envelopes just before transients) */
792       if ((stop_pos - start_pos - j) > 0) {
793         stop_pos = stop_pos - j;
794       }
795     }
796     for (j = 0; j < no_of_bands; j++) {
797       FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f);
798       FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f);
799 
800       li = h_con->freqBandTable[freq_res][j];
801       ui = h_con->freqBandTable[freq_res][j + 1];
802 
803       if (freq_res == FREQ_RES_HIGH) {
804         if (j == 0 && ui - li > 1) {
805           li++;
806         }
807       } else {
808         if (j == 0 && ui - li > 2) {
809           li++;
810         }
811       }
812 
813       /*
814         Find out whether a sine will be missing in the scale-factor
815         band that we're currently processing.
816       */
817       missingHarmonic[j] = 0;
818 
819       if (h_sbr->encEnvData.addHarmonicFlag) {
820         if (freq_res == FREQ_RES_HIGH) {
821           if (h_sbr->encEnvData
822                   .addHarmonic[j]) { /*A missing sine in the current band*/
823             missingHarmonic[j] = 1;
824           }
825         } else {
826           INT i;
827           INT startBandHigh = 0;
828           INT stopBandHigh = 0;
829 
830           while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] <
831                  h_con->freqBandTable[FREQ_RES_LOW][j])
832             startBandHigh++;
833           while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] <
834                  h_con->freqBandTable[FREQ_RES_LOW][j + 1])
835             stopBandHigh++;
836 
837           for (i = startBandHigh; i < stopBandHigh; i++) {
838             if (h_sbr->encEnvData.addHarmonic[i]) {
839               missingHarmonic[j] = 1;
840             }
841           }
842         }
843       }
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       int border_pos =
851           fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset
852                                << YBufferSzShift);
853 
854       if (missingHarmonic[j]) {
855         int k;
856         count[j] = stop_pos - start_pos;
857         nrgLeft = FL2FXCONST_DBL(0.0f);
858 
859         for (k = li; k < ui; k++) {
860           FIXP_DBL tmpNrg;
861           tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
862                                    YBufferLeft, YBufferSzShift, scaleLeft0,
863                                    scaleLeft1);
864 
865           nrgLeft = fixMax(nrgLeft, tmpNrg);
866         }
867 
868         /* Energy lowering compensation */
869         nrgLeft = mhLoweringEnergy(nrgLeft, ui - li);
870 
871         if (stereoMode == SBR_COUPLING) {
872           nrgRight = FL2FXCONST_DBL(0.0f);
873 
874           for (k = li; k < ui; k++) {
875             FIXP_DBL tmpNrg;
876             tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos,
877                                      YBufferRight, YBufferSzShift, scaleRight0,
878                                      scaleRight1);
879 
880             nrgRight = fixMax(nrgRight, tmpNrg);
881           }
882 
883           /* Energy lowering compensation */
884           nrgRight = mhLoweringEnergy(nrgRight, ui - li);
885         }
886       } /* end missingHarmonic */
887       else {
888         count[j] = (stop_pos - start_pos) * (ui - li);
889 
890         nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
891                                   YBufferLeft, YBufferSzShift, scaleLeft0,
892                                   scaleLeft1);
893 
894         if (stereoMode == SBR_COUPLING) {
895           nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos,
896                                      YBufferRight, YBufferSzShift, scaleRight0,
897                                      scaleRight1);
898         }
899       } /* !missingHarmonic */
900 
901       /* save energies */
902       pNrgLeft[j] = nrgLeft;
903       pNrgRight[j] = nrgRight;
904       envNrgLeft += (nrgLeft >> envNrg_scale);
905       envNrgRight += (nrgRight >> envNrg_scale);
906     } /* j */
907 
908     for (j = 0; j < no_of_bands; j++) {
909       FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f);
910       FIXP_DBL nrgLeft = pNrgLeft[j];
911       FIXP_DBL nrgRight = pNrgRight[j];
912 
913       /* None missing harmonic Energy lowering compensation */
914       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         nrgLeft =
918             nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands);
919         if (stereoMode == SBR_COUPLING) {
920           nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale,
921                                        no_of_bands);
922         }
923       }
924 
925       if (stereoMode == SBR_COUPLING) {
926         /* calc operation later with log */
927         nrgLeft2 = nrgLeft;
928         nrgLeft = (nrgRight + nrgLeft) >> 1;
929       }
930 
931       /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */
932       /* If nrgLeft == 0 then the Log calculations below do fail. */
933       if (nrgLeft > FL2FXCONST_DBL(0.0f)) {
934         FIXP_DBL tmp0, tmp1, tmp2, tmp3;
935         INT tmpScale;
936 
937         tmpScale = CountLeadingBits(nrgLeft);
938         nrgLeft = nrgLeft << tmpScale;
939 
940         tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */
941         tmp1 = ((FIXP_DBL)(commonScale + tmpScale))
942                << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */
943         tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1);
944         tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */
945         tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >>
946                1; /* scaled by 1/64 */
947 
948         nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1);
949       } else {
950         nrgLeft = FL2FXCONST_DBL(-1.0f);
951       }
952 
953       /* ld64 to integer conversion */
954       nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)),
955                        (FL2FXCONST_DBL(0.5f) >> oneBitLess));
956       nrgLeft = (FIXP_DBL)(LONG)nrgLeft >>
957                 (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1);
958       sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */
959 
960       if (stereoMode == SBR_COUPLING) {
961         FIXP_DBL scaleFract;
962         int sc0, sc1;
963 
964         nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2);
965         nrgRight = fixMax((FIXP_DBL)0x1, nrgRight);
966 
967         sc0 = CountLeadingBits(nrgLeft2);
968         sc1 = CountLeadingBits(nrgRight);
969 
970         scaleFract =
971             ((FIXP_DBL)(sc0 - sc1))
972             << (DFRACT_BITS - 1 -
973                 LD_DATA_SHIFT); /* scale value in ld64 representation */
974         nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) -
975                    scaleFract;
976 
977         /* ld64 to integer conversion */
978         nrgRight = (FIXP_DBL)(LONG)(nrgRight) >>
979                    (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess);
980         nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */
981 
982         sfb_nrgRight[m] = mapPanorama(
983             nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError);
984 
985         *maxQuantError = fixMax(quantError, *maxQuantError);
986       }
987 
988       m++;
989     } /* 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     if (h_con->useParametricCoding) {
995       m -= no_of_bands;
996       for (j = 0; j < no_of_bands; j++) {
997         if (freq_res == FREQ_RES_HIGH &&
998             h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) {
999           sfb_nrgLeft[m] -=
1000               (ca *
1001                fixp_abs(
1002                    (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j]));
1003         }
1004         sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]);
1005         m++;
1006       }
1007     } /* useParametricCoding */
1008 
1009   } /* env loop */
1010 }
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
FDKsbrEnc_extractSbrEnvelope1(HANDLE_SBR_CONFIG_DATA h_con,HANDLE_SBR_HEADER_DATA sbrHeaderData,HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,HANDLE_ENV_CHANNEL hEnvChan,HANDLE_COMMON_DATA hCmonData,SBR_ENV_TEMP_DATA * eData,SBR_FRAME_TEMP_DATA * fData)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     SBR_FRAME_TEMP_DATA *fData) {
1034   HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
1035 
1036   if (sbrExtrEnv->YBufferSzShift == 0)
1037     FDKsbrEnc_getEnergyFromCplxQmfDataFull(
1038         &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
1039         sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
1040         sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
1041         sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]);
1042   else
1043     FDKsbrEnc_getEnergyFromCplxQmfData(
1044         &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset],
1045         sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset,
1046         sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands,
1047         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   FDKsbrEnc_CalculateTonalityQuotas(
1057       &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer,
1058       h_con->freqBandTable[HI][h_con->nSfb[HI]], hEnvChan->qmfScale);
1059 
1060   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1061     FIXP_DBL tonality = FDKsbrEnc_GetTonality(
1062         hEnvChan->TonCorr.quotaMatrix,
1063         hEnvChan->TonCorr.numberOfEstimatesPerFrame,
1064         hEnvChan->TonCorr.startIndexMatrix,
1065         sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset,
1066         h_con->freqBandTable[HI][0] + 1, h_con->noQmfBands,
1067         sbrExtrEnv->no_cols);
1068 
1069     hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0];
1070     hEnvChan->encEnvData.ton_HF[0] = tonality;
1071 
1072     /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */
1073     hEnvChan->encEnvData.global_tonality =
1074         (hEnvChan->encEnvData.ton_HF[0] >> 1) +
1075         (hEnvChan->encEnvData.ton_HF[1] >> 1);
1076   }
1077 
1078   /*
1079     Transient detection COEFF Transform OK
1080   */
1081 
1082   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1083     FDKsbrEnc_fastTransientDetect(&hEnvChan->sbrFastTransientDetector,
1084                                   sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
1085                                   sbrExtrEnv->YBufferWriteOffset,
1086                                   eData->transient_info);
1087 
1088   } else {
1089     FDKsbrEnc_transientDetect(
1090         &hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer,
1091         sbrExtrEnv->YBufferScale, eData->transient_info,
1092         sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift,
1093         sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot);
1094   }
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   FDKsbrEnc_frameSplitter(
1105       sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale,
1106       &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1],
1107       eData->transient_info, sbrExtrEnv->YBufferWriteOffset,
1108       sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step,
1109       sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality);
1110 }
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
FDKsbrEnc_extractSbrEnvelope2(HANDLE_SBR_CONFIG_DATA h_con,HANDLE_SBR_HEADER_DATA sbrHeaderData,HANDLE_PARAMETRIC_STEREO hParametricStereo,HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData,HANDLE_ENV_CHANNEL h_envChan0,HANDLE_ENV_CHANNEL h_envChan1,HANDLE_COMMON_DATA hCmonData,SBR_ENV_TEMP_DATA * eData,SBR_FRAME_TEMP_DATA * fData,int clearOutput)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     SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) {
1149   HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1};
1150   int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift;
1151 
1152   SBR_STEREO_MODE stereoMode = h_con->stereoMode;
1153   int nChannels = h_con->nChannels;
1154   const int *v_tuning;
1155   static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0};
1156 
1157   static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0};
1158 
1159   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
1160     v_tuning = v_tuningELD;
1161   else
1162     v_tuning = v_tuningHEAAC;
1163 
1164   /*
1165     Select stereo mode.
1166   */
1167   if (stereoMode == SBR_COUPLING) {
1168     if (eData[0].transient_info[1] && eData[1].transient_info[1]) {
1169       eData[0].transient_info[0] =
1170           fixMin(eData[1].transient_info[0], eData[0].transient_info[0]);
1171       eData[1].transient_info[0] = eData[0].transient_info[0];
1172     } else {
1173       if (eData[0].transient_info[1] && !eData[1].transient_info[1]) {
1174         eData[1].transient_info[0] = eData[0].transient_info[0];
1175       } else {
1176         if (!eData[0].transient_info[1] && eData[1].transient_info[1])
1177           eData[0].transient_info[0] = eData[1].transient_info[0];
1178         else {
1179           eData[0].transient_info[0] =
1180               fixMax(eData[1].transient_info[0], eData[0].transient_info[0]);
1181           eData[1].transient_info[0] = eData[0].transient_info[0];
1182         }
1183       }
1184     }
1185   }
1186 
1187   /*
1188     Determine time/frequency division of current granule
1189   */
1190   eData[0].frame_info = FDKsbrEnc_frameInfoGenerator(
1191       &h_envChan[0]->SbrEnvFrame, eData[0].transient_info,
1192       sbrBitstreamData->rightBorderFIX,
1193       h_envChan[0]->sbrExtractEnvelope.pre_transient_info,
1194       h_envChan[0]->encEnvData.ldGrid, v_tuning);
1195 
1196   h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
1197 
1198   /* AAC LD patch for transient prediction */
1199   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     h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv =
1203         h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
1204   }
1205 
1206   switch (stereoMode) {
1207     case SBR_LEFT_RIGHT:
1208     case SBR_SWITCH_LRC:
1209       eData[1].frame_info = FDKsbrEnc_frameInfoGenerator(
1210           &h_envChan[1]->SbrEnvFrame, eData[1].transient_info,
1211           sbrBitstreamData->rightBorderFIX,
1212           h_envChan[1]->sbrExtractEnvelope.pre_transient_info,
1213           h_envChan[1]->encEnvData.ldGrid, v_tuning);
1214 
1215       h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid;
1216 
1217       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         h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv =
1221             h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes;
1222       }
1223 
1224       /* compare left and right frame_infos */
1225       if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) {
1226         stereoMode = SBR_LEFT_RIGHT;
1227       } else {
1228         for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) {
1229           if (eData[0].frame_info->borders[i] !=
1230               eData[1].frame_info->borders[i]) {
1231             stereoMode = SBR_LEFT_RIGHT;
1232             break;
1233           }
1234         }
1235         for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) {
1236           if (eData[0].frame_info->freqRes[i] !=
1237               eData[1].frame_info->freqRes[i]) {
1238             stereoMode = SBR_LEFT_RIGHT;
1239             break;
1240           }
1241         }
1242         if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) {
1243           stereoMode = SBR_LEFT_RIGHT;
1244         }
1245       }
1246       break;
1247     case SBR_COUPLING:
1248       eData[1].frame_info = eData[0].frame_info;
1249       h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid;
1250       break;
1251     case SBR_MONO:
1252       /* nothing to do */
1253       break;
1254     default:
1255       FDK_ASSERT(0);
1256   }
1257 
1258   for (ch = 0; ch < nChannels; ch++) {
1259     HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch];
1260     HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope;
1261     SBR_ENV_TEMP_DATA *ed = &eData[ch];
1262 
1263     /*
1264        Send transient info to bitstream and store for next call
1265     */
1266     sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */
1267     sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */
1268     hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes =
1269         ed->frame_info->nEnvelopes; /* number of envelopes of current frame */
1270     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     if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
1277         (ed->nEnvelopes == 1)) {
1278       AMP_RES currentAmpResFF = SBR_AMP_RES_1_5;
1279       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         if (fIsLessThan(/* global_tonality > threshold ? */
1287                         h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
1288                         hEnvChan->encEnvData.global_tonality,
1289                         RELAXATION_SHIFT + 2)) {
1290           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
1291         } else {
1292           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
1293         }
1294         currentAmpResFF = hEnvChan->encEnvData.currentAmpResFF;
1295       }
1296 
1297       if (currentAmpResFF != hEnvChan->encEnvData.init_sbr_amp_res) {
1298         FDKsbrEnc_InitSbrHuffmanTables(
1299             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1300             &hEnvChan->sbrCodeNoiseFloor, currentAmpResFF);
1301       }
1302     } else {
1303       if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
1304         FDKsbrEnc_InitSbrHuffmanTables(
1305             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1306             &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res);
1307       }
1308     }
1309 
1310     if (!clearOutput) {
1311       /*
1312         Tonality correction parameter extraction (inverse filtering level, noise
1313         floor additional sines).
1314       */
1315       FDKsbrEnc_TonCorrParamExtr(
1316           &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec,
1317           ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag,
1318           hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation,
1319           ed->frame_info, ed->transient_info, h_con->freqBandTable[HI],
1320           h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode,
1321           h_con->sbrSyntaxFlags);
1322     }
1323 
1324     /* Low energy in low band fix */
1325     if (hEnvChan->sbrTransientDetector.prevLowBandEnergy <
1326             hEnvChan->sbrTransientDetector.prevHighBandEnergy &&
1327         hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
1328         /* The fix needs the non-fast transient detector running.
1329            It sets prevLowBandEnergy and prevHighBandEnergy.      */
1330         && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) {
1331       hEnvChan->fLevelProtect = 1;
1332 
1333       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1334         hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
1335     } else {
1336       hEnvChan->fLevelProtect = 0;
1337     }
1338 
1339     hEnvChan->encEnvData.sbr_invf_mode =
1340         hEnvChan->encEnvData.sbr_invf_mode_vec[0];
1341 
1342     hEnvChan->encEnvData.noOfnoisebands =
1343         hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
1344 
1345   } /* ch */
1346 
1347   /*
1348      Save number of scf bands per envelope
1349    */
1350   for (ch = 0; ch < nChannels; ch++) {
1351     for (i = 0; i < eData[ch].nEnvelopes; i++) {
1352       h_envChan[ch]->encEnvData.noScfBands[i] =
1353           (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH
1354                ? h_con->nSfb[FREQ_RES_HIGH]
1355                : h_con->nSfb[FREQ_RES_LOW]);
1356     }
1357   }
1358 
1359   if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY &&
1360       stereoMode == SBR_SWITCH_LRC &&
1361       h_envChan[0]->encEnvData.currentAmpResFF !=
1362           h_envChan[1]->encEnvData.currentAmpResFF) {
1363     stereoMode = SBR_LEFT_RIGHT;
1364   }
1365 
1366   /*
1367     Extract envelope of current frame.
1368   */
1369   switch (stereoMode) {
1370     case SBR_MONO:
1371       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1372                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1373                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1374                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1375       break;
1376     case SBR_LEFT_RIGHT:
1377       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1378                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1379                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1380                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1381       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1382                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1383                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1384                            h_envChan[1], SBR_MONO, NULL, YSzShift);
1385       break;
1386     case SBR_COUPLING:
1387       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1388                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
1389                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1390                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1391                            eData[0].frame_info, eData[0].sfb_nrg,
1392                            eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING,
1393                            &fData->maxQuantError, YSzShift);
1394       break;
1395     case SBR_SWITCH_LRC:
1396       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1397                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1398                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1399                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1400       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1401                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1402                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1403                            h_envChan[1], SBR_MONO, NULL, YSzShift);
1404       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1405                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
1406                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1407                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1408                            eData[0].frame_info, eData[0].sfb_nrg_coupling,
1409                            eData[1].sfb_nrg_coupling, h_con, h_envChan[0],
1410                            SBR_COUPLING, &fData->maxQuantError, YSzShift);
1411       break;
1412   }
1413 
1414   /*
1415     Noise floor quantisation and coding.
1416   */
1417 
1418   switch (stereoMode) {
1419     case SBR_MONO:
1420       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1421                                       0);
1422 
1423       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1424                              &h_envChan[0]->sbrCodeNoiseFloor,
1425                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1426                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1427                              sbrBitstreamData->HeaderActive);
1428 
1429       break;
1430     case SBR_LEFT_RIGHT:
1431       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1432                                       0);
1433 
1434       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1435                              &h_envChan[0]->sbrCodeNoiseFloor,
1436                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1437                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1438                              sbrBitstreamData->HeaderActive);
1439 
1440       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1441                                       0);
1442 
1443       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1444                              &h_envChan[1]->sbrCodeNoiseFloor,
1445                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
1446                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1447                              sbrBitstreamData->HeaderActive);
1448 
1449       break;
1450 
1451     case SBR_COUPLING:
1452       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1453 
1454       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1455                                       0);
1456 
1457       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1458                              &h_envChan[0]->sbrCodeNoiseFloor,
1459                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
1460                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1461                              sbrBitstreamData->HeaderActive);
1462 
1463       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1464                                       1);
1465 
1466       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1467                              &h_envChan[1]->sbrCodeNoiseFloor,
1468                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
1469                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1470                              sbrBitstreamData->HeaderActive);
1471 
1472       break;
1473     case SBR_SWITCH_LRC:
1474       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1475                                       0);
1476       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1477                                       0);
1478       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1479       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,
1480                                       eData[0].noiseFloor, 0);
1481       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,
1482                                       eData[1].noiseFloor, 1);
1483       break;
1484   }
1485 
1486   /*
1487     Encode envelope of current frame.
1488   */
1489   switch (stereoMode) {
1490     case SBR_MONO:
1491       sbrHeaderData->coupling = 0;
1492       h_envChan[0]->encEnvData.balance = 0;
1493       FDKsbrEnc_codeEnvelope(
1494           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1495           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1496           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1497           sbrBitstreamData->HeaderActive);
1498       break;
1499     case SBR_LEFT_RIGHT:
1500       sbrHeaderData->coupling = 0;
1501 
1502       h_envChan[0]->encEnvData.balance = 0;
1503       h_envChan[1]->encEnvData.balance = 0;
1504 
1505       FDKsbrEnc_codeEnvelope(
1506           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1507           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1508           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1509           sbrBitstreamData->HeaderActive);
1510       FDKsbrEnc_codeEnvelope(
1511           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1512           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1513           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0,
1514           sbrBitstreamData->HeaderActive);
1515       break;
1516     case SBR_COUPLING:
1517       sbrHeaderData->coupling = 1;
1518       h_envChan[0]->encEnvData.balance = 0;
1519       h_envChan[1]->encEnvData.balance = 1;
1520 
1521       FDKsbrEnc_codeEnvelope(
1522           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1523           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1524           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1525           sbrBitstreamData->HeaderActive);
1526       FDKsbrEnc_codeEnvelope(
1527           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1528           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1529           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1,
1530           sbrBitstreamData->HeaderActive);
1531       break;
1532     case SBR_SWITCH_LRC: {
1533       INT payloadbitsLR;
1534       INT payloadbitsCOUPLING;
1535 
1536       SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
1537       SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
1538       INT upDateNrgTemp[MAX_NUM_CHANNELS];
1539       INT upDateNoiseTemp[MAX_NUM_CHANNELS];
1540       INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1541       INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1542 
1543       INT tempFlagRight = 0;
1544       INT tempFlagLeft = 0;
1545 
1546       /*
1547          Store previous values, in order to be able to "undo" what is being
1548          done.
1549       */
1550 
1551       for (ch = 0; ch < nChannels; ch++) {
1552         FDKmemcpy(sfbNrgPrevTemp[ch],
1553                   h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1554                   MAX_FREQ_COEFFS * sizeof(SCHAR));
1555 
1556         FDKmemcpy(noisePrevTemp[ch],
1557                   h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1558                   MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1559 
1560         upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
1561         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         if (sbrHeaderData->prev_coupling) {
1568           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1569           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1570         }
1571       } /* ch */
1572 
1573       /*
1574          Code ordinary Left/Right stereo
1575       */
1576       FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1577                              &h_envChan[0]->sbrCodeEnvelope,
1578                              h_envChan[0]->encEnvData.domain_vec, 0,
1579                              eData[0].frame_info->nEnvelopes, 0,
1580                              sbrBitstreamData->HeaderActive);
1581       FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1582                              &h_envChan[1]->sbrCodeEnvelope,
1583                              h_envChan[1]->encEnvData.domain_vec, 0,
1584                              eData[1].frame_info->nEnvelopes, 0,
1585                              sbrBitstreamData->HeaderActive);
1586 
1587       c = 0;
1588       for (i = 0; i < eData[0].nEnvelopes; i++) {
1589         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1590           h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
1591           h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
1592           c++;
1593         }
1594       }
1595 
1596       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1597                              &h_envChan[0]->sbrCodeNoiseFloor,
1598                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1599                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1600                              sbrBitstreamData->HeaderActive);
1601 
1602       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1603         h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
1604 
1605       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1606                              &h_envChan[1]->sbrCodeNoiseFloor,
1607                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
1608                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1609                              sbrBitstreamData->HeaderActive);
1610 
1611       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1612         h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
1613 
1614       sbrHeaderData->coupling = 0;
1615       h_envChan[0]->encEnvData.balance = 0;
1616       h_envChan[1]->encEnvData.balance = 0;
1617 
1618       payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement(
1619           sbrHeaderData, hParametricStereo, sbrBitstreamData,
1620           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1621           h_con->sbrSyntaxFlags);
1622 
1623       /*
1624         swap saved stored with current values
1625       */
1626       for (ch = 0; ch < nChannels; ch++) {
1627         INT itmp;
1628         for (i = 0; i < MAX_FREQ_COEFFS; i++) {
1629           /*
1630             swap sfb energies
1631           */
1632           itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
1633           h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] =
1634               sfbNrgPrevTemp[ch][i];
1635           sfbNrgPrevTemp[ch][i] = itmp;
1636         }
1637         for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) {
1638           /*
1639             swap noise energies
1640           */
1641           itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
1642           h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] =
1643               noisePrevTemp[ch][i];
1644           noisePrevTemp[ch][i] = itmp;
1645         }
1646         /* swap update flags */
1647         itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
1648         h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1649         upDateNrgTemp[ch] = itmp;
1650 
1651         itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
1652         h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1653         upDateNoiseTemp[ch] = itmp;
1654 
1655         /*
1656             save domain vecs
1657         */
1658         FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec,
1659                   sizeof(INT) * MAX_ENVELOPES);
1660         FDKmemcpy(domainVecNoiseTemp[ch],
1661                   h_envChan[ch]->encEnvData.domain_vec_noise,
1662                   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         if (!sbrHeaderData->prev_coupling) {
1670           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1671           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1672         }
1673       } /* ch */
1674 
1675       /*
1676          Coupling
1677        */
1678 
1679       FDKsbrEnc_codeEnvelope(
1680           eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
1681           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1682           1, eData[0].frame_info->nEnvelopes, 0,
1683           sbrBitstreamData->HeaderActive);
1684 
1685       FDKsbrEnc_codeEnvelope(
1686           eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
1687           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1688           1, eData[1].frame_info->nEnvelopes, 1,
1689           sbrBitstreamData->HeaderActive);
1690 
1691       c = 0;
1692       for (i = 0; i < eData[0].nEnvelopes; i++) {
1693         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1694           h_envChan[0]->encEnvData.ienvelope[i][j] =
1695               eData[0].sfb_nrg_coupling[c];
1696           h_envChan[1]->encEnvData.ienvelope[i][j] =
1697               eData[1].sfb_nrg_coupling[c];
1698           c++;
1699         }
1700       }
1701 
1702       FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res,
1703                              &h_envChan[0]->sbrCodeNoiseFloor,
1704                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
1705                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1706                              sbrBitstreamData->HeaderActive);
1707 
1708       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1709         h_envChan[0]->encEnvData.sbr_noise_levels[i] =
1710             eData[0].noise_level_coupling[i];
1711 
1712       FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res,
1713                              &h_envChan[1]->sbrCodeNoiseFloor,
1714                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
1715                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1716                              sbrBitstreamData->HeaderActive);
1717 
1718       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1719         h_envChan[1]->encEnvData.sbr_noise_levels[i] =
1720             eData[1].noise_level_coupling[i];
1721 
1722       sbrHeaderData->coupling = 1;
1723 
1724       h_envChan[0]->encEnvData.balance = 0;
1725       h_envChan[1]->encEnvData.balance = 1;
1726 
1727       tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
1728       tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
1729 
1730       payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement(
1731           sbrHeaderData, hParametricStereo, sbrBitstreamData,
1732           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1733           h_con->sbrSyntaxFlags);
1734 
1735       h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
1736       h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
1737 
1738       if (payloadbitsCOUPLING < payloadbitsLR) {
1739         /*
1740           copy coded coupling envelope and noise data to l/r
1741         */
1742         for (ch = 0; ch < nChannels; ch++) {
1743           SBR_ENV_TEMP_DATA *ed = &eData[ch];
1744           FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling,
1745                     MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR));
1746           FDKmemcpy(ed->noise_level, ed->noise_level_coupling,
1747                     MAX_NUM_NOISE_VALUES * sizeof(SCHAR));
1748         }
1749 
1750         sbrHeaderData->coupling = 1;
1751         h_envChan[0]->encEnvData.balance = 0;
1752         h_envChan[1]->encEnvData.balance = 1;
1753       } else {
1754         /*
1755           restore saved l/r items
1756         */
1757         for (ch = 0; ch < nChannels; ch++) {
1758           FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1759                     sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR));
1760 
1761           h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1762 
1763           FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1764                     noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1765 
1766           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch],
1767                     sizeof(INT) * MAX_ENVELOPES);
1768           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise,
1769                     domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES);
1770 
1771           h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1772         }
1773 
1774         sbrHeaderData->coupling = 0;
1775         h_envChan[0]->encEnvData.balance = 0;
1776         h_envChan[1]->encEnvData.balance = 0;
1777       }
1778     } break;
1779   } /* 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   if (stereoMode == SBR_MONO) {
1784     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
1785       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1786     else
1787       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1788   } else {
1789     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
1790         h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
1791       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1792       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
1793     } else {
1794       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1795       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1796     }
1797   }
1798 
1799   /*
1800     Send the encoded data to the bitstream
1801   */
1802   for (ch = 0; ch < nChannels; ch++) {
1803     SBR_ENV_TEMP_DATA *ed = &eData[ch];
1804     c = 0;
1805     for (i = 0; i < ed->nEnvelopes; i++) {
1806       for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
1807         h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
1808 
1809         c++;
1810       }
1811     }
1812     for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
1813       h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
1814     }
1815   } /* ch */
1816 
1817   /*
1818     Write bitstream
1819   */
1820   if (nChannels == 2) {
1821     FDKsbrEnc_WriteEnvChannelPairElement(
1822         sbrHeaderData, hParametricStereo, sbrBitstreamData,
1823         &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1824         h_con->sbrSyntaxFlags);
1825   } else {
1826     FDKsbrEnc_WriteEnvSingleChannelElement(
1827         sbrHeaderData, hParametricStereo, sbrBitstreamData,
1828         &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags);
1829   }
1830 
1831   /*
1832    * Update buffers.
1833    */
1834   for (ch = 0; ch < nChannels; ch++) {
1835     int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >>
1836                         h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
1837     for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
1838       FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
1839                 h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
1840                 sizeof(FIXP_DBL) * 64);
1841     }
1842     h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] =
1843         h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
1844   }
1845 
1846   sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
1847 }
1848 
1849 /***************************************************************************/
1850 /*!
1851 
1852   \brief  creates an envelope extractor handle
1853 
1854   \return error status
1855 
1856 ****************************************************************************/
FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,INT channel,INT chInEl,UCHAR * dynamic_RAM)1857 INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
1858                                        INT channel, INT chInEl,
1859                                        UCHAR *dynamic_RAM) {
1860   INT i;
1861   FIXP_DBL *rBuffer, *iBuffer;
1862   INT n;
1863   FIXP_DBL *YBufferDyn;
1864 
1865   FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE));
1866 
1867   if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) {
1868     goto bail;
1869   }
1870 
1871   for (i = 0; i < (32 >> 1); i++) {
1872     hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64);
1873   }
1874   YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1875   for (n = 0; i < 32; i++, n++) {
1876     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1877   }
1878 
1879   rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
1880   iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
1881 
1882   for (i = 0; i < 32; i++) {
1883     hSbrCut->rBuffer[i] = rBuffer + (i * 64);
1884     hSbrCut->iBuffer[i] = iBuffer + (i * 64);
1885   }
1886 
1887   return 0;
1888 
1889 bail:
1890   FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut);
1891 
1892   return -1;
1893 }
1894 
1895 /***************************************************************************/
1896 /*!
1897 
1898   \brief  Initialize an envelope extractor instance.
1899 
1900   \return error status
1901 
1902 ****************************************************************************/
FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,int no_cols,int no_rows,int start_index,int time_slots,int time_step,int tran_off,ULONG statesInitFlag,int chInEl,UCHAR * dynamic_RAM,UINT sbrSyntaxFlags)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                                      UINT sbrSyntaxFlags) {
1909   int YBufferLength, rBufferLength;
1910   int i;
1911 
1912   if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1913     int off = TRANSIENT_OFFSET_LD;
1914     hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step;
1915   } else {
1916     hSbrCut->YBufferWriteOffset = tran_off * time_step;
1917   }
1918   hSbrCut->rBufferReadOffset = 0;
1919 
1920   YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
1921   rBufferLength = no_cols;
1922 
1923   hSbrCut->pre_transient_info[0] = 0;
1924   hSbrCut->pre_transient_info[1] = 0;
1925 
1926   hSbrCut->no_cols = no_cols;
1927   hSbrCut->no_rows = no_rows;
1928   hSbrCut->start_index = start_index;
1929 
1930   hSbrCut->time_slots = time_slots;
1931   hSbrCut->time_step = time_step;
1932 
1933   FDK_ASSERT(no_rows <= 64);
1934 
1935   /* Use half the Energy values if time step is 2 or greater */
1936   if (time_step >= 2)
1937     hSbrCut->YBufferSzShift = 1;
1938   else
1939     hSbrCut->YBufferSzShift = 0;
1940 
1941   YBufferLength >>= hSbrCut->YBufferSzShift;
1942   hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
1943 
1944   FDK_ASSERT(YBufferLength <= 32);
1945 
1946   FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1947   INT n = 0;
1948   for (i = (32 >> 1); i < 32; i++, n++) {
1949     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1950   }
1951 
1952   if (statesInitFlag) {
1953     for (i = 0; i < YBufferLength; i++) {
1954       FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL));
1955     }
1956   }
1957 
1958   for (i = 0; i < rBufferLength; i++) {
1959     FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL));
1960     FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL));
1961   }
1962 
1963   FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
1964 
1965   if (statesInitFlag) {
1966     hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1;
1967   }
1968 
1969   return (0);
1970 }
1971 
1972 /***************************************************************************/
1973 /*!
1974 
1975   \brief  deinitializes an envelope extractor handle
1976 
1977   \return void
1978 
1979 ****************************************************************************/
1980 
FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut)1981 void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) {
1982   if (hSbrCut) {
1983     FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
1984   }
1985 }
1986 
FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr)1987 INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) {
1988   return hSbr->no_rows *
1989          ((hSbr->YBufferWriteOffset) *
1990               2 /* mult 2 because nrg's are grouped half */
1991           - hSbr->rBufferReadOffset); /* in reference hold half spec and calc
1992                                          nrg's on overlapped spec */
1993 }
1994