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