1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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