• 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 "nf_est.h"
104 
105 #include "sbr_misc.h"
106 
107 #include "genericStds.h"
108 
109 /* smoothFilter[4]  = {0.05857864376269f, 0.2f, 0.34142135623731f, 0.4f}; */
110 static const FIXP_DBL smoothFilter[4] = {0x077f813d, 0x19999995, 0x2bb3b1f5,
111                                          0x33333335};
112 
113 /* static const INT smoothFilterLength = 4; */
114 
115 static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */
116 
117 #ifndef min
118 #define min(a, b) (a < b ? a : b)
119 #endif
120 
121 #ifndef max
122 #define max(a, b) (a > b ? a : b)
123 #endif
124 
125 #define NOISE_FLOOR_OFFSET_SCALING (4)
126 
127 /**************************************************************************/
128 /*!
129   \brief     The function applies smoothing to the noise levels.
130 
131 
132 
133   \return    none
134 
135 */
136 /**************************************************************************/
smoothingOfNoiseLevels(FIXP_DBL * NoiseLevels,INT nEnvelopes,INT noNoiseBands,FIXP_DBL prevNoiseLevels[NF_SMOOTHING_LENGTH][MAX_NUM_NOISE_VALUES],const FIXP_DBL * pSmoothFilter,INT transientFlag)137 static void smoothingOfNoiseLevels(
138     FIXP_DBL *NoiseLevels, /*!< pointer to noise-floor levels.*/
139     INT nEnvelopes,        /*!< Number of noise floor envelopes.*/
140     INT noNoiseBands, /*!< Number of noise bands for every noise floor envelope.
141                        */
142     FIXP_DBL prevNoiseLevels[NF_SMOOTHING_LENGTH]
143                             [MAX_NUM_NOISE_VALUES], /*!< Previous noise floor
144                                                        envelopes. */
145     const FIXP_DBL *
146         pSmoothFilter, /*!< filter used for smoothing the noise floor levels. */
147     INT transientFlag) /*!< flag indicating if a transient is present*/
148 
149 {
150   INT i, band, env;
151   FIXP_DBL accu;
152 
153   for (env = 0; env < nEnvelopes; env++) {
154     if (transientFlag) {
155       for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
156         FDKmemcpy(prevNoiseLevels[i], NoiseLevels + env * noNoiseBands,
157                   noNoiseBands * sizeof(FIXP_DBL));
158       }
159     } else {
160       for (i = 1; i < NF_SMOOTHING_LENGTH; i++) {
161         FDKmemcpy(prevNoiseLevels[i - 1], prevNoiseLevels[i],
162                   noNoiseBands * sizeof(FIXP_DBL));
163       }
164       FDKmemcpy(prevNoiseLevels[NF_SMOOTHING_LENGTH - 1],
165                 NoiseLevels + env * noNoiseBands,
166                 noNoiseBands * sizeof(FIXP_DBL));
167     }
168 
169     for (band = 0; band < noNoiseBands; band++) {
170       accu = FL2FXCONST_DBL(0.0f);
171       for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
172         accu += fMultDiv2(pSmoothFilter[i], prevNoiseLevels[i][band]);
173       }
174       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
175       NoiseLevels[band + env * noNoiseBands] = accu << 1;
176     }
177   }
178 }
179 
180 /**************************************************************************/
181 /*!
182   \brief     Does the noise floor level estiamtion.
183 
184   The noiseLevel samples are scaled by the factor 0.25
185 
186   \return    none
187 
188 */
189 /**************************************************************************/
qmfBasedNoiseFloorDetection(FIXP_DBL * noiseLevel,FIXP_DBL ** quotaMatrixOrig,SCHAR * indexVector,INT startIndex,INT stopIndex,INT startChannel,INT stopChannel,FIXP_DBL ana_max_level,FIXP_DBL noiseFloorOffset,INT missingHarmonicFlag,FIXP_DBL weightFac,INVF_MODE diffThres,INVF_MODE inverseFilteringLevel)190 static void qmfBasedNoiseFloorDetection(
191     FIXP_DBL *noiseLevel,            /*!< Pointer to vector to
192                                         store the noise levels
193                                         in.*/
194     FIXP_DBL **quotaMatrixOrig,      /*!< Matrix holding the quota
195                                         values of the original. */
196     SCHAR *indexVector,              /*!< Index vector to obtain the
197                                         patched data. */
198     INT startIndex,                  /*!< Start index. */
199     INT stopIndex,                   /*!< Stop index. */
200     INT startChannel,                /*!< Start channel of the current
201                                         noise floor band.*/
202     INT stopChannel,                 /*!< Stop channel of the current
203                                         noise floor band. */
204     FIXP_DBL ana_max_level,          /*!< Maximum level of the
205                                         adaptive noise.*/
206     FIXP_DBL noiseFloorOffset,       /*!< Noise floor offset. */
207     INT missingHarmonicFlag,         /*!< Flag indicating if a
208                                         strong tonal component
209                                         is missing.*/
210     FIXP_DBL weightFac,              /*!< Weightening factor for the
211                                         difference between orig and sbr.
212                                       */
213     INVF_MODE diffThres,             /*!< Threshold value to control the
214                                         inverse filtering decision.*/
215     INVF_MODE inverseFilteringLevel) /*!< Inverse filtering
216                                         level of the current
217                                         band.*/
218 {
219   INT scale, l, k;
220   FIXP_DBL meanOrig = FL2FXCONST_DBL(0.0f), meanSbr = FL2FXCONST_DBL(0.0f),
221            diff;
222   FIXP_DBL invIndex = GetInvInt(stopIndex - startIndex);
223   FIXP_DBL invChannel = GetInvInt(stopChannel - startChannel);
224   FIXP_DBL accu;
225 
226   /*
227   Calculate the mean value, over the current time segment, for the original, the
228   HFR and the difference, over all channels in the current frequency range.
229   */
230 
231   if (missingHarmonicFlag == 1) {
232     for (l = startChannel; l < stopChannel; l++) {
233       /* tonalityOrig */
234       accu = FL2FXCONST_DBL(0.0f);
235       for (k = startIndex; k < stopIndex; k++) {
236         accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
237       }
238       meanOrig = fixMax(meanOrig, (accu << 1));
239 
240       /* tonalitySbr */
241       accu = FL2FXCONST_DBL(0.0f);
242       for (k = startIndex; k < stopIndex; k++) {
243         accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
244       }
245       meanSbr = fixMax(meanSbr, (accu << 1));
246     }
247   } else {
248     for (l = startChannel; l < stopChannel; l++) {
249       /* tonalityOrig */
250       accu = FL2FXCONST_DBL(0.0f);
251       for (k = startIndex; k < stopIndex; k++) {
252         accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
253       }
254       meanOrig += fMult((accu << 1), invChannel);
255 
256       /* tonalitySbr */
257       accu = FL2FXCONST_DBL(0.0f);
258       for (k = startIndex; k < stopIndex; k++) {
259         accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
260       }
261       meanSbr += fMult((accu << 1), invChannel);
262     }
263   }
264 
265   /* Small fix to avoid noise during silent passages.*/
266   if (meanOrig <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT) &&
267       meanSbr <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT)) {
268     meanOrig = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
269     meanSbr = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
270   }
271 
272   meanOrig = fixMax(meanOrig, RELAXATION);
273   meanSbr = fixMax(meanSbr, RELAXATION);
274 
275   if (missingHarmonicFlag == 1 || inverseFilteringLevel == INVF_MID_LEVEL ||
276       inverseFilteringLevel == INVF_LOW_LEVEL ||
277       inverseFilteringLevel == INVF_OFF || inverseFilteringLevel <= diffThres) {
278     diff = RELAXATION;
279   } else {
280     accu = fDivNorm(meanSbr, meanOrig, &scale);
281 
282     diff = fixMax(RELAXATION, fMult(RELAXATION_FRACT, fMult(weightFac, accu)) >>
283                                   (RELAXATION_SHIFT - scale));
284   }
285 
286   /*
287    * noise Level is now a positive value, i.e.
288    * the more harmonic the signal is the higher noise level,
289    * this makes no sense so we change the sign.
290    *********************************************************/
291   accu = fDivNorm(diff, meanOrig, &scale);
292   scale -= 2;
293 
294   if ((scale > 0) && (accu > ((FIXP_DBL)MAXVAL_DBL) >> scale)) {
295     *noiseLevel = (FIXP_DBL)MAXVAL_DBL;
296   } else {
297     *noiseLevel = scaleValue(accu, scale);
298   }
299 
300   /*
301    * Add a noise floor offset to compensate for bias in the detector
302    *****************************************************************/
303   if (!missingHarmonicFlag) {
304     *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset),
305                          (FIXP_DBL)MAXVAL_DBL >> NOISE_FLOOR_OFFSET_SCALING)
306                   << NOISE_FLOOR_OFFSET_SCALING;
307   }
308 
309   /*
310    * check to see that we don't exceed the maximum allowed level
311    **************************************************************/
312   *noiseLevel =
313       fixMin(*noiseLevel,
314              ana_max_level); /* ana_max_level is scaled with factor 0.25 */
315 }
316 
317 /**************************************************************************/
318 /*!
319   \brief     Does the noise floor level estiamtion.
320   The function calls the Noisefloor estimation function
321   for the time segments decided based upon the transient
322   information. The block is always divided into one or two segments.
323 
324 
325   \return    none
326 
327 */
328 /**************************************************************************/
FDKsbrEnc_sbrNoiseFloorEstimateQmf(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate,const SBR_FRAME_INFO * frame_info,FIXP_DBL * noiseLevels,FIXP_DBL ** quotaMatrixOrig,SCHAR * indexVector,INT missingHarmonicsFlag,INT startIndex,UINT numberOfEstimatesPerFrame,int transientFrame,INVF_MODE * pInvFiltLevels,UINT sbrSyntaxFlags)329 void FDKsbrEnc_sbrNoiseFloorEstimateQmf(
330     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
331         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
332                                   */
333     const SBR_FRAME_INFO
334         *frame_info, /*!< Time frequency grid of the current frame. */
335     FIXP_DBL
336         *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/
337     FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the
338                                    original. */
339     SCHAR *indexVector,         /*!< Index vector to obtain the patched data. */
340     INT missingHarmonicsFlag,   /*!< Flag indicating if a strong tonal component
341                                    will be missing. */
342     INT startIndex,             /*!< Start index. */
343     UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per
344                                        frame. */
345     int transientFrame, /*!< A flag indicating if a transient is present. */
346     INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse
347                                   filtering levels. */
348     UINT sbrSyntaxFlags)
349 
350 {
351   INT nNoiseEnvelopes, startPos[2], stopPos[2], env, band;
352 
353   INT noNoiseBands = h_sbrNoiseFloorEstimate->noNoiseBands;
354   INT *freqBandTable = h_sbrNoiseFloorEstimate->freqBandTableQmf;
355 
356   nNoiseEnvelopes = frame_info->nNoiseEnvelopes;
357 
358   startPos[0] = startIndex;
359 
360   if (nNoiseEnvelopes == 1) {
361     stopPos[0] = startIndex + min(numberOfEstimatesPerFrame, 2);
362   } else {
363     stopPos[0] = startIndex + 1;
364     startPos[1] = startIndex + 1;
365     stopPos[1] = startIndex + min(numberOfEstimatesPerFrame, 2);
366   }
367 
368   /*
369    * Estimate the noise floor.
370    **************************************/
371   for (env = 0; env < nNoiseEnvelopes; env++) {
372     for (band = 0; band < noNoiseBands; band++) {
373       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
374       qmfBasedNoiseFloorDetection(
375           &noiseLevels[band + env * noNoiseBands], quotaMatrixOrig, indexVector,
376           startPos[env], stopPos[env], freqBandTable[band],
377           freqBandTable[band + 1], h_sbrNoiseFloorEstimate->ana_max_level,
378           h_sbrNoiseFloorEstimate->noiseFloorOffset[band], missingHarmonicsFlag,
379           h_sbrNoiseFloorEstimate->weightFac,
380           h_sbrNoiseFloorEstimate->diffThres, pInvFiltLevels[band]);
381     }
382   }
383 
384   /*
385    * Smoothing of the values.
386    **************************/
387   smoothingOfNoiseLevels(noiseLevels, nNoiseEnvelopes,
388                          h_sbrNoiseFloorEstimate->noNoiseBands,
389                          h_sbrNoiseFloorEstimate->prevNoiseLevels,
390                          h_sbrNoiseFloorEstimate->smoothFilter, transientFrame);
391 
392   /* quantisation*/
393   for (env = 0; env < nNoiseEnvelopes; env++) {
394     for (band = 0; band < noNoiseBands; band++) {
395       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
396       noiseLevels[band + env * noNoiseBands] =
397           (FIXP_DBL)NOISE_FLOOR_OFFSET_64 -
398           (FIXP_DBL)CalcLdData(noiseLevels[band + env * noNoiseBands] +
399                                (FIXP_DBL)1) +
400           QuantOffset;
401     }
402   }
403 }
404 
405 /**************************************************************************/
406 /*!
407   \brief
408 
409 
410   \return    errorCode, noError if successful
411 
412 */
413 /**************************************************************************/
downSampleLoRes(INT * v_result,INT num_result,const UCHAR * freqBandTableRef,INT num_Ref)414 static INT downSampleLoRes(INT *v_result,                 /*!<    */
415                            INT num_result,                /*!<    */
416                            const UCHAR *freqBandTableRef, /*!<    */
417                            INT num_Ref)                   /*!<    */
418 {
419   INT step;
420   INT i, j;
421   INT org_length, result_length;
422   INT v_index[MAX_FREQ_COEFFS / 2];
423 
424   /* init */
425   org_length = num_Ref;
426   result_length = num_result;
427 
428   v_index[0] = 0; /* Always use left border */
429   i = 0;
430   while (org_length > 0) /* Create downsample vector */
431   {
432     i++;
433     step = org_length / result_length; /* floor; */
434     org_length = org_length - step;
435     result_length--;
436     v_index[i] = v_index[i - 1] + step;
437   }
438 
439   if (i != num_result) /* Should never happen */
440     return (1);        /* error downsampling */
441 
442   for (j = 0; j <= i;
443        j++) /* Use downsample vector to index LoResolution vector. */
444   {
445     v_result[j] = freqBandTableRef[v_index[j]];
446   }
447 
448   return (0);
449 }
450 
451 /**************************************************************************/
452 /*!
453   \brief    Initialize an instance of the noise floor level estimation module.
454 
455 
456   \return    errorCode, noError if successful
457 
458 */
459 /**************************************************************************/
FDKsbrEnc_InitSbrNoiseFloorEstimate(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate,INT ana_max_level,const UCHAR * freqBandTable,INT nSfb,INT noiseBands,INT noiseFloorOffset,INT timeSlots,UINT useSpeechConfig)460 INT FDKsbrEnc_InitSbrNoiseFloorEstimate(
461     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
462         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
463                                   */
464     INT ana_max_level,           /*!< Maximum level of the adaptive noise. */
465     const UCHAR *freqBandTable,  /*!< Frequency band table. */
466     INT nSfb,                    /*!< Number of frequency bands. */
467     INT noiseBands,              /*!< Number of noise bands per octave. */
468     INT noiseFloorOffset,        /*!< Noise floor offset. */
469     INT timeSlots,               /*!< Number of time slots in a frame. */
470     UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech
471                           */
472 ) {
473   INT i, qexp, qtmp;
474   FIXP_DBL tmp, exp;
475 
476   FDKmemclear(h_sbrNoiseFloorEstimate, sizeof(SBR_NOISE_FLOOR_ESTIMATE));
477 
478   h_sbrNoiseFloorEstimate->smoothFilter = smoothFilter;
479   if (useSpeechConfig) {
480     h_sbrNoiseFloorEstimate->weightFac = (FIXP_DBL)MAXVAL_DBL;
481     h_sbrNoiseFloorEstimate->diffThres = INVF_LOW_LEVEL;
482   } else {
483     h_sbrNoiseFloorEstimate->weightFac = FL2FXCONST_DBL(0.25f);
484     h_sbrNoiseFloorEstimate->diffThres = INVF_MID_LEVEL;
485   }
486 
487   h_sbrNoiseFloorEstimate->timeSlots = timeSlots;
488   h_sbrNoiseFloorEstimate->noiseBands = noiseBands;
489 
490   /* h_sbrNoiseFloorEstimate->ana_max_level is scaled by 0.25  */
491   switch (ana_max_level) {
492     case 6:
493       h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
494       break;
495     case 3:
496       h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.5);
497       break;
498     case -3:
499       h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.125);
500       break;
501     default:
502       /* Should not enter here */
503       h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
504       break;
505   }
506 
507   /*
508     calculate number of noise bands and allocate
509   */
510   if (FDKsbrEnc_resetSbrNoiseFloorEstimate(h_sbrNoiseFloorEstimate,
511                                            freqBandTable, nSfb))
512     return (1);
513 
514   if (noiseFloorOffset == 0) {
515     tmp = ((FIXP_DBL)MAXVAL_DBL) >> NOISE_FLOOR_OFFSET_SCALING;
516   } else {
517     /* noiseFloorOffset has to be smaller than 12, because
518        the result of the calculation below must be smaller than 1:
519        (2^(noiseFloorOffset/3))*2^4<1                                        */
520     FDK_ASSERT(noiseFloorOffset < 12);
521 
522     /* Assumes the noise floor offset in tuning table are in q31    */
523     /* Change the qformat here when non-zero values would be filled */
524     exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp);
525     tmp = fPow(2, DFRACT_BITS - 1, exp, qexp, &qtmp);
526     tmp = scaleValue(tmp, qtmp - NOISE_FLOOR_OFFSET_SCALING);
527   }
528 
529   for (i = 0; i < h_sbrNoiseFloorEstimate->noNoiseBands; i++) {
530     h_sbrNoiseFloorEstimate->noiseFloorOffset[i] = tmp;
531   }
532 
533   return (0);
534 }
535 
536 /**************************************************************************/
537 /*!
538   \brief     Resets the current instance of the noise floor estiamtion
539           module.
540 
541 
542   \return    errorCode, noError if successful
543 
544 */
545 /**************************************************************************/
FDKsbrEnc_resetSbrNoiseFloorEstimate(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate,const UCHAR * freqBandTable,INT nSfb)546 INT FDKsbrEnc_resetSbrNoiseFloorEstimate(
547     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
548         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
549                                   */
550     const UCHAR *freqBandTable,  /*!< Frequency band table. */
551     INT nSfb /*!< Number of bands in the frequency band table. */
552 ) {
553   INT k2, kx;
554 
555   /*
556    * Calculate number of noise bands
557    ***********************************/
558   k2 = freqBandTable[nSfb];
559   kx = freqBandTable[0];
560   if (h_sbrNoiseFloorEstimate->noiseBands == 0) {
561     h_sbrNoiseFloorEstimate->noNoiseBands = 1;
562   } else {
563     /*
564      * Calculate number of noise bands 1,2 or 3 bands/octave
565      ********************************************************/
566     FIXP_DBL tmp, ratio, lg2;
567     INT ratio_e, qlg2, nNoiseBands;
568 
569     ratio = fDivNorm(k2, kx, &ratio_e);
570     lg2 = fLog2(ratio, ratio_e, &qlg2);
571     tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands << 24), lg2);
572     tmp = scaleValue(tmp, qlg2 - 23);
573 
574     nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1);
575 
576     if (nNoiseBands > MAX_NUM_NOISE_COEFFS) {
577       nNoiseBands = MAX_NUM_NOISE_COEFFS;
578     }
579 
580     if (nNoiseBands == 0) {
581       nNoiseBands = 1;
582     }
583 
584     h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands;
585   }
586 
587   return (downSampleLoRes(h_sbrNoiseFloorEstimate->freqBandTableQmf,
588                           h_sbrNoiseFloorEstimate->noNoiseBands, freqBandTable,
589                           nSfb));
590 }
591 
592 /**************************************************************************/
593 /*!
594   \brief     Deletes the current instancce of the noise floor level
595   estimation module.
596 
597 
598   \return    none
599 
600 */
601 /**************************************************************************/
FDKsbrEnc_deleteSbrNoiseFloorEstimate(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate)602 void FDKsbrEnc_deleteSbrNoiseFloorEstimate(
603     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
604         h_sbrNoiseFloorEstimate) /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
605                                   */
606 {
607   if (h_sbrNoiseFloorEstimate) {
608     /*
609       nothing to do
610     */
611   }
612 }
613