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