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