xref: /aosp_15_r20/external/aac/libSBRenc/src/nf_est.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** SBR encoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description:
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "nf_est.h"
104*e5436536SAndroid Build Coastguard Worker 
105*e5436536SAndroid Build Coastguard Worker #include "sbr_misc.h"
106*e5436536SAndroid Build Coastguard Worker 
107*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
108*e5436536SAndroid Build Coastguard Worker 
109*e5436536SAndroid Build Coastguard Worker /* smoothFilter[4]  = {0.05857864376269f, 0.2f, 0.34142135623731f, 0.4f}; */
110*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL smoothFilter[4] = {0x077f813d, 0x19999995, 0x2bb3b1f5,
111*e5436536SAndroid Build Coastguard Worker                                          0x33333335};
112*e5436536SAndroid Build Coastguard Worker 
113*e5436536SAndroid Build Coastguard Worker /* static const INT smoothFilterLength = 4; */
114*e5436536SAndroid Build Coastguard Worker 
115*e5436536SAndroid Build Coastguard Worker static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker #ifndef min
118*e5436536SAndroid Build Coastguard Worker #define min(a, b) (a < b ? a : b)
119*e5436536SAndroid Build Coastguard Worker #endif
120*e5436536SAndroid Build Coastguard Worker 
121*e5436536SAndroid Build Coastguard Worker #ifndef max
122*e5436536SAndroid Build Coastguard Worker #define max(a, b) (a > b ? a : b)
123*e5436536SAndroid Build Coastguard Worker #endif
124*e5436536SAndroid Build Coastguard Worker 
125*e5436536SAndroid Build Coastguard Worker #define NOISE_FLOOR_OFFSET_SCALING (4)
126*e5436536SAndroid Build Coastguard Worker 
127*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
128*e5436536SAndroid Build Coastguard Worker /*!
129*e5436536SAndroid Build Coastguard Worker   \brief     The function applies smoothing to the noise levels.
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker 
132*e5436536SAndroid Build Coastguard Worker 
133*e5436536SAndroid Build Coastguard Worker   \return    none
134*e5436536SAndroid Build Coastguard Worker 
135*e5436536SAndroid Build Coastguard Worker */
136*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
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*e5436536SAndroid Build Coastguard Worker static void smoothingOfNoiseLevels(
138*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *NoiseLevels, /*!< pointer to noise-floor levels.*/
139*e5436536SAndroid Build Coastguard Worker     INT nEnvelopes,        /*!< Number of noise floor envelopes.*/
140*e5436536SAndroid Build Coastguard Worker     INT noNoiseBands, /*!< Number of noise bands for every noise floor envelope.
141*e5436536SAndroid Build Coastguard Worker                        */
142*e5436536SAndroid Build Coastguard Worker     FIXP_DBL prevNoiseLevels[NF_SMOOTHING_LENGTH]
143*e5436536SAndroid Build Coastguard Worker                             [MAX_NUM_NOISE_VALUES], /*!< Previous noise floor
144*e5436536SAndroid Build Coastguard Worker                                                        envelopes. */
145*e5436536SAndroid Build Coastguard Worker     const FIXP_DBL *
146*e5436536SAndroid Build Coastguard Worker         pSmoothFilter, /*!< filter used for smoothing the noise floor levels. */
147*e5436536SAndroid Build Coastguard Worker     INT transientFlag) /*!< flag indicating if a transient is present*/
148*e5436536SAndroid Build Coastguard Worker 
149*e5436536SAndroid Build Coastguard Worker {
150*e5436536SAndroid Build Coastguard Worker   INT i, band, env;
151*e5436536SAndroid Build Coastguard Worker   FIXP_DBL accu;
152*e5436536SAndroid Build Coastguard Worker 
153*e5436536SAndroid Build Coastguard Worker   for (env = 0; env < nEnvelopes; env++) {
154*e5436536SAndroid Build Coastguard Worker     if (transientFlag) {
155*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
156*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(prevNoiseLevels[i], NoiseLevels + env * noNoiseBands,
157*e5436536SAndroid Build Coastguard Worker                   noNoiseBands * sizeof(FIXP_DBL));
158*e5436536SAndroid Build Coastguard Worker       }
159*e5436536SAndroid Build Coastguard Worker     } else {
160*e5436536SAndroid Build Coastguard Worker       for (i = 1; i < NF_SMOOTHING_LENGTH; i++) {
161*e5436536SAndroid Build Coastguard Worker         FDKmemcpy(prevNoiseLevels[i - 1], prevNoiseLevels[i],
162*e5436536SAndroid Build Coastguard Worker                   noNoiseBands * sizeof(FIXP_DBL));
163*e5436536SAndroid Build Coastguard Worker       }
164*e5436536SAndroid Build Coastguard Worker       FDKmemcpy(prevNoiseLevels[NF_SMOOTHING_LENGTH - 1],
165*e5436536SAndroid Build Coastguard Worker                 NoiseLevels + env * noNoiseBands,
166*e5436536SAndroid Build Coastguard Worker                 noNoiseBands * sizeof(FIXP_DBL));
167*e5436536SAndroid Build Coastguard Worker     }
168*e5436536SAndroid Build Coastguard Worker 
169*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < noNoiseBands; band++) {
170*e5436536SAndroid Build Coastguard Worker       accu = FL2FXCONST_DBL(0.0f);
171*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < NF_SMOOTHING_LENGTH; i++) {
172*e5436536SAndroid Build Coastguard Worker         accu += fMultDiv2(pSmoothFilter[i], prevNoiseLevels[i][band]);
173*e5436536SAndroid Build Coastguard Worker       }
174*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
175*e5436536SAndroid Build Coastguard Worker       NoiseLevels[band + env * noNoiseBands] = accu << 1;
176*e5436536SAndroid Build Coastguard Worker     }
177*e5436536SAndroid Build Coastguard Worker   }
178*e5436536SAndroid Build Coastguard Worker }
179*e5436536SAndroid Build Coastguard Worker 
180*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
181*e5436536SAndroid Build Coastguard Worker /*!
182*e5436536SAndroid Build Coastguard Worker   \brief     Does the noise floor level estiamtion.
183*e5436536SAndroid Build Coastguard Worker 
184*e5436536SAndroid Build Coastguard Worker   The noiseLevel samples are scaled by the factor 0.25
185*e5436536SAndroid Build Coastguard Worker 
186*e5436536SAndroid Build Coastguard Worker   \return    none
187*e5436536SAndroid Build Coastguard Worker 
188*e5436536SAndroid Build Coastguard Worker */
189*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
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*e5436536SAndroid Build Coastguard Worker static void qmfBasedNoiseFloorDetection(
191*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *noiseLevel,            /*!< Pointer to vector to
192*e5436536SAndroid Build Coastguard Worker                                         store the noise levels
193*e5436536SAndroid Build Coastguard Worker                                         in.*/
194*e5436536SAndroid Build Coastguard Worker     FIXP_DBL **quotaMatrixOrig,      /*!< Matrix holding the quota
195*e5436536SAndroid Build Coastguard Worker                                         values of the original. */
196*e5436536SAndroid Build Coastguard Worker     SCHAR *indexVector,              /*!< Index vector to obtain the
197*e5436536SAndroid Build Coastguard Worker                                         patched data. */
198*e5436536SAndroid Build Coastguard Worker     INT startIndex,                  /*!< Start index. */
199*e5436536SAndroid Build Coastguard Worker     INT stopIndex,                   /*!< Stop index. */
200*e5436536SAndroid Build Coastguard Worker     INT startChannel,                /*!< Start channel of the current
201*e5436536SAndroid Build Coastguard Worker                                         noise floor band.*/
202*e5436536SAndroid Build Coastguard Worker     INT stopChannel,                 /*!< Stop channel of the current
203*e5436536SAndroid Build Coastguard Worker                                         noise floor band. */
204*e5436536SAndroid Build Coastguard Worker     FIXP_DBL ana_max_level,          /*!< Maximum level of the
205*e5436536SAndroid Build Coastguard Worker                                         adaptive noise.*/
206*e5436536SAndroid Build Coastguard Worker     FIXP_DBL noiseFloorOffset,       /*!< Noise floor offset. */
207*e5436536SAndroid Build Coastguard Worker     INT missingHarmonicFlag,         /*!< Flag indicating if a
208*e5436536SAndroid Build Coastguard Worker                                         strong tonal component
209*e5436536SAndroid Build Coastguard Worker                                         is missing.*/
210*e5436536SAndroid Build Coastguard Worker     FIXP_DBL weightFac,              /*!< Weightening factor for the
211*e5436536SAndroid Build Coastguard Worker                                         difference between orig and sbr.
212*e5436536SAndroid Build Coastguard Worker                                       */
213*e5436536SAndroid Build Coastguard Worker     INVF_MODE diffThres,             /*!< Threshold value to control the
214*e5436536SAndroid Build Coastguard Worker                                         inverse filtering decision.*/
215*e5436536SAndroid Build Coastguard Worker     INVF_MODE inverseFilteringLevel) /*!< Inverse filtering
216*e5436536SAndroid Build Coastguard Worker                                         level of the current
217*e5436536SAndroid Build Coastguard Worker                                         band.*/
218*e5436536SAndroid Build Coastguard Worker {
219*e5436536SAndroid Build Coastguard Worker   INT scale, l, k;
220*e5436536SAndroid Build Coastguard Worker   FIXP_DBL meanOrig = FL2FXCONST_DBL(0.0f), meanSbr = FL2FXCONST_DBL(0.0f),
221*e5436536SAndroid Build Coastguard Worker            diff;
222*e5436536SAndroid Build Coastguard Worker   FIXP_DBL invIndex = GetInvInt(stopIndex - startIndex);
223*e5436536SAndroid Build Coastguard Worker   FIXP_DBL invChannel = GetInvInt(stopChannel - startChannel);
224*e5436536SAndroid Build Coastguard Worker   FIXP_DBL accu;
225*e5436536SAndroid Build Coastguard Worker 
226*e5436536SAndroid Build Coastguard Worker   /*
227*e5436536SAndroid Build Coastguard Worker   Calculate the mean value, over the current time segment, for the original, the
228*e5436536SAndroid Build Coastguard Worker   HFR and the difference, over all channels in the current frequency range.
229*e5436536SAndroid Build Coastguard Worker   */
230*e5436536SAndroid Build Coastguard Worker 
231*e5436536SAndroid Build Coastguard Worker   if (missingHarmonicFlag == 1) {
232*e5436536SAndroid Build Coastguard Worker     for (l = startChannel; l < stopChannel; l++) {
233*e5436536SAndroid Build Coastguard Worker       /* tonalityOrig */
234*e5436536SAndroid Build Coastguard Worker       accu = FL2FXCONST_DBL(0.0f);
235*e5436536SAndroid Build Coastguard Worker       for (k = startIndex; k < stopIndex; k++) {
236*e5436536SAndroid Build Coastguard Worker         accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
237*e5436536SAndroid Build Coastguard Worker       }
238*e5436536SAndroid Build Coastguard Worker       meanOrig = fixMax(meanOrig, (accu << 1));
239*e5436536SAndroid Build Coastguard Worker 
240*e5436536SAndroid Build Coastguard Worker       /* tonalitySbr */
241*e5436536SAndroid Build Coastguard Worker       accu = FL2FXCONST_DBL(0.0f);
242*e5436536SAndroid Build Coastguard Worker       for (k = startIndex; k < stopIndex; k++) {
243*e5436536SAndroid Build Coastguard Worker         accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
244*e5436536SAndroid Build Coastguard Worker       }
245*e5436536SAndroid Build Coastguard Worker       meanSbr = fixMax(meanSbr, (accu << 1));
246*e5436536SAndroid Build Coastguard Worker     }
247*e5436536SAndroid Build Coastguard Worker   } else {
248*e5436536SAndroid Build Coastguard Worker     for (l = startChannel; l < stopChannel; l++) {
249*e5436536SAndroid Build Coastguard Worker       /* tonalityOrig */
250*e5436536SAndroid Build Coastguard Worker       accu = FL2FXCONST_DBL(0.0f);
251*e5436536SAndroid Build Coastguard Worker       for (k = startIndex; k < stopIndex; k++) {
252*e5436536SAndroid Build Coastguard Worker         accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex);
253*e5436536SAndroid Build Coastguard Worker       }
254*e5436536SAndroid Build Coastguard Worker       meanOrig += fMult((accu << 1), invChannel);
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker       /* tonalitySbr */
257*e5436536SAndroid Build Coastguard Worker       accu = FL2FXCONST_DBL(0.0f);
258*e5436536SAndroid Build Coastguard Worker       for (k = startIndex; k < stopIndex; k++) {
259*e5436536SAndroid Build Coastguard Worker         accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex);
260*e5436536SAndroid Build Coastguard Worker       }
261*e5436536SAndroid Build Coastguard Worker       meanSbr += fMult((accu << 1), invChannel);
262*e5436536SAndroid Build Coastguard Worker     }
263*e5436536SAndroid Build Coastguard Worker   }
264*e5436536SAndroid Build Coastguard Worker 
265*e5436536SAndroid Build Coastguard Worker   /* Small fix to avoid noise during silent passages.*/
266*e5436536SAndroid Build Coastguard Worker   if (meanOrig <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT) &&
267*e5436536SAndroid Build Coastguard Worker       meanSbr <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT)) {
268*e5436536SAndroid Build Coastguard Worker     meanOrig = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
269*e5436536SAndroid Build Coastguard Worker     meanSbr = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT);
270*e5436536SAndroid Build Coastguard Worker   }
271*e5436536SAndroid Build Coastguard Worker 
272*e5436536SAndroid Build Coastguard Worker   meanOrig = fixMax(meanOrig, RELAXATION);
273*e5436536SAndroid Build Coastguard Worker   meanSbr = fixMax(meanSbr, RELAXATION);
274*e5436536SAndroid Build Coastguard Worker 
275*e5436536SAndroid Build Coastguard Worker   if (missingHarmonicFlag == 1 || inverseFilteringLevel == INVF_MID_LEVEL ||
276*e5436536SAndroid Build Coastguard Worker       inverseFilteringLevel == INVF_LOW_LEVEL ||
277*e5436536SAndroid Build Coastguard Worker       inverseFilteringLevel == INVF_OFF || inverseFilteringLevel <= diffThres) {
278*e5436536SAndroid Build Coastguard Worker     diff = RELAXATION;
279*e5436536SAndroid Build Coastguard Worker   } else {
280*e5436536SAndroid Build Coastguard Worker     accu = fDivNorm(meanSbr, meanOrig, &scale);
281*e5436536SAndroid Build Coastguard Worker 
282*e5436536SAndroid Build Coastguard Worker     diff = fixMax(RELAXATION, fMult(RELAXATION_FRACT, fMult(weightFac, accu)) >>
283*e5436536SAndroid Build Coastguard Worker                                   (RELAXATION_SHIFT - scale));
284*e5436536SAndroid Build Coastguard Worker   }
285*e5436536SAndroid Build Coastguard Worker 
286*e5436536SAndroid Build Coastguard Worker   /*
287*e5436536SAndroid Build Coastguard Worker    * noise Level is now a positive value, i.e.
288*e5436536SAndroid Build Coastguard Worker    * the more harmonic the signal is the higher noise level,
289*e5436536SAndroid Build Coastguard Worker    * this makes no sense so we change the sign.
290*e5436536SAndroid Build Coastguard Worker    *********************************************************/
291*e5436536SAndroid Build Coastguard Worker   accu = fDivNorm(diff, meanOrig, &scale);
292*e5436536SAndroid Build Coastguard Worker   scale -= 2;
293*e5436536SAndroid Build Coastguard Worker 
294*e5436536SAndroid Build Coastguard Worker   if ((scale > 0) && (accu > ((FIXP_DBL)MAXVAL_DBL) >> scale)) {
295*e5436536SAndroid Build Coastguard Worker     *noiseLevel = (FIXP_DBL)MAXVAL_DBL;
296*e5436536SAndroid Build Coastguard Worker   } else {
297*e5436536SAndroid Build Coastguard Worker     *noiseLevel = scaleValue(accu, scale);
298*e5436536SAndroid Build Coastguard Worker   }
299*e5436536SAndroid Build Coastguard Worker 
300*e5436536SAndroid Build Coastguard Worker   /*
301*e5436536SAndroid Build Coastguard Worker    * Add a noise floor offset to compensate for bias in the detector
302*e5436536SAndroid Build Coastguard Worker    *****************************************************************/
303*e5436536SAndroid Build Coastguard Worker   if (!missingHarmonicFlag) {
304*e5436536SAndroid Build Coastguard Worker     *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset),
305*e5436536SAndroid Build Coastguard Worker                          (FIXP_DBL)MAXVAL_DBL >> NOISE_FLOOR_OFFSET_SCALING)
306*e5436536SAndroid Build Coastguard Worker                   << NOISE_FLOOR_OFFSET_SCALING;
307*e5436536SAndroid Build Coastguard Worker   }
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker   /*
310*e5436536SAndroid Build Coastguard Worker    * check to see that we don't exceed the maximum allowed level
311*e5436536SAndroid Build Coastguard Worker    **************************************************************/
312*e5436536SAndroid Build Coastguard Worker   *noiseLevel =
313*e5436536SAndroid Build Coastguard Worker       fixMin(*noiseLevel,
314*e5436536SAndroid Build Coastguard Worker              ana_max_level); /* ana_max_level is scaled with factor 0.25 */
315*e5436536SAndroid Build Coastguard Worker }
316*e5436536SAndroid Build Coastguard Worker 
317*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
318*e5436536SAndroid Build Coastguard Worker /*!
319*e5436536SAndroid Build Coastguard Worker   \brief     Does the noise floor level estiamtion.
320*e5436536SAndroid Build Coastguard Worker   The function calls the Noisefloor estimation function
321*e5436536SAndroid Build Coastguard Worker   for the time segments decided based upon the transient
322*e5436536SAndroid Build Coastguard Worker   information. The block is always divided into one or two segments.
323*e5436536SAndroid Build Coastguard Worker 
324*e5436536SAndroid Build Coastguard Worker 
325*e5436536SAndroid Build Coastguard Worker   \return    none
326*e5436536SAndroid Build Coastguard Worker 
327*e5436536SAndroid Build Coastguard Worker */
328*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
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*e5436536SAndroid Build Coastguard Worker void FDKsbrEnc_sbrNoiseFloorEstimateQmf(
330*e5436536SAndroid Build Coastguard Worker     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
331*e5436536SAndroid Build Coastguard Worker         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
332*e5436536SAndroid Build Coastguard Worker                                   */
333*e5436536SAndroid Build Coastguard Worker     const SBR_FRAME_INFO
334*e5436536SAndroid Build Coastguard Worker         *frame_info, /*!< Time frequency grid of the current frame. */
335*e5436536SAndroid Build Coastguard Worker     FIXP_DBL
336*e5436536SAndroid Build Coastguard Worker         *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/
337*e5436536SAndroid Build Coastguard Worker     FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the
338*e5436536SAndroid Build Coastguard Worker                                    original. */
339*e5436536SAndroid Build Coastguard Worker     SCHAR *indexVector,         /*!< Index vector to obtain the patched data. */
340*e5436536SAndroid Build Coastguard Worker     INT missingHarmonicsFlag,   /*!< Flag indicating if a strong tonal component
341*e5436536SAndroid Build Coastguard Worker                                    will be missing. */
342*e5436536SAndroid Build Coastguard Worker     INT startIndex,             /*!< Start index. */
343*e5436536SAndroid Build Coastguard Worker     UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per
344*e5436536SAndroid Build Coastguard Worker                                        frame. */
345*e5436536SAndroid Build Coastguard Worker     int transientFrame, /*!< A flag indicating if a transient is present. */
346*e5436536SAndroid Build Coastguard Worker     INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse
347*e5436536SAndroid Build Coastguard Worker                                   filtering levels. */
348*e5436536SAndroid Build Coastguard Worker     UINT sbrSyntaxFlags)
349*e5436536SAndroid Build Coastguard Worker 
350*e5436536SAndroid Build Coastguard Worker {
351*e5436536SAndroid Build Coastguard Worker   INT nNoiseEnvelopes, startPos[2], stopPos[2], env, band;
352*e5436536SAndroid Build Coastguard Worker 
353*e5436536SAndroid Build Coastguard Worker   INT noNoiseBands = h_sbrNoiseFloorEstimate->noNoiseBands;
354*e5436536SAndroid Build Coastguard Worker   INT *freqBandTable = h_sbrNoiseFloorEstimate->freqBandTableQmf;
355*e5436536SAndroid Build Coastguard Worker 
356*e5436536SAndroid Build Coastguard Worker   nNoiseEnvelopes = frame_info->nNoiseEnvelopes;
357*e5436536SAndroid Build Coastguard Worker 
358*e5436536SAndroid Build Coastguard Worker   startPos[0] = startIndex;
359*e5436536SAndroid Build Coastguard Worker 
360*e5436536SAndroid Build Coastguard Worker   if (nNoiseEnvelopes == 1) {
361*e5436536SAndroid Build Coastguard Worker     stopPos[0] = startIndex + min(numberOfEstimatesPerFrame, 2);
362*e5436536SAndroid Build Coastguard Worker   } else {
363*e5436536SAndroid Build Coastguard Worker     stopPos[0] = startIndex + 1;
364*e5436536SAndroid Build Coastguard Worker     startPos[1] = startIndex + 1;
365*e5436536SAndroid Build Coastguard Worker     stopPos[1] = startIndex + min(numberOfEstimatesPerFrame, 2);
366*e5436536SAndroid Build Coastguard Worker   }
367*e5436536SAndroid Build Coastguard Worker 
368*e5436536SAndroid Build Coastguard Worker   /*
369*e5436536SAndroid Build Coastguard Worker    * Estimate the noise floor.
370*e5436536SAndroid Build Coastguard Worker    **************************************/
371*e5436536SAndroid Build Coastguard Worker   for (env = 0; env < nNoiseEnvelopes; env++) {
372*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < noNoiseBands; band++) {
373*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
374*e5436536SAndroid Build Coastguard Worker       qmfBasedNoiseFloorDetection(
375*e5436536SAndroid Build Coastguard Worker           &noiseLevels[band + env * noNoiseBands], quotaMatrixOrig, indexVector,
376*e5436536SAndroid Build Coastguard Worker           startPos[env], stopPos[env], freqBandTable[band],
377*e5436536SAndroid Build Coastguard Worker           freqBandTable[band + 1], h_sbrNoiseFloorEstimate->ana_max_level,
378*e5436536SAndroid Build Coastguard Worker           h_sbrNoiseFloorEstimate->noiseFloorOffset[band], missingHarmonicsFlag,
379*e5436536SAndroid Build Coastguard Worker           h_sbrNoiseFloorEstimate->weightFac,
380*e5436536SAndroid Build Coastguard Worker           h_sbrNoiseFloorEstimate->diffThres, pInvFiltLevels[band]);
381*e5436536SAndroid Build Coastguard Worker     }
382*e5436536SAndroid Build Coastguard Worker   }
383*e5436536SAndroid Build Coastguard Worker 
384*e5436536SAndroid Build Coastguard Worker   /*
385*e5436536SAndroid Build Coastguard Worker    * Smoothing of the values.
386*e5436536SAndroid Build Coastguard Worker    **************************/
387*e5436536SAndroid Build Coastguard Worker   smoothingOfNoiseLevels(noiseLevels, nNoiseEnvelopes,
388*e5436536SAndroid Build Coastguard Worker                          h_sbrNoiseFloorEstimate->noNoiseBands,
389*e5436536SAndroid Build Coastguard Worker                          h_sbrNoiseFloorEstimate->prevNoiseLevels,
390*e5436536SAndroid Build Coastguard Worker                          h_sbrNoiseFloorEstimate->smoothFilter, transientFrame);
391*e5436536SAndroid Build Coastguard Worker 
392*e5436536SAndroid Build Coastguard Worker   /* quantisation*/
393*e5436536SAndroid Build Coastguard Worker   for (env = 0; env < nNoiseEnvelopes; env++) {
394*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < noNoiseBands; band++) {
395*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES);
396*e5436536SAndroid Build Coastguard Worker       noiseLevels[band + env * noNoiseBands] =
397*e5436536SAndroid Build Coastguard Worker           (FIXP_DBL)NOISE_FLOOR_OFFSET_64 -
398*e5436536SAndroid Build Coastguard Worker           (FIXP_DBL)CalcLdData(noiseLevels[band + env * noNoiseBands] +
399*e5436536SAndroid Build Coastguard Worker                                (FIXP_DBL)1) +
400*e5436536SAndroid Build Coastguard Worker           QuantOffset;
401*e5436536SAndroid Build Coastguard Worker     }
402*e5436536SAndroid Build Coastguard Worker   }
403*e5436536SAndroid Build Coastguard Worker }
404*e5436536SAndroid Build Coastguard Worker 
405*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
406*e5436536SAndroid Build Coastguard Worker /*!
407*e5436536SAndroid Build Coastguard Worker   \brief
408*e5436536SAndroid Build Coastguard Worker 
409*e5436536SAndroid Build Coastguard Worker 
410*e5436536SAndroid Build Coastguard Worker   \return    errorCode, noError if successful
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker */
413*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
downSampleLoRes(INT * v_result,INT num_result,const UCHAR * freqBandTableRef,INT num_Ref)414*e5436536SAndroid Build Coastguard Worker static INT downSampleLoRes(INT *v_result,                 /*!<    */
415*e5436536SAndroid Build Coastguard Worker                            INT num_result,                /*!<    */
416*e5436536SAndroid Build Coastguard Worker                            const UCHAR *freqBandTableRef, /*!<    */
417*e5436536SAndroid Build Coastguard Worker                            INT num_Ref)                   /*!<    */
418*e5436536SAndroid Build Coastguard Worker {
419*e5436536SAndroid Build Coastguard Worker   INT step;
420*e5436536SAndroid Build Coastguard Worker   INT i, j;
421*e5436536SAndroid Build Coastguard Worker   INT org_length, result_length;
422*e5436536SAndroid Build Coastguard Worker   INT v_index[MAX_FREQ_COEFFS / 2];
423*e5436536SAndroid Build Coastguard Worker 
424*e5436536SAndroid Build Coastguard Worker   /* init */
425*e5436536SAndroid Build Coastguard Worker   org_length = num_Ref;
426*e5436536SAndroid Build Coastguard Worker   result_length = num_result;
427*e5436536SAndroid Build Coastguard Worker 
428*e5436536SAndroid Build Coastguard Worker   v_index[0] = 0; /* Always use left border */
429*e5436536SAndroid Build Coastguard Worker   i = 0;
430*e5436536SAndroid Build Coastguard Worker   while (org_length > 0) /* Create downsample vector */
431*e5436536SAndroid Build Coastguard Worker   {
432*e5436536SAndroid Build Coastguard Worker     i++;
433*e5436536SAndroid Build Coastguard Worker     step = org_length / result_length; /* floor; */
434*e5436536SAndroid Build Coastguard Worker     org_length = org_length - step;
435*e5436536SAndroid Build Coastguard Worker     result_length--;
436*e5436536SAndroid Build Coastguard Worker     v_index[i] = v_index[i - 1] + step;
437*e5436536SAndroid Build Coastguard Worker   }
438*e5436536SAndroid Build Coastguard Worker 
439*e5436536SAndroid Build Coastguard Worker   if (i != num_result) /* Should never happen */
440*e5436536SAndroid Build Coastguard Worker     return (1);        /* error downsampling */
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   for (j = 0; j <= i;
443*e5436536SAndroid Build Coastguard Worker        j++) /* Use downsample vector to index LoResolution vector. */
444*e5436536SAndroid Build Coastguard Worker   {
445*e5436536SAndroid Build Coastguard Worker     v_result[j] = freqBandTableRef[v_index[j]];
446*e5436536SAndroid Build Coastguard Worker   }
447*e5436536SAndroid Build Coastguard Worker 
448*e5436536SAndroid Build Coastguard Worker   return (0);
449*e5436536SAndroid Build Coastguard Worker }
450*e5436536SAndroid Build Coastguard Worker 
451*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
452*e5436536SAndroid Build Coastguard Worker /*!
453*e5436536SAndroid Build Coastguard Worker   \brief    Initialize an instance of the noise floor level estimation module.
454*e5436536SAndroid Build Coastguard Worker 
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker   \return    errorCode, noError if successful
457*e5436536SAndroid Build Coastguard Worker 
458*e5436536SAndroid Build Coastguard Worker */
459*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
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*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_InitSbrNoiseFloorEstimate(
461*e5436536SAndroid Build Coastguard Worker     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
462*e5436536SAndroid Build Coastguard Worker         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
463*e5436536SAndroid Build Coastguard Worker                                   */
464*e5436536SAndroid Build Coastguard Worker     INT ana_max_level,           /*!< Maximum level of the adaptive noise. */
465*e5436536SAndroid Build Coastguard Worker     const UCHAR *freqBandTable,  /*!< Frequency band table. */
466*e5436536SAndroid Build Coastguard Worker     INT nSfb,                    /*!< Number of frequency bands. */
467*e5436536SAndroid Build Coastguard Worker     INT noiseBands,              /*!< Number of noise bands per octave. */
468*e5436536SAndroid Build Coastguard Worker     INT noiseFloorOffset,        /*!< Noise floor offset. */
469*e5436536SAndroid Build Coastguard Worker     INT timeSlots,               /*!< Number of time slots in a frame. */
470*e5436536SAndroid Build Coastguard Worker     UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech
471*e5436536SAndroid Build Coastguard Worker                           */
472*e5436536SAndroid Build Coastguard Worker ) {
473*e5436536SAndroid Build Coastguard Worker   INT i, qexp, qtmp;
474*e5436536SAndroid Build Coastguard Worker   FIXP_DBL tmp, exp;
475*e5436536SAndroid Build Coastguard Worker 
476*e5436536SAndroid Build Coastguard Worker   FDKmemclear(h_sbrNoiseFloorEstimate, sizeof(SBR_NOISE_FLOOR_ESTIMATE));
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker   h_sbrNoiseFloorEstimate->smoothFilter = smoothFilter;
479*e5436536SAndroid Build Coastguard Worker   if (useSpeechConfig) {
480*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->weightFac = (FIXP_DBL)MAXVAL_DBL;
481*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->diffThres = INVF_LOW_LEVEL;
482*e5436536SAndroid Build Coastguard Worker   } else {
483*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->weightFac = FL2FXCONST_DBL(0.25f);
484*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->diffThres = INVF_MID_LEVEL;
485*e5436536SAndroid Build Coastguard Worker   }
486*e5436536SAndroid Build Coastguard Worker 
487*e5436536SAndroid Build Coastguard Worker   h_sbrNoiseFloorEstimate->timeSlots = timeSlots;
488*e5436536SAndroid Build Coastguard Worker   h_sbrNoiseFloorEstimate->noiseBands = noiseBands;
489*e5436536SAndroid Build Coastguard Worker 
490*e5436536SAndroid Build Coastguard Worker   /* h_sbrNoiseFloorEstimate->ana_max_level is scaled by 0.25  */
491*e5436536SAndroid Build Coastguard Worker   switch (ana_max_level) {
492*e5436536SAndroid Build Coastguard Worker     case 6:
493*e5436536SAndroid Build Coastguard Worker       h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
494*e5436536SAndroid Build Coastguard Worker       break;
495*e5436536SAndroid Build Coastguard Worker     case 3:
496*e5436536SAndroid Build Coastguard Worker       h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.5);
497*e5436536SAndroid Build Coastguard Worker       break;
498*e5436536SAndroid Build Coastguard Worker     case -3:
499*e5436536SAndroid Build Coastguard Worker       h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.125);
500*e5436536SAndroid Build Coastguard Worker       break;
501*e5436536SAndroid Build Coastguard Worker     default:
502*e5436536SAndroid Build Coastguard Worker       /* Should not enter here */
503*e5436536SAndroid Build Coastguard Worker       h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL;
504*e5436536SAndroid Build Coastguard Worker       break;
505*e5436536SAndroid Build Coastguard Worker   }
506*e5436536SAndroid Build Coastguard Worker 
507*e5436536SAndroid Build Coastguard Worker   /*
508*e5436536SAndroid Build Coastguard Worker     calculate number of noise bands and allocate
509*e5436536SAndroid Build Coastguard Worker   */
510*e5436536SAndroid Build Coastguard Worker   if (FDKsbrEnc_resetSbrNoiseFloorEstimate(h_sbrNoiseFloorEstimate,
511*e5436536SAndroid Build Coastguard Worker                                            freqBandTable, nSfb))
512*e5436536SAndroid Build Coastguard Worker     return (1);
513*e5436536SAndroid Build Coastguard Worker 
514*e5436536SAndroid Build Coastguard Worker   if (noiseFloorOffset == 0) {
515*e5436536SAndroid Build Coastguard Worker     tmp = ((FIXP_DBL)MAXVAL_DBL) >> NOISE_FLOOR_OFFSET_SCALING;
516*e5436536SAndroid Build Coastguard Worker   } else {
517*e5436536SAndroid Build Coastguard Worker     /* noiseFloorOffset has to be smaller than 12, because
518*e5436536SAndroid Build Coastguard Worker        the result of the calculation below must be smaller than 1:
519*e5436536SAndroid Build Coastguard Worker        (2^(noiseFloorOffset/3))*2^4<1                                        */
520*e5436536SAndroid Build Coastguard Worker     FDK_ASSERT(noiseFloorOffset < 12);
521*e5436536SAndroid Build Coastguard Worker 
522*e5436536SAndroid Build Coastguard Worker     /* Assumes the noise floor offset in tuning table are in q31    */
523*e5436536SAndroid Build Coastguard Worker     /* Change the qformat here when non-zero values would be filled */
524*e5436536SAndroid Build Coastguard Worker     exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp);
525*e5436536SAndroid Build Coastguard Worker     tmp = fPow(2, DFRACT_BITS - 1, exp, qexp, &qtmp);
526*e5436536SAndroid Build Coastguard Worker     tmp = scaleValue(tmp, qtmp - NOISE_FLOOR_OFFSET_SCALING);
527*e5436536SAndroid Build Coastguard Worker   }
528*e5436536SAndroid Build Coastguard Worker 
529*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < h_sbrNoiseFloorEstimate->noNoiseBands; i++) {
530*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->noiseFloorOffset[i] = tmp;
531*e5436536SAndroid Build Coastguard Worker   }
532*e5436536SAndroid Build Coastguard Worker 
533*e5436536SAndroid Build Coastguard Worker   return (0);
534*e5436536SAndroid Build Coastguard Worker }
535*e5436536SAndroid Build Coastguard Worker 
536*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
537*e5436536SAndroid Build Coastguard Worker /*!
538*e5436536SAndroid Build Coastguard Worker   \brief     Resets the current instance of the noise floor estiamtion
539*e5436536SAndroid Build Coastguard Worker           module.
540*e5436536SAndroid Build Coastguard Worker 
541*e5436536SAndroid Build Coastguard Worker 
542*e5436536SAndroid Build Coastguard Worker   \return    errorCode, noError if successful
543*e5436536SAndroid Build Coastguard Worker 
544*e5436536SAndroid Build Coastguard Worker */
545*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_resetSbrNoiseFloorEstimate(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate,const UCHAR * freqBandTable,INT nSfb)546*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_resetSbrNoiseFloorEstimate(
547*e5436536SAndroid Build Coastguard Worker     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
548*e5436536SAndroid Build Coastguard Worker         h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
549*e5436536SAndroid Build Coastguard Worker                                   */
550*e5436536SAndroid Build Coastguard Worker     const UCHAR *freqBandTable,  /*!< Frequency band table. */
551*e5436536SAndroid Build Coastguard Worker     INT nSfb /*!< Number of bands in the frequency band table. */
552*e5436536SAndroid Build Coastguard Worker ) {
553*e5436536SAndroid Build Coastguard Worker   INT k2, kx;
554*e5436536SAndroid Build Coastguard Worker 
555*e5436536SAndroid Build Coastguard Worker   /*
556*e5436536SAndroid Build Coastguard Worker    * Calculate number of noise bands
557*e5436536SAndroid Build Coastguard Worker    ***********************************/
558*e5436536SAndroid Build Coastguard Worker   k2 = freqBandTable[nSfb];
559*e5436536SAndroid Build Coastguard Worker   kx = freqBandTable[0];
560*e5436536SAndroid Build Coastguard Worker   if (h_sbrNoiseFloorEstimate->noiseBands == 0) {
561*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->noNoiseBands = 1;
562*e5436536SAndroid Build Coastguard Worker   } else {
563*e5436536SAndroid Build Coastguard Worker     /*
564*e5436536SAndroid Build Coastguard Worker      * Calculate number of noise bands 1,2 or 3 bands/octave
565*e5436536SAndroid Build Coastguard Worker      ********************************************************/
566*e5436536SAndroid Build Coastguard Worker     FIXP_DBL tmp, ratio, lg2;
567*e5436536SAndroid Build Coastguard Worker     INT ratio_e, qlg2, nNoiseBands;
568*e5436536SAndroid Build Coastguard Worker 
569*e5436536SAndroid Build Coastguard Worker     ratio = fDivNorm(k2, kx, &ratio_e);
570*e5436536SAndroid Build Coastguard Worker     lg2 = fLog2(ratio, ratio_e, &qlg2);
571*e5436536SAndroid Build Coastguard Worker     tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands << 24), lg2);
572*e5436536SAndroid Build Coastguard Worker     tmp = scaleValue(tmp, qlg2 - 23);
573*e5436536SAndroid Build Coastguard Worker 
574*e5436536SAndroid Build Coastguard Worker     nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1);
575*e5436536SAndroid Build Coastguard Worker 
576*e5436536SAndroid Build Coastguard Worker     if (nNoiseBands > MAX_NUM_NOISE_COEFFS) {
577*e5436536SAndroid Build Coastguard Worker       nNoiseBands = MAX_NUM_NOISE_COEFFS;
578*e5436536SAndroid Build Coastguard Worker     }
579*e5436536SAndroid Build Coastguard Worker 
580*e5436536SAndroid Build Coastguard Worker     if (nNoiseBands == 0) {
581*e5436536SAndroid Build Coastguard Worker       nNoiseBands = 1;
582*e5436536SAndroid Build Coastguard Worker     }
583*e5436536SAndroid Build Coastguard Worker 
584*e5436536SAndroid Build Coastguard Worker     h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands;
585*e5436536SAndroid Build Coastguard Worker   }
586*e5436536SAndroid Build Coastguard Worker 
587*e5436536SAndroid Build Coastguard Worker   return (downSampleLoRes(h_sbrNoiseFloorEstimate->freqBandTableQmf,
588*e5436536SAndroid Build Coastguard Worker                           h_sbrNoiseFloorEstimate->noNoiseBands, freqBandTable,
589*e5436536SAndroid Build Coastguard Worker                           nSfb));
590*e5436536SAndroid Build Coastguard Worker }
591*e5436536SAndroid Build Coastguard Worker 
592*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
593*e5436536SAndroid Build Coastguard Worker /*!
594*e5436536SAndroid Build Coastguard Worker   \brief     Deletes the current instancce of the noise floor level
595*e5436536SAndroid Build Coastguard Worker   estimation module.
596*e5436536SAndroid Build Coastguard Worker 
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker   \return    none
599*e5436536SAndroid Build Coastguard Worker 
600*e5436536SAndroid Build Coastguard Worker */
601*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_deleteSbrNoiseFloorEstimate(HANDLE_SBR_NOISE_FLOOR_ESTIMATE h_sbrNoiseFloorEstimate)602*e5436536SAndroid Build Coastguard Worker void FDKsbrEnc_deleteSbrNoiseFloorEstimate(
603*e5436536SAndroid Build Coastguard Worker     HANDLE_SBR_NOISE_FLOOR_ESTIMATE
604*e5436536SAndroid Build Coastguard Worker         h_sbrNoiseFloorEstimate) /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct
605*e5436536SAndroid Build Coastguard Worker                                   */
606*e5436536SAndroid Build Coastguard Worker {
607*e5436536SAndroid Build Coastguard Worker   if (h_sbrNoiseFloorEstimate) {
608*e5436536SAndroid Build Coastguard Worker     /*
609*e5436536SAndroid Build Coastguard Worker       nothing to do
610*e5436536SAndroid Build Coastguard Worker     */
611*e5436536SAndroid Build Coastguard Worker   }
612*e5436536SAndroid Build Coastguard Worker }
613