• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 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 
1271     /*
1272       Check if the current frame is divided into one envelope only. If so, set
1273       the amplitude resolution to 1.5 dB, otherwise may set back to chosen value
1274     */
1275     if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) &&
1276         (ed->nEnvelopes == 1)) {
1277       if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1278         /* Note: global_tonaliy_float_value ==
1279            ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0)));
1280                  threshold_float_value ==
1281            ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0)));
1282          */
1283         /* decision of SBR_AMP_RES */
1284         if (fIsLessThan(/* global_tonality > threshold ? */
1285                         h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e,
1286                         hEnvChan->encEnvData.global_tonality,
1287                         RELAXATION_SHIFT + 2)) {
1288           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
1289         } else {
1290           hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0;
1291         }
1292       } else
1293         hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5;
1294 
1295       if (hEnvChan->encEnvData.currentAmpResFF !=
1296           hEnvChan->encEnvData.init_sbr_amp_res) {
1297         FDKsbrEnc_InitSbrHuffmanTables(
1298             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1299             &hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF);
1300       }
1301     } else {
1302       if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) {
1303         FDKsbrEnc_InitSbrHuffmanTables(
1304             &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope,
1305             &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res);
1306       }
1307     }
1308 
1309     if (!clearOutput) {
1310       /*
1311         Tonality correction parameter extraction (inverse filtering level, noise
1312         floor additional sines).
1313       */
1314       FDKsbrEnc_TonCorrParamExtr(
1315           &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec,
1316           ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag,
1317           hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation,
1318           ed->frame_info, ed->transient_info, h_con->freqBandTable[HI],
1319           h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode,
1320           h_con->sbrSyntaxFlags);
1321     }
1322 
1323     /* Low energy in low band fix */
1324     if (hEnvChan->sbrTransientDetector.prevLowBandEnergy <
1325             hEnvChan->sbrTransientDetector.prevHighBandEnergy &&
1326         hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03)
1327         /* The fix needs the non-fast transient detector running.
1328            It sets prevLowBandEnergy and prevHighBandEnergy.      */
1329         && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) {
1330       hEnvChan->fLevelProtect = 1;
1331 
1332       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1333         hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL;
1334     } else {
1335       hEnvChan->fLevelProtect = 0;
1336     }
1337 
1338     hEnvChan->encEnvData.sbr_invf_mode =
1339         hEnvChan->encEnvData.sbr_invf_mode_vec[0];
1340 
1341     hEnvChan->encEnvData.noOfnoisebands =
1342         hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands;
1343 
1344   } /* ch */
1345 
1346   /*
1347      Save number of scf bands per envelope
1348    */
1349   for (ch = 0; ch < nChannels; ch++) {
1350     for (i = 0; i < eData[ch].nEnvelopes; i++) {
1351       h_envChan[ch]->encEnvData.noScfBands[i] =
1352           (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH
1353                ? h_con->nSfb[FREQ_RES_HIGH]
1354                : h_con->nSfb[FREQ_RES_LOW]);
1355     }
1356   }
1357 
1358   /*
1359     Extract envelope of current frame.
1360   */
1361   switch (stereoMode) {
1362     case SBR_MONO:
1363       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1364                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1365                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1366                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1367       break;
1368     case SBR_LEFT_RIGHT:
1369       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1370                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1371                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1372                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1373       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1374                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1375                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1376                            h_envChan[1], SBR_MONO, NULL, YSzShift);
1377       break;
1378     case SBR_COUPLING:
1379       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1380                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
1381                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1382                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1383                            eData[0].frame_info, eData[0].sfb_nrg,
1384                            eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING,
1385                            &fData->maxQuantError, YSzShift);
1386       break;
1387     case SBR_SWITCH_LRC:
1388       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL,
1389                            h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL,
1390                            eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con,
1391                            h_envChan[0], SBR_MONO, NULL, YSzShift);
1392       calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL,
1393                            h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL,
1394                            eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con,
1395                            h_envChan[1], SBR_MONO, NULL, YSzShift);
1396       calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer,
1397                            h_envChan[1]->sbrExtractEnvelope.YBuffer,
1398                            h_envChan[0]->sbrExtractEnvelope.YBufferScale,
1399                            h_envChan[1]->sbrExtractEnvelope.YBufferScale,
1400                            eData[0].frame_info, eData[0].sfb_nrg_coupling,
1401                            eData[1].sfb_nrg_coupling, h_con, h_envChan[0],
1402                            SBR_COUPLING, &fData->maxQuantError, YSzShift);
1403       break;
1404   }
1405 
1406   /*
1407     Noise floor quantisation and coding.
1408   */
1409 
1410   switch (stereoMode) {
1411     case SBR_MONO:
1412       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1413                                       0);
1414 
1415       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1416                              &h_envChan[0]->sbrCodeNoiseFloor,
1417                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1418                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1419                              sbrBitstreamData->HeaderActive);
1420 
1421       break;
1422     case SBR_LEFT_RIGHT:
1423       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1424                                       0);
1425 
1426       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1427                              &h_envChan[0]->sbrCodeNoiseFloor,
1428                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1429                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1430                              sbrBitstreamData->HeaderActive);
1431 
1432       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1433                                       0);
1434 
1435       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1436                              &h_envChan[1]->sbrCodeNoiseFloor,
1437                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
1438                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1439                              sbrBitstreamData->HeaderActive);
1440 
1441       break;
1442 
1443     case SBR_COUPLING:
1444       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1445 
1446       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1447                                       0);
1448 
1449       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1450                              &h_envChan[0]->sbrCodeNoiseFloor,
1451                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
1452                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1453                              sbrBitstreamData->HeaderActive);
1454 
1455       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1456                                       1);
1457 
1458       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1459                              &h_envChan[1]->sbrCodeNoiseFloor,
1460                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
1461                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1462                              sbrBitstreamData->HeaderActive);
1463 
1464       break;
1465     case SBR_SWITCH_LRC:
1466       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor,
1467                                       0);
1468       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor,
1469                                       0);
1470       coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor);
1471       sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling,
1472                                       eData[0].noiseFloor, 0);
1473       sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling,
1474                                       eData[1].noiseFloor, 1);
1475       break;
1476   }
1477 
1478   /*
1479     Encode envelope of current frame.
1480   */
1481   switch (stereoMode) {
1482     case SBR_MONO:
1483       sbrHeaderData->coupling = 0;
1484       h_envChan[0]->encEnvData.balance = 0;
1485       FDKsbrEnc_codeEnvelope(
1486           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1487           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1488           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1489           sbrBitstreamData->HeaderActive);
1490       break;
1491     case SBR_LEFT_RIGHT:
1492       sbrHeaderData->coupling = 0;
1493 
1494       h_envChan[0]->encEnvData.balance = 0;
1495       h_envChan[1]->encEnvData.balance = 0;
1496 
1497       FDKsbrEnc_codeEnvelope(
1498           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1499           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1500           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1501           sbrBitstreamData->HeaderActive);
1502       FDKsbrEnc_codeEnvelope(
1503           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1504           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1505           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0,
1506           sbrBitstreamData->HeaderActive);
1507       break;
1508     case SBR_COUPLING:
1509       sbrHeaderData->coupling = 1;
1510       h_envChan[0]->encEnvData.balance = 0;
1511       h_envChan[1]->encEnvData.balance = 1;
1512 
1513       FDKsbrEnc_codeEnvelope(
1514           eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1515           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1516           sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0,
1517           sbrBitstreamData->HeaderActive);
1518       FDKsbrEnc_codeEnvelope(
1519           eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1520           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1521           sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1,
1522           sbrBitstreamData->HeaderActive);
1523       break;
1524     case SBR_SWITCH_LRC: {
1525       INT payloadbitsLR;
1526       INT payloadbitsCOUPLING;
1527 
1528       SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS];
1529       SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS];
1530       INT upDateNrgTemp[MAX_NUM_CHANNELS];
1531       INT upDateNoiseTemp[MAX_NUM_CHANNELS];
1532       INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1533       INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES];
1534 
1535       INT tempFlagRight = 0;
1536       INT tempFlagLeft = 0;
1537 
1538       /*
1539          Store previous values, in order to be able to "undo" what is being
1540          done.
1541       */
1542 
1543       for (ch = 0; ch < nChannels; ch++) {
1544         FDKmemcpy(sfbNrgPrevTemp[ch],
1545                   h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1546                   MAX_FREQ_COEFFS * sizeof(SCHAR));
1547 
1548         FDKmemcpy(noisePrevTemp[ch],
1549                   h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1550                   MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1551 
1552         upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate;
1553         upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
1554 
1555         /*
1556           forbid time coding in the first envelope in case of a different
1557           previous stereomode
1558         */
1559         if (sbrHeaderData->prev_coupling) {
1560           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1561           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1562         }
1563       } /* ch */
1564 
1565       /*
1566          Code ordinary Left/Right stereo
1567       */
1568       FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes,
1569                              &h_envChan[0]->sbrCodeEnvelope,
1570                              h_envChan[0]->encEnvData.domain_vec, 0,
1571                              eData[0].frame_info->nEnvelopes, 0,
1572                              sbrBitstreamData->HeaderActive);
1573       FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes,
1574                              &h_envChan[1]->sbrCodeEnvelope,
1575                              h_envChan[1]->encEnvData.domain_vec, 0,
1576                              eData[1].frame_info->nEnvelopes, 0,
1577                              sbrBitstreamData->HeaderActive);
1578 
1579       c = 0;
1580       for (i = 0; i < eData[0].nEnvelopes; i++) {
1581         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1582           h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c];
1583           h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c];
1584           c++;
1585         }
1586       }
1587 
1588       FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res,
1589                              &h_envChan[0]->sbrCodeNoiseFloor,
1590                              h_envChan[0]->encEnvData.domain_vec_noise, 0,
1591                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1592                              sbrBitstreamData->HeaderActive);
1593 
1594       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1595         h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i];
1596 
1597       FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res,
1598                              &h_envChan[1]->sbrCodeNoiseFloor,
1599                              h_envChan[1]->encEnvData.domain_vec_noise, 0,
1600                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1601                              sbrBitstreamData->HeaderActive);
1602 
1603       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1604         h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i];
1605 
1606       sbrHeaderData->coupling = 0;
1607       h_envChan[0]->encEnvData.balance = 0;
1608       h_envChan[1]->encEnvData.balance = 0;
1609 
1610       payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement(
1611           sbrHeaderData, hParametricStereo, sbrBitstreamData,
1612           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1613           h_con->sbrSyntaxFlags);
1614 
1615       /*
1616         swap saved stored with current values
1617       */
1618       for (ch = 0; ch < nChannels; ch++) {
1619         INT itmp;
1620         for (i = 0; i < MAX_FREQ_COEFFS; i++) {
1621           /*
1622             swap sfb energies
1623           */
1624           itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i];
1625           h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] =
1626               sfbNrgPrevTemp[ch][i];
1627           sfbNrgPrevTemp[ch][i] = itmp;
1628         }
1629         for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) {
1630           /*
1631             swap noise energies
1632           */
1633           itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i];
1634           h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] =
1635               noisePrevTemp[ch][i];
1636           noisePrevTemp[ch][i] = itmp;
1637         }
1638         /* swap update flags */
1639         itmp = h_envChan[ch]->sbrCodeEnvelope.upDate;
1640         h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1641         upDateNrgTemp[ch] = itmp;
1642 
1643         itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate;
1644         h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1645         upDateNoiseTemp[ch] = itmp;
1646 
1647         /*
1648             save domain vecs
1649         */
1650         FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec,
1651                   sizeof(INT) * MAX_ENVELOPES);
1652         FDKmemcpy(domainVecNoiseTemp[ch],
1653                   h_envChan[ch]->encEnvData.domain_vec_noise,
1654                   sizeof(INT) * MAX_ENVELOPES);
1655 
1656         /*
1657           forbid time coding in the first envelope in case of a different
1658           previous stereomode
1659         */
1660 
1661         if (!sbrHeaderData->prev_coupling) {
1662           h_envChan[ch]->sbrCodeEnvelope.upDate = 0;
1663           h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0;
1664         }
1665       } /* ch */
1666 
1667       /*
1668          Coupling
1669        */
1670 
1671       FDKsbrEnc_codeEnvelope(
1672           eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes,
1673           &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec,
1674           1, eData[0].frame_info->nEnvelopes, 0,
1675           sbrBitstreamData->HeaderActive);
1676 
1677       FDKsbrEnc_codeEnvelope(
1678           eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes,
1679           &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec,
1680           1, eData[1].frame_info->nEnvelopes, 1,
1681           sbrBitstreamData->HeaderActive);
1682 
1683       c = 0;
1684       for (i = 0; i < eData[0].nEnvelopes; i++) {
1685         for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) {
1686           h_envChan[0]->encEnvData.ienvelope[i][j] =
1687               eData[0].sfb_nrg_coupling[c];
1688           h_envChan[1]->encEnvData.ienvelope[i][j] =
1689               eData[1].sfb_nrg_coupling[c];
1690           c++;
1691         }
1692       }
1693 
1694       FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res,
1695                              &h_envChan[0]->sbrCodeNoiseFloor,
1696                              h_envChan[0]->encEnvData.domain_vec_noise, 1,
1697                              (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0,
1698                              sbrBitstreamData->HeaderActive);
1699 
1700       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1701         h_envChan[0]->encEnvData.sbr_noise_levels[i] =
1702             eData[0].noise_level_coupling[i];
1703 
1704       FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res,
1705                              &h_envChan[1]->sbrCodeNoiseFloor,
1706                              h_envChan[1]->encEnvData.domain_vec_noise, 1,
1707                              (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1,
1708                              sbrBitstreamData->HeaderActive);
1709 
1710       for (i = 0; i < MAX_NUM_NOISE_VALUES; i++)
1711         h_envChan[1]->encEnvData.sbr_noise_levels[i] =
1712             eData[1].noise_level_coupling[i];
1713 
1714       sbrHeaderData->coupling = 1;
1715 
1716       h_envChan[0]->encEnvData.balance = 0;
1717       h_envChan[1]->encEnvData.balance = 1;
1718 
1719       tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag;
1720       tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag;
1721 
1722       payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement(
1723           sbrHeaderData, hParametricStereo, sbrBitstreamData,
1724           &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1725           h_con->sbrSyntaxFlags);
1726 
1727       h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft;
1728       h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight;
1729 
1730       if (payloadbitsCOUPLING < payloadbitsLR) {
1731         /*
1732           copy coded coupling envelope and noise data to l/r
1733         */
1734         for (ch = 0; ch < nChannels; ch++) {
1735           SBR_ENV_TEMP_DATA *ed = &eData[ch];
1736           FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling,
1737                     MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR));
1738           FDKmemcpy(ed->noise_level, ed->noise_level_coupling,
1739                     MAX_NUM_NOISE_VALUES * sizeof(SCHAR));
1740         }
1741 
1742         sbrHeaderData->coupling = 1;
1743         h_envChan[0]->encEnvData.balance = 0;
1744         h_envChan[1]->encEnvData.balance = 1;
1745       } else {
1746         /*
1747           restore saved l/r items
1748         */
1749         for (ch = 0; ch < nChannels; ch++) {
1750           FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev,
1751                     sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR));
1752 
1753           h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch];
1754 
1755           FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev,
1756                     noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR));
1757 
1758           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch],
1759                     sizeof(INT) * MAX_ENVELOPES);
1760           FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise,
1761                     domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES);
1762 
1763           h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch];
1764         }
1765 
1766         sbrHeaderData->coupling = 0;
1767         h_envChan[0]->encEnvData.balance = 0;
1768         h_envChan[1]->encEnvData.balance = 0;
1769       }
1770     } break;
1771   } /* switch */
1772 
1773   /* tell the envelope encoders how long it has been, since we last sent
1774      a frame starting with a dF-coded envelope */
1775   if (stereoMode == SBR_MONO) {
1776     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME)
1777       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1778     else
1779       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1780   } else {
1781     if (h_envChan[0]->encEnvData.domain_vec[0] == TIME ||
1782         h_envChan[1]->encEnvData.domain_vec[0] == TIME) {
1783       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++;
1784       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++;
1785     } else {
1786       h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1787       h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0;
1788     }
1789   }
1790 
1791   /*
1792     Send the encoded data to the bitstream
1793   */
1794   for (ch = 0; ch < nChannels; ch++) {
1795     SBR_ENV_TEMP_DATA *ed = &eData[ch];
1796     c = 0;
1797     for (i = 0; i < ed->nEnvelopes; i++) {
1798       for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) {
1799         h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c];
1800 
1801         c++;
1802       }
1803     }
1804     for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) {
1805       h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i];
1806     }
1807   } /* ch */
1808 
1809   /*
1810     Write bitstream
1811   */
1812   if (nChannels == 2) {
1813     FDKsbrEnc_WriteEnvChannelPairElement(
1814         sbrHeaderData, hParametricStereo, sbrBitstreamData,
1815         &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData,
1816         h_con->sbrSyntaxFlags);
1817   } else {
1818     FDKsbrEnc_WriteEnvSingleChannelElement(
1819         sbrHeaderData, hParametricStereo, sbrBitstreamData,
1820         &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags);
1821   }
1822 
1823   /*
1824    * Update buffers.
1825    */
1826   for (ch = 0; ch < nChannels; ch++) {
1827     int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >>
1828                         h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift;
1829     for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) {
1830       FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i],
1831                 h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength],
1832                 sizeof(FIXP_DBL) * 64);
1833     }
1834     h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] =
1835         h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1];
1836   }
1837 
1838   sbrHeaderData->prev_coupling = sbrHeaderData->coupling;
1839 }
1840 
1841 /***************************************************************************/
1842 /*!
1843 
1844   \brief  creates an envelope extractor handle
1845 
1846   \return error status
1847 
1848 ****************************************************************************/
FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,INT channel,INT chInEl,UCHAR * dynamic_RAM)1849 INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
1850                                        INT channel, INT chInEl,
1851                                        UCHAR *dynamic_RAM) {
1852   INT i;
1853   FIXP_DBL *rBuffer, *iBuffer;
1854   INT n;
1855   FIXP_DBL *YBufferDyn;
1856 
1857   FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE));
1858 
1859   if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) {
1860     goto bail;
1861   }
1862 
1863   for (i = 0; i < (32 >> 1); i++) {
1864     hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64);
1865   }
1866   YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1867   for (n = 0; i < 32; i++, n++) {
1868     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1869   }
1870 
1871   rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM);
1872   iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM);
1873 
1874   for (i = 0; i < 32; i++) {
1875     hSbrCut->rBuffer[i] = rBuffer + (i * 64);
1876     hSbrCut->iBuffer[i] = iBuffer + (i * 64);
1877   }
1878 
1879   return 0;
1880 
1881 bail:
1882   FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut);
1883 
1884   return -1;
1885 }
1886 
1887 /***************************************************************************/
1888 /*!
1889 
1890   \brief  Initialize an envelope extractor instance.
1891 
1892   \return error status
1893 
1894 ****************************************************************************/
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)1895 INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut,
1896                                      int no_cols, int no_rows, int start_index,
1897                                      int time_slots, int time_step,
1898                                      int tran_off, ULONG statesInitFlag,
1899                                      int chInEl, UCHAR *dynamic_RAM,
1900                                      UINT sbrSyntaxFlags) {
1901   int YBufferLength, rBufferLength;
1902   int i;
1903 
1904   if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1905     int off = TRANSIENT_OFFSET_LD;
1906     hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step;
1907   } else {
1908     hSbrCut->YBufferWriteOffset = tran_off * time_step;
1909   }
1910   hSbrCut->rBufferReadOffset = 0;
1911 
1912   YBufferLength = hSbrCut->YBufferWriteOffset + no_cols;
1913   rBufferLength = no_cols;
1914 
1915   hSbrCut->pre_transient_info[0] = 0;
1916   hSbrCut->pre_transient_info[1] = 0;
1917 
1918   hSbrCut->no_cols = no_cols;
1919   hSbrCut->no_rows = no_rows;
1920   hSbrCut->start_index = start_index;
1921 
1922   hSbrCut->time_slots = time_slots;
1923   hSbrCut->time_step = time_step;
1924 
1925   FDK_ASSERT(no_rows <= 64);
1926 
1927   /* Use half the Energy values if time step is 2 or greater */
1928   if (time_step >= 2)
1929     hSbrCut->YBufferSzShift = 1;
1930   else
1931     hSbrCut->YBufferSzShift = 0;
1932 
1933   YBufferLength >>= hSbrCut->YBufferSzShift;
1934   hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift;
1935 
1936   FDK_ASSERT(YBufferLength <= 32);
1937 
1938   FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM);
1939   INT n = 0;
1940   for (i = (32 >> 1); i < 32; i++, n++) {
1941     hSbrCut->YBuffer[i] = YBufferDyn + (n * 64);
1942   }
1943 
1944   if (statesInitFlag) {
1945     for (i = 0; i < YBufferLength; i++) {
1946       FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL));
1947     }
1948   }
1949 
1950   for (i = 0; i < rBufferLength; i++) {
1951     FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL));
1952     FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL));
1953   }
1954 
1955   FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
1956 
1957   if (statesInitFlag) {
1958     hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1;
1959   }
1960 
1961   return (0);
1962 }
1963 
1964 /***************************************************************************/
1965 /*!
1966 
1967   \brief  deinitializes an envelope extractor handle
1968 
1969   \return void
1970 
1971 ****************************************************************************/
1972 
FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut)1973 void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) {
1974   if (hSbrCut) {
1975     FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer);
1976   }
1977 }
1978 
FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr)1979 INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) {
1980   return hSbr->no_rows *
1981          ((hSbr->YBufferWriteOffset) *
1982               2 /* mult 2 because nrg's are grouped half */
1983           - hSbr->rBufferReadOffset); /* in reference hold half spec and calc
1984                                          nrg's on overlapped spec */
1985 }
1986