Home | History | Annotate | Download | only in src
      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