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 "mh_det.h"
104*e5436536SAndroid Build Coastguard Worker
105*e5436536SAndroid Build Coastguard Worker #include "sbrenc_ram.h"
106*e5436536SAndroid Build Coastguard Worker #include "sbr_misc.h"
107*e5436536SAndroid Build Coastguard Worker
108*e5436536SAndroid Build Coastguard Worker #include "genericStds.h"
109*e5436536SAndroid Build Coastguard Worker
110*e5436536SAndroid Build Coastguard Worker #define SFM_SHIFT 2 /* Attention: SFM_SCALE depends on SFM_SHIFT */
111*e5436536SAndroid Build Coastguard Worker #define SFM_SCALE (MAXVAL_DBL >> SFM_SHIFT) /* 1.0 >> SFM_SHIFT */
112*e5436536SAndroid Build Coastguard Worker
113*e5436536SAndroid Build Coastguard Worker /*!< Detector Parameters for AAC core codec. */
114*e5436536SAndroid Build Coastguard Worker static const DETECTOR_PARAMETERS_MH paramsAac = {
115*e5436536SAndroid Build Coastguard Worker 9, /*!< deltaTime */
116*e5436536SAndroid Build Coastguard Worker {
117*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(20.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */
118*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldDiffGuide */
119*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */
120*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL((1.0f / 15.0f) *
121*e5436536SAndroid Build Coastguard Worker RELAXATION_FLOAT), /*!< invThresHoldTone */
122*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */
123*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */
124*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */
125*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */
126*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.5f), /*!< decayGuideDiff */
127*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.000112993269),
128*e5436536SAndroid Build Coastguard Worker /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */
129*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.000112993269),
130*e5436536SAndroid Build Coastguard Worker /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */
131*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(
132*e5436536SAndroid Build Coastguard Worker -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!<
133*e5436536SAndroid Build Coastguard Worker derivThresAboveLD64
134*e5436536SAndroid Build Coastguard Worker */
135*e5436536SAndroid Build Coastguard Worker },
136*e5436536SAndroid Build Coastguard Worker 50 /*!< maxComp */
137*e5436536SAndroid Build Coastguard Worker };
138*e5436536SAndroid Build Coastguard Worker
139*e5436536SAndroid Build Coastguard Worker /*!< Detector Parameters for AAC LD core codec. */
140*e5436536SAndroid Build Coastguard Worker static const DETECTOR_PARAMETERS_MH paramsAacLd = {
141*e5436536SAndroid Build Coastguard Worker 16, /*!< Delta time. */
142*e5436536SAndroid Build Coastguard Worker {
143*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(25.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */
144*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< tresHoldDiffGuide */
145*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */
146*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL((1.0f / 15.0f) *
147*e5436536SAndroid Build Coastguard Worker RELAXATION_FLOAT), /*!< invThresHoldTone */
148*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */
149*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */
150*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */
151*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */
152*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.2f), /*!< decayGuideDiff */
153*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.000112993269),
154*e5436536SAndroid Build Coastguard Worker /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */
155*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(-0.000112993269),
156*e5436536SAndroid Build Coastguard Worker /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */
157*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(
158*e5436536SAndroid Build Coastguard Worker -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!<
159*e5436536SAndroid Build Coastguard Worker derivThresAboveLD64
160*e5436536SAndroid Build Coastguard Worker */
161*e5436536SAndroid Build Coastguard Worker },
162*e5436536SAndroid Build Coastguard Worker 50 /*!< maxComp */
163*e5436536SAndroid Build Coastguard Worker };
164*e5436536SAndroid Build Coastguard Worker
165*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
166*e5436536SAndroid Build Coastguard Worker /*!
167*e5436536SAndroid Build Coastguard Worker \brief Calculates the difference in tonality between original and SBR
168*e5436536SAndroid Build Coastguard Worker for a given time and frequency region.
169*e5436536SAndroid Build Coastguard Worker
170*e5436536SAndroid Build Coastguard Worker The values for pDiffMapped2Scfb are scaled by RELAXATION
171*e5436536SAndroid Build Coastguard Worker
172*e5436536SAndroid Build Coastguard Worker \return none.
173*e5436536SAndroid Build Coastguard Worker
174*e5436536SAndroid Build Coastguard Worker */
175*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
diff(FIXP_DBL * RESTRICT pTonalityOrig,FIXP_DBL * pDiffMapped2Scfb,const UCHAR * RESTRICT pFreqBandTable,INT nScfb,SCHAR * indexVector)176*e5436536SAndroid Build Coastguard Worker static void diff(FIXP_DBL *RESTRICT pTonalityOrig, FIXP_DBL *pDiffMapped2Scfb,
177*e5436536SAndroid Build Coastguard Worker const UCHAR *RESTRICT pFreqBandTable, INT nScfb,
178*e5436536SAndroid Build Coastguard Worker SCHAR *indexVector) {
179*e5436536SAndroid Build Coastguard Worker UCHAR i, ll, lu, k;
180*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxValOrig, maxValSbr, tmp;
181*e5436536SAndroid Build Coastguard Worker INT scale;
182*e5436536SAndroid Build Coastguard Worker
183*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nScfb; i++) {
184*e5436536SAndroid Build Coastguard Worker ll = pFreqBandTable[i];
185*e5436536SAndroid Build Coastguard Worker lu = pFreqBandTable[i + 1];
186*e5436536SAndroid Build Coastguard Worker
187*e5436536SAndroid Build Coastguard Worker maxValOrig = FL2FXCONST_DBL(0.0f);
188*e5436536SAndroid Build Coastguard Worker maxValSbr = FL2FXCONST_DBL(0.0f);
189*e5436536SAndroid Build Coastguard Worker
190*e5436536SAndroid Build Coastguard Worker for (k = ll; k < lu; k++) {
191*e5436536SAndroid Build Coastguard Worker maxValOrig = fixMax(maxValOrig, pTonalityOrig[k]);
192*e5436536SAndroid Build Coastguard Worker maxValSbr = fixMax(maxValSbr, pTonalityOrig[indexVector[k]]);
193*e5436536SAndroid Build Coastguard Worker }
194*e5436536SAndroid Build Coastguard Worker
195*e5436536SAndroid Build Coastguard Worker if ((maxValSbr >= RELAXATION)) {
196*e5436536SAndroid Build Coastguard Worker tmp = fDivNorm(maxValOrig, maxValSbr, &scale);
197*e5436536SAndroid Build Coastguard Worker pDiffMapped2Scfb[i] =
198*e5436536SAndroid Build Coastguard Worker scaleValue(fMult(tmp, RELAXATION_FRACT),
199*e5436536SAndroid Build Coastguard Worker fixMax(-(DFRACT_BITS - 1), (scale - RELAXATION_SHIFT)));
200*e5436536SAndroid Build Coastguard Worker } else {
201*e5436536SAndroid Build Coastguard Worker pDiffMapped2Scfb[i] = maxValOrig;
202*e5436536SAndroid Build Coastguard Worker }
203*e5436536SAndroid Build Coastguard Worker }
204*e5436536SAndroid Build Coastguard Worker }
205*e5436536SAndroid Build Coastguard Worker
206*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
207*e5436536SAndroid Build Coastguard Worker /*!
208*e5436536SAndroid Build Coastguard Worker \brief Calculates a flatness measure of the tonality measures.
209*e5436536SAndroid Build Coastguard Worker
210*e5436536SAndroid Build Coastguard Worker Calculation of the power function and using scalefactor for basis:
211*e5436536SAndroid Build Coastguard Worker Using log2:
212*e5436536SAndroid Build Coastguard Worker z = (2^k * x)^y;
213*e5436536SAndroid Build Coastguard Worker z' = CalcLd(z) = y*CalcLd(x) + y*k;
214*e5436536SAndroid Build Coastguard Worker z = CalcInvLd(z');
215*e5436536SAndroid Build Coastguard Worker
216*e5436536SAndroid Build Coastguard Worker Using ld64:
217*e5436536SAndroid Build Coastguard Worker z = (2^k * x)^y;
218*e5436536SAndroid Build Coastguard Worker z' = CalcLd64(z) = y*CalcLd64(x)/64 + y*k/64;
219*e5436536SAndroid Build Coastguard Worker z = CalcInvLd64(z');
220*e5436536SAndroid Build Coastguard Worker
221*e5436536SAndroid Build Coastguard Worker The values pSfmOrigVec and pSfmSbrVec are scaled by the factor 1/4.0
222*e5436536SAndroid Build Coastguard Worker
223*e5436536SAndroid Build Coastguard Worker \return none.
224*e5436536SAndroid Build Coastguard Worker
225*e5436536SAndroid Build Coastguard Worker */
226*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
calculateFlatnessMeasure(FIXP_DBL * pQuotaBuffer,SCHAR * indexVector,FIXP_DBL * pSfmOrigVec,FIXP_DBL * pSfmSbrVec,const UCHAR * pFreqBandTable,INT nSfb)227*e5436536SAndroid Build Coastguard Worker static void calculateFlatnessMeasure(FIXP_DBL *pQuotaBuffer, SCHAR *indexVector,
228*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pSfmOrigVec,
229*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pSfmSbrVec,
230*e5436536SAndroid Build Coastguard Worker const UCHAR *pFreqBandTable, INT nSfb) {
231*e5436536SAndroid Build Coastguard Worker INT i, j;
232*e5436536SAndroid Build Coastguard Worker FIXP_DBL invBands, tmp1, tmp2;
233*e5436536SAndroid Build Coastguard Worker INT shiftFac0, shiftFacSum0;
234*e5436536SAndroid Build Coastguard Worker INT shiftFac1, shiftFacSum1;
235*e5436536SAndroid Build Coastguard Worker FIXP_DBL accu;
236*e5436536SAndroid Build Coastguard Worker
237*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
238*e5436536SAndroid Build Coastguard Worker INT ll = pFreqBandTable[i];
239*e5436536SAndroid Build Coastguard Worker INT lu = pFreqBandTable[i + 1];
240*e5436536SAndroid Build Coastguard Worker pSfmOrigVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2);
241*e5436536SAndroid Build Coastguard Worker pSfmSbrVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2);
242*e5436536SAndroid Build Coastguard Worker
243*e5436536SAndroid Build Coastguard Worker if (lu - ll > 1) {
244*e5436536SAndroid Build Coastguard Worker FIXP_DBL amOrig, amTransp, gmOrig, gmTransp, sfmOrig, sfmTransp;
245*e5436536SAndroid Build Coastguard Worker invBands = GetInvInt(lu - ll);
246*e5436536SAndroid Build Coastguard Worker shiftFacSum0 = 0;
247*e5436536SAndroid Build Coastguard Worker shiftFacSum1 = 0;
248*e5436536SAndroid Build Coastguard Worker amOrig = amTransp = FL2FXCONST_DBL(0.0f);
249*e5436536SAndroid Build Coastguard Worker gmOrig = gmTransp = (FIXP_DBL)MAXVAL_DBL;
250*e5436536SAndroid Build Coastguard Worker
251*e5436536SAndroid Build Coastguard Worker for (j = ll; j < lu; j++) {
252*e5436536SAndroid Build Coastguard Worker sfmOrig = pQuotaBuffer[j];
253*e5436536SAndroid Build Coastguard Worker sfmTransp = pQuotaBuffer[indexVector[j]];
254*e5436536SAndroid Build Coastguard Worker
255*e5436536SAndroid Build Coastguard Worker amOrig += fMult(sfmOrig, invBands);
256*e5436536SAndroid Build Coastguard Worker amTransp += fMult(sfmTransp, invBands);
257*e5436536SAndroid Build Coastguard Worker
258*e5436536SAndroid Build Coastguard Worker shiftFac0 = CountLeadingBits(sfmOrig);
259*e5436536SAndroid Build Coastguard Worker shiftFac1 = CountLeadingBits(sfmTransp);
260*e5436536SAndroid Build Coastguard Worker
261*e5436536SAndroid Build Coastguard Worker gmOrig = fMult(gmOrig, sfmOrig << shiftFac0);
262*e5436536SAndroid Build Coastguard Worker gmTransp = fMult(gmTransp, sfmTransp << shiftFac1);
263*e5436536SAndroid Build Coastguard Worker
264*e5436536SAndroid Build Coastguard Worker shiftFacSum0 += shiftFac0;
265*e5436536SAndroid Build Coastguard Worker shiftFacSum1 += shiftFac1;
266*e5436536SAndroid Build Coastguard Worker }
267*e5436536SAndroid Build Coastguard Worker
268*e5436536SAndroid Build Coastguard Worker if (gmOrig > FL2FXCONST_DBL(0.0f)) {
269*e5436536SAndroid Build Coastguard Worker tmp1 = CalcLdData(gmOrig); /* CalcLd64(x)/64 */
270*e5436536SAndroid Build Coastguard Worker tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */
271*e5436536SAndroid Build Coastguard Worker
272*e5436536SAndroid Build Coastguard Worker /* y*k/64 */
273*e5436536SAndroid Build Coastguard Worker accu = (FIXP_DBL)-shiftFacSum0 << (DFRACT_BITS - 1 - 8);
274*e5436536SAndroid Build Coastguard Worker tmp2 = fMultDiv2(invBands, accu) << (2 + 1);
275*e5436536SAndroid Build Coastguard Worker
276*e5436536SAndroid Build Coastguard Worker tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */
277*e5436536SAndroid Build Coastguard Worker gmOrig = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */
278*e5436536SAndroid Build Coastguard Worker } else {
279*e5436536SAndroid Build Coastguard Worker gmOrig = FL2FXCONST_DBL(0.0f);
280*e5436536SAndroid Build Coastguard Worker }
281*e5436536SAndroid Build Coastguard Worker
282*e5436536SAndroid Build Coastguard Worker if (gmTransp > FL2FXCONST_DBL(0.0f)) {
283*e5436536SAndroid Build Coastguard Worker tmp1 = CalcLdData(gmTransp); /* CalcLd64(x)/64 */
284*e5436536SAndroid Build Coastguard Worker tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */
285*e5436536SAndroid Build Coastguard Worker
286*e5436536SAndroid Build Coastguard Worker /* y*k/64 */
287*e5436536SAndroid Build Coastguard Worker accu = (FIXP_DBL)-shiftFacSum1 << (DFRACT_BITS - 1 - 8);
288*e5436536SAndroid Build Coastguard Worker tmp2 = fMultDiv2(invBands, accu) << (2 + 1);
289*e5436536SAndroid Build Coastguard Worker
290*e5436536SAndroid Build Coastguard Worker tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */
291*e5436536SAndroid Build Coastguard Worker gmTransp = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */
292*e5436536SAndroid Build Coastguard Worker } else {
293*e5436536SAndroid Build Coastguard Worker gmTransp = FL2FXCONST_DBL(0.0f);
294*e5436536SAndroid Build Coastguard Worker }
295*e5436536SAndroid Build Coastguard Worker if (amOrig != FL2FXCONST_DBL(0.0f))
296*e5436536SAndroid Build Coastguard Worker pSfmOrigVec[i] =
297*e5436536SAndroid Build Coastguard Worker FDKsbrEnc_LSI_divide_scale_fract(gmOrig, amOrig, SFM_SCALE);
298*e5436536SAndroid Build Coastguard Worker
299*e5436536SAndroid Build Coastguard Worker if (amTransp != FL2FXCONST_DBL(0.0f))
300*e5436536SAndroid Build Coastguard Worker pSfmSbrVec[i] =
301*e5436536SAndroid Build Coastguard Worker FDKsbrEnc_LSI_divide_scale_fract(gmTransp, amTransp, SFM_SCALE);
302*e5436536SAndroid Build Coastguard Worker }
303*e5436536SAndroid Build Coastguard Worker }
304*e5436536SAndroid Build Coastguard Worker }
305*e5436536SAndroid Build Coastguard Worker
306*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
307*e5436536SAndroid Build Coastguard Worker /*!
308*e5436536SAndroid Build Coastguard Worker \brief Calculates the input to the missing harmonics detection.
309*e5436536SAndroid Build Coastguard Worker
310*e5436536SAndroid Build Coastguard Worker
311*e5436536SAndroid Build Coastguard Worker \return none.
312*e5436536SAndroid Build Coastguard Worker
313*e5436536SAndroid Build Coastguard Worker */
314*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
calculateDetectorInput(FIXP_DBL ** RESTRICT pQuotaBuffer,SCHAR * RESTRICT indexVector,FIXP_DBL ** RESTRICT tonalityDiff,FIXP_DBL ** RESTRICT pSfmOrig,FIXP_DBL ** RESTRICT pSfmSbr,const UCHAR * freqBandTable,INT nSfb,INT noEstPerFrame,INT move)315*e5436536SAndroid Build Coastguard Worker static void calculateDetectorInput(
316*e5436536SAndroid Build Coastguard Worker FIXP_DBL **RESTRICT pQuotaBuffer, /*!< Pointer to tonality matrix. */
317*e5436536SAndroid Build Coastguard Worker SCHAR *RESTRICT indexVector, FIXP_DBL **RESTRICT tonalityDiff,
318*e5436536SAndroid Build Coastguard Worker FIXP_DBL **RESTRICT pSfmOrig, FIXP_DBL **RESTRICT pSfmSbr,
319*e5436536SAndroid Build Coastguard Worker const UCHAR *freqBandTable, INT nSfb, INT noEstPerFrame, INT move) {
320*e5436536SAndroid Build Coastguard Worker INT est;
321*e5436536SAndroid Build Coastguard Worker
322*e5436536SAndroid Build Coastguard Worker /*
323*e5436536SAndroid Build Coastguard Worker New estimate.
324*e5436536SAndroid Build Coastguard Worker */
325*e5436536SAndroid Build Coastguard Worker for (est = 0; est < noEstPerFrame; est++) {
326*e5436536SAndroid Build Coastguard Worker diff(pQuotaBuffer[est + move], tonalityDiff[est + move], freqBandTable,
327*e5436536SAndroid Build Coastguard Worker nSfb, indexVector);
328*e5436536SAndroid Build Coastguard Worker
329*e5436536SAndroid Build Coastguard Worker calculateFlatnessMeasure(pQuotaBuffer[est + move], indexVector,
330*e5436536SAndroid Build Coastguard Worker pSfmOrig[est + move], pSfmSbr[est + move],
331*e5436536SAndroid Build Coastguard Worker freqBandTable, nSfb);
332*e5436536SAndroid Build Coastguard Worker }
333*e5436536SAndroid Build Coastguard Worker }
334*e5436536SAndroid Build Coastguard Worker
335*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
336*e5436536SAndroid Build Coastguard Worker /*!
337*e5436536SAndroid Build Coastguard Worker \brief Checks that the detection is not due to a LP filter
338*e5436536SAndroid Build Coastguard Worker
339*e5436536SAndroid Build Coastguard Worker This function determines if a newly detected missing harmonics is not
340*e5436536SAndroid Build Coastguard Worker in fact just a low-pass filtere input signal. If so, the detection is
341*e5436536SAndroid Build Coastguard Worker removed.
342*e5436536SAndroid Build Coastguard Worker
343*e5436536SAndroid Build Coastguard Worker \return none.
344*e5436536SAndroid Build Coastguard Worker
345*e5436536SAndroid Build Coastguard Worker */
346*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
removeLowPassDetection(UCHAR * RESTRICT pAddHarmSfb,UCHAR ** RESTRICT pDetectionVectors,INT start,INT stop,INT nSfb,const UCHAR * RESTRICT pFreqBandTable,FIXP_DBL * RESTRICT pNrgVector,THRES_HOLDS mhThresh)347*e5436536SAndroid Build Coastguard Worker static void removeLowPassDetection(UCHAR *RESTRICT pAddHarmSfb,
348*e5436536SAndroid Build Coastguard Worker UCHAR **RESTRICT pDetectionVectors,
349*e5436536SAndroid Build Coastguard Worker INT start, INT stop, INT nSfb,
350*e5436536SAndroid Build Coastguard Worker const UCHAR *RESTRICT pFreqBandTable,
351*e5436536SAndroid Build Coastguard Worker FIXP_DBL *RESTRICT pNrgVector,
352*e5436536SAndroid Build Coastguard Worker THRES_HOLDS mhThresh)
353*e5436536SAndroid Build Coastguard Worker
354*e5436536SAndroid Build Coastguard Worker {
355*e5436536SAndroid Build Coastguard Worker INT i, est;
356*e5436536SAndroid Build Coastguard Worker INT maxDerivPos = pFreqBandTable[nSfb];
357*e5436536SAndroid Build Coastguard Worker INT numBands = pFreqBandTable[nSfb];
358*e5436536SAndroid Build Coastguard Worker FIXP_DBL nrgLow, nrgHigh;
359*e5436536SAndroid Build Coastguard Worker FIXP_DBL nrgLD64, nrgLowLD64, nrgHighLD64, nrgDiffLD64;
360*e5436536SAndroid Build Coastguard Worker FIXP_DBL valLD64, maxValLD64, maxValAboveLD64;
361*e5436536SAndroid Build Coastguard Worker INT bLPsignal = 0;
362*e5436536SAndroid Build Coastguard Worker
363*e5436536SAndroid Build Coastguard Worker maxValLD64 = FL2FXCONST_DBL(-1.0f);
364*e5436536SAndroid Build Coastguard Worker for (i = numBands - 1 - 2; i > pFreqBandTable[0]; i--) {
365*e5436536SAndroid Build Coastguard Worker nrgLow = pNrgVector[i];
366*e5436536SAndroid Build Coastguard Worker nrgHigh = pNrgVector[i + 2];
367*e5436536SAndroid Build Coastguard Worker
368*e5436536SAndroid Build Coastguard Worker if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) {
369*e5436536SAndroid Build Coastguard Worker nrgLowLD64 = CalcLdData(nrgLow >> 1);
370*e5436536SAndroid Build Coastguard Worker nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1));
371*e5436536SAndroid Build Coastguard Worker valLD64 = nrgDiffLD64 - nrgLowLD64;
372*e5436536SAndroid Build Coastguard Worker if (valLD64 > maxValLD64) {
373*e5436536SAndroid Build Coastguard Worker maxDerivPos = i;
374*e5436536SAndroid Build Coastguard Worker maxValLD64 = valLD64;
375*e5436536SAndroid Build Coastguard Worker }
376*e5436536SAndroid Build Coastguard Worker if (maxValLD64 > mhThresh.derivThresMaxLD64) {
377*e5436536SAndroid Build Coastguard Worker break;
378*e5436536SAndroid Build Coastguard Worker }
379*e5436536SAndroid Build Coastguard Worker }
380*e5436536SAndroid Build Coastguard Worker }
381*e5436536SAndroid Build Coastguard Worker
382*e5436536SAndroid Build Coastguard Worker /* Find the largest "gradient" above. (should be relatively flat, hence we
383*e5436536SAndroid Build Coastguard Worker expect a low value if the signal is LP.*/
384*e5436536SAndroid Build Coastguard Worker maxValAboveLD64 = FL2FXCONST_DBL(-1.0f);
385*e5436536SAndroid Build Coastguard Worker for (i = numBands - 1 - 2; i > maxDerivPos + 2; i--) {
386*e5436536SAndroid Build Coastguard Worker nrgLow = pNrgVector[i];
387*e5436536SAndroid Build Coastguard Worker nrgHigh = pNrgVector[i + 2];
388*e5436536SAndroid Build Coastguard Worker
389*e5436536SAndroid Build Coastguard Worker if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) {
390*e5436536SAndroid Build Coastguard Worker nrgLowLD64 = CalcLdData(nrgLow >> 1);
391*e5436536SAndroid Build Coastguard Worker nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1));
392*e5436536SAndroid Build Coastguard Worker valLD64 = nrgDiffLD64 - nrgLowLD64;
393*e5436536SAndroid Build Coastguard Worker if (valLD64 > maxValAboveLD64) {
394*e5436536SAndroid Build Coastguard Worker maxValAboveLD64 = valLD64;
395*e5436536SAndroid Build Coastguard Worker }
396*e5436536SAndroid Build Coastguard Worker } else {
397*e5436536SAndroid Build Coastguard Worker if (nrgHigh != FL2FXCONST_DBL(0.0f) && nrgHigh > nrgLow) {
398*e5436536SAndroid Build Coastguard Worker nrgHighLD64 = CalcLdData(nrgHigh >> 1);
399*e5436536SAndroid Build Coastguard Worker nrgDiffLD64 = CalcLdData((nrgHigh >> 1) - (nrgLow >> 1));
400*e5436536SAndroid Build Coastguard Worker valLD64 = nrgDiffLD64 - nrgHighLD64;
401*e5436536SAndroid Build Coastguard Worker if (valLD64 > maxValAboveLD64) {
402*e5436536SAndroid Build Coastguard Worker maxValAboveLD64 = valLD64;
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
408*e5436536SAndroid Build Coastguard Worker if (maxValLD64 > mhThresh.derivThresMaxLD64 &&
409*e5436536SAndroid Build Coastguard Worker maxValAboveLD64 < mhThresh.derivThresAboveLD64) {
410*e5436536SAndroid Build Coastguard Worker bLPsignal = 1;
411*e5436536SAndroid Build Coastguard Worker
412*e5436536SAndroid Build Coastguard Worker for (i = maxDerivPos - 1; i > maxDerivPos - 5 && i >= 0; i--) {
413*e5436536SAndroid Build Coastguard Worker if (pNrgVector[i] != FL2FXCONST_DBL(0.0f) &&
414*e5436536SAndroid Build Coastguard Worker pNrgVector[i] > pNrgVector[maxDerivPos + 2]) {
415*e5436536SAndroid Build Coastguard Worker nrgDiffLD64 = CalcLdData((pNrgVector[i] >> 1) -
416*e5436536SAndroid Build Coastguard Worker (pNrgVector[maxDerivPos + 2] >> 1));
417*e5436536SAndroid Build Coastguard Worker nrgLD64 = CalcLdData(pNrgVector[i] >> 1);
418*e5436536SAndroid Build Coastguard Worker valLD64 = nrgDiffLD64 - nrgLD64;
419*e5436536SAndroid Build Coastguard Worker if (valLD64 < mhThresh.derivThresBelowLD64) {
420*e5436536SAndroid Build Coastguard Worker bLPsignal = 0;
421*e5436536SAndroid Build Coastguard Worker break;
422*e5436536SAndroid Build Coastguard Worker }
423*e5436536SAndroid Build Coastguard Worker } else {
424*e5436536SAndroid Build Coastguard Worker bLPsignal = 0;
425*e5436536SAndroid Build Coastguard Worker break;
426*e5436536SAndroid Build Coastguard Worker }
427*e5436536SAndroid Build Coastguard Worker }
428*e5436536SAndroid Build Coastguard Worker }
429*e5436536SAndroid Build Coastguard Worker
430*e5436536SAndroid Build Coastguard Worker if (bLPsignal) {
431*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
432*e5436536SAndroid Build Coastguard Worker if (maxDerivPos >= pFreqBandTable[i] &&
433*e5436536SAndroid Build Coastguard Worker maxDerivPos < pFreqBandTable[i + 1])
434*e5436536SAndroid Build Coastguard Worker break;
435*e5436536SAndroid Build Coastguard Worker }
436*e5436536SAndroid Build Coastguard Worker
437*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[i]) {
438*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i] = 0;
439*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
440*e5436536SAndroid Build Coastguard Worker pDetectionVectors[est][i] = 0;
441*e5436536SAndroid Build Coastguard Worker }
442*e5436536SAndroid Build Coastguard Worker }
443*e5436536SAndroid Build Coastguard Worker }
444*e5436536SAndroid Build Coastguard Worker }
445*e5436536SAndroid Build Coastguard Worker
446*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
447*e5436536SAndroid Build Coastguard Worker /*!
448*e5436536SAndroid Build Coastguard Worker \brief Checks if it is allowed to detect a missing tone, that wasn't
449*e5436536SAndroid Build Coastguard Worker detected previously.
450*e5436536SAndroid Build Coastguard Worker
451*e5436536SAndroid Build Coastguard Worker
452*e5436536SAndroid Build Coastguard Worker \return newDetectionAllowed flag.
453*e5436536SAndroid Build Coastguard Worker
454*e5436536SAndroid Build Coastguard Worker */
455*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
isDetectionOfNewToneAllowed(const SBR_FRAME_INFO * pFrameInfo,INT * pDetectionStartPos,INT noEstPerFrame,INT prevTransientFrame,INT prevTransientPos,INT prevTransientFlag,INT transientPosOffset,INT transientFlag,INT transientPos,INT deltaTime,HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector)456*e5436536SAndroid Build Coastguard Worker static INT isDetectionOfNewToneAllowed(
457*e5436536SAndroid Build Coastguard Worker const SBR_FRAME_INFO *pFrameInfo, INT *pDetectionStartPos,
458*e5436536SAndroid Build Coastguard Worker INT noEstPerFrame, INT prevTransientFrame, INT prevTransientPos,
459*e5436536SAndroid Build Coastguard Worker INT prevTransientFlag, INT transientPosOffset, INT transientFlag,
460*e5436536SAndroid Build Coastguard Worker INT transientPos, INT deltaTime,
461*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector) {
462*e5436536SAndroid Build Coastguard Worker INT transientFrame, newDetectionAllowed;
463*e5436536SAndroid Build Coastguard Worker
464*e5436536SAndroid Build Coastguard Worker /* Determine if this is a frame where a transient starts...
465*e5436536SAndroid Build Coastguard Worker * If the transient flag was set the previous frame but not the
466*e5436536SAndroid Build Coastguard Worker * transient frame flag, the transient frame flag is set in the current frame.
467*e5436536SAndroid Build Coastguard Worker *****************************************************************************/
468*e5436536SAndroid Build Coastguard Worker transientFrame = 0;
469*e5436536SAndroid Build Coastguard Worker if (transientFlag) {
470*e5436536SAndroid Build Coastguard Worker if (transientPos + transientPosOffset <
471*e5436536SAndroid Build Coastguard Worker pFrameInfo->borders[pFrameInfo->nEnvelopes]) {
472*e5436536SAndroid Build Coastguard Worker transientFrame = 1;
473*e5436536SAndroid Build Coastguard Worker if (noEstPerFrame > 1) {
474*e5436536SAndroid Build Coastguard Worker if (transientPos + transientPosOffset >
475*e5436536SAndroid Build Coastguard Worker h_sbrMissingHarmonicsDetector->timeSlots >> 1) {
476*e5436536SAndroid Build Coastguard Worker *pDetectionStartPos = noEstPerFrame;
477*e5436536SAndroid Build Coastguard Worker } else {
478*e5436536SAndroid Build Coastguard Worker *pDetectionStartPos = noEstPerFrame >> 1;
479*e5436536SAndroid Build Coastguard Worker }
480*e5436536SAndroid Build Coastguard Worker
481*e5436536SAndroid Build Coastguard Worker } else {
482*e5436536SAndroid Build Coastguard Worker *pDetectionStartPos = noEstPerFrame;
483*e5436536SAndroid Build Coastguard Worker }
484*e5436536SAndroid Build Coastguard Worker }
485*e5436536SAndroid Build Coastguard Worker } else {
486*e5436536SAndroid Build Coastguard Worker if (prevTransientFlag && !prevTransientFrame) {
487*e5436536SAndroid Build Coastguard Worker transientFrame = 1;
488*e5436536SAndroid Build Coastguard Worker *pDetectionStartPos = 0;
489*e5436536SAndroid Build Coastguard Worker }
490*e5436536SAndroid Build Coastguard Worker }
491*e5436536SAndroid Build Coastguard Worker
492*e5436536SAndroid Build Coastguard Worker /*
493*e5436536SAndroid Build Coastguard Worker * Determine if detection of new missing harmonics are allowed.
494*e5436536SAndroid Build Coastguard Worker * If the frame contains a transient it's ok. If the previous
495*e5436536SAndroid Build Coastguard Worker * frame contained a transient it needs to be sufficiently close
496*e5436536SAndroid Build Coastguard Worker * to the start of the current frame.
497*e5436536SAndroid Build Coastguard Worker ****************************************************************/
498*e5436536SAndroid Build Coastguard Worker newDetectionAllowed = 0;
499*e5436536SAndroid Build Coastguard Worker if (transientFrame) {
500*e5436536SAndroid Build Coastguard Worker newDetectionAllowed = 1;
501*e5436536SAndroid Build Coastguard Worker } else {
502*e5436536SAndroid Build Coastguard Worker if (prevTransientFrame &&
503*e5436536SAndroid Build Coastguard Worker fixp_abs(pFrameInfo->borders[0] -
504*e5436536SAndroid Build Coastguard Worker (prevTransientPos + transientPosOffset -
505*e5436536SAndroid Build Coastguard Worker h_sbrMissingHarmonicsDetector->timeSlots)) < deltaTime) {
506*e5436536SAndroid Build Coastguard Worker newDetectionAllowed = 1;
507*e5436536SAndroid Build Coastguard Worker *pDetectionStartPos = 0;
508*e5436536SAndroid Build Coastguard Worker }
509*e5436536SAndroid Build Coastguard Worker }
510*e5436536SAndroid Build Coastguard Worker
511*e5436536SAndroid Build Coastguard Worker h_sbrMissingHarmonicsDetector->previousTransientFlag = transientFlag;
512*e5436536SAndroid Build Coastguard Worker h_sbrMissingHarmonicsDetector->previousTransientFrame = transientFrame;
513*e5436536SAndroid Build Coastguard Worker h_sbrMissingHarmonicsDetector->previousTransientPos = transientPos;
514*e5436536SAndroid Build Coastguard Worker
515*e5436536SAndroid Build Coastguard Worker return (newDetectionAllowed);
516*e5436536SAndroid Build Coastguard Worker }
517*e5436536SAndroid Build Coastguard Worker
518*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
519*e5436536SAndroid Build Coastguard Worker /*!
520*e5436536SAndroid Build Coastguard Worker \brief Cleans up the detection after a transient.
521*e5436536SAndroid Build Coastguard Worker
522*e5436536SAndroid Build Coastguard Worker
523*e5436536SAndroid Build Coastguard Worker \return none.
524*e5436536SAndroid Build Coastguard Worker
525*e5436536SAndroid Build Coastguard Worker */
526*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
transientCleanUp(FIXP_DBL ** quotaBuffer,INT nSfb,UCHAR ** detectionVectors,UCHAR * pAddHarmSfb,UCHAR * pPrevAddHarmSfb,INT ** signBuffer,const UCHAR * pFreqBandTable,INT start,INT stop,INT newDetectionAllowed,FIXP_DBL * pNrgVector,THRES_HOLDS mhThresh)527*e5436536SAndroid Build Coastguard Worker static void transientCleanUp(FIXP_DBL **quotaBuffer, INT nSfb,
528*e5436536SAndroid Build Coastguard Worker UCHAR **detectionVectors, UCHAR *pAddHarmSfb,
529*e5436536SAndroid Build Coastguard Worker UCHAR *pPrevAddHarmSfb, INT **signBuffer,
530*e5436536SAndroid Build Coastguard Worker const UCHAR *pFreqBandTable, INT start, INT stop,
531*e5436536SAndroid Build Coastguard Worker INT newDetectionAllowed, FIXP_DBL *pNrgVector,
532*e5436536SAndroid Build Coastguard Worker THRES_HOLDS mhThresh) {
533*e5436536SAndroid Build Coastguard Worker INT i, j, est;
534*e5436536SAndroid Build Coastguard Worker
535*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
536*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
537*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i] = pAddHarmSfb[i] || detectionVectors[est][i];
538*e5436536SAndroid Build Coastguard Worker }
539*e5436536SAndroid Build Coastguard Worker }
540*e5436536SAndroid Build Coastguard Worker
541*e5436536SAndroid Build Coastguard Worker if (newDetectionAllowed == 1) {
542*e5436536SAndroid Build Coastguard Worker /*
543*e5436536SAndroid Build Coastguard Worker * Check for duplication of sines located
544*e5436536SAndroid Build Coastguard Worker * on the border of two scf-bands.
545*e5436536SAndroid Build Coastguard Worker *************************************************/
546*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb - 1; i++) {
547*e5436536SAndroid Build Coastguard Worker /* detection in adjacent channels.*/
548*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[i] && pAddHarmSfb[i + 1]) {
549*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxVal1, maxVal2;
550*e5436536SAndroid Build Coastguard Worker INT maxPos1, maxPos2, maxPosTime1, maxPosTime2;
551*e5436536SAndroid Build Coastguard Worker
552*e5436536SAndroid Build Coastguard Worker INT li = pFreqBandTable[i];
553*e5436536SAndroid Build Coastguard Worker INT ui = pFreqBandTable[i + 1];
554*e5436536SAndroid Build Coastguard Worker
555*e5436536SAndroid Build Coastguard Worker /* Find maximum tonality in the the two scf bands.*/
556*e5436536SAndroid Build Coastguard Worker maxPosTime1 = start;
557*e5436536SAndroid Build Coastguard Worker maxPos1 = li;
558*e5436536SAndroid Build Coastguard Worker maxVal1 = quotaBuffer[start][li];
559*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
560*e5436536SAndroid Build Coastguard Worker for (j = li; j < ui; j++) {
561*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[est][j] > maxVal1) {
562*e5436536SAndroid Build Coastguard Worker maxVal1 = quotaBuffer[est][j];
563*e5436536SAndroid Build Coastguard Worker maxPos1 = j;
564*e5436536SAndroid Build Coastguard Worker maxPosTime1 = est;
565*e5436536SAndroid Build Coastguard Worker }
566*e5436536SAndroid Build Coastguard Worker }
567*e5436536SAndroid Build Coastguard Worker }
568*e5436536SAndroid Build Coastguard Worker
569*e5436536SAndroid Build Coastguard Worker li = pFreqBandTable[i + 1];
570*e5436536SAndroid Build Coastguard Worker ui = pFreqBandTable[i + 2];
571*e5436536SAndroid Build Coastguard Worker
572*e5436536SAndroid Build Coastguard Worker /* Find maximum tonality in the the two scf bands.*/
573*e5436536SAndroid Build Coastguard Worker maxPosTime2 = start;
574*e5436536SAndroid Build Coastguard Worker maxPos2 = li;
575*e5436536SAndroid Build Coastguard Worker maxVal2 = quotaBuffer[start][li];
576*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
577*e5436536SAndroid Build Coastguard Worker for (j = li; j < ui; j++) {
578*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[est][j] > maxVal2) {
579*e5436536SAndroid Build Coastguard Worker maxVal2 = quotaBuffer[est][j];
580*e5436536SAndroid Build Coastguard Worker maxPos2 = j;
581*e5436536SAndroid Build Coastguard Worker maxPosTime2 = est;
582*e5436536SAndroid Build Coastguard Worker }
583*e5436536SAndroid Build Coastguard Worker }
584*e5436536SAndroid Build Coastguard Worker }
585*e5436536SAndroid Build Coastguard Worker
586*e5436536SAndroid Build Coastguard Worker /* If the maximum values are in adjacent QMF-channels, we need to remove
587*e5436536SAndroid Build Coastguard Worker the lowest of the two.*/
588*e5436536SAndroid Build Coastguard Worker if (maxPos2 - maxPos1 < 2) {
589*e5436536SAndroid Build Coastguard Worker if (pPrevAddHarmSfb[i] == 1 && pPrevAddHarmSfb[i + 1] == 0) {
590*e5436536SAndroid Build Coastguard Worker /* Keep the lower, remove the upper.*/
591*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i + 1] = 0;
592*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
593*e5436536SAndroid Build Coastguard Worker detectionVectors[est][i + 1] = 0;
594*e5436536SAndroid Build Coastguard Worker }
595*e5436536SAndroid Build Coastguard Worker } else {
596*e5436536SAndroid Build Coastguard Worker if (pPrevAddHarmSfb[i] == 0 && pPrevAddHarmSfb[i + 1] == 1) {
597*e5436536SAndroid Build Coastguard Worker /* Keep the upper, remove the lower.*/
598*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i] = 0;
599*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
600*e5436536SAndroid Build Coastguard Worker detectionVectors[est][i] = 0;
601*e5436536SAndroid Build Coastguard Worker }
602*e5436536SAndroid Build Coastguard Worker } else {
603*e5436536SAndroid Build Coastguard Worker /* If the maximum values are in adjacent QMF-channels, and if the
604*e5436536SAndroid Build Coastguard Worker signs indicate that it is the same sine, we need to remove the
605*e5436536SAndroid Build Coastguard Worker lowest of the two.*/
606*e5436536SAndroid Build Coastguard Worker if (maxVal1 > maxVal2) {
607*e5436536SAndroid Build Coastguard Worker if (signBuffer[maxPosTime1][maxPos2] < 0 &&
608*e5436536SAndroid Build Coastguard Worker signBuffer[maxPosTime1][maxPos1] > 0) {
609*e5436536SAndroid Build Coastguard Worker /* Keep the lower, remove the upper.*/
610*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i + 1] = 0;
611*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
612*e5436536SAndroid Build Coastguard Worker detectionVectors[est][i + 1] = 0;
613*e5436536SAndroid Build Coastguard Worker }
614*e5436536SAndroid Build Coastguard Worker }
615*e5436536SAndroid Build Coastguard Worker } else {
616*e5436536SAndroid Build Coastguard Worker if (signBuffer[maxPosTime2][maxPos2] < 0 &&
617*e5436536SAndroid Build Coastguard Worker signBuffer[maxPosTime2][maxPos1] > 0) {
618*e5436536SAndroid Build Coastguard Worker /* Keep the upper, remove the lower.*/
619*e5436536SAndroid Build Coastguard Worker pAddHarmSfb[i] = 0;
620*e5436536SAndroid Build Coastguard Worker for (est = start; est < stop; est++) {
621*e5436536SAndroid Build Coastguard Worker detectionVectors[est][i] = 0;
622*e5436536SAndroid Build Coastguard Worker }
623*e5436536SAndroid Build Coastguard Worker }
624*e5436536SAndroid Build Coastguard Worker }
625*e5436536SAndroid Build Coastguard Worker }
626*e5436536SAndroid Build Coastguard Worker }
627*e5436536SAndroid Build Coastguard Worker }
628*e5436536SAndroid Build Coastguard Worker }
629*e5436536SAndroid Build Coastguard Worker }
630*e5436536SAndroid Build Coastguard Worker
631*e5436536SAndroid Build Coastguard Worker /* Make sure that the detection is not the cut-off of a low pass filter. */
632*e5436536SAndroid Build Coastguard Worker removeLowPassDetection(pAddHarmSfb, detectionVectors, start, stop, nSfb,
633*e5436536SAndroid Build Coastguard Worker pFreqBandTable, pNrgVector, mhThresh);
634*e5436536SAndroid Build Coastguard Worker } else {
635*e5436536SAndroid Build Coastguard Worker /*
636*e5436536SAndroid Build Coastguard Worker * If a missing harmonic wasn't missing the previous frame
637*e5436536SAndroid Build Coastguard Worker * the transient-flag needs to be set in order to be allowed to detect it.
638*e5436536SAndroid Build Coastguard Worker *************************************************************************/
639*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
640*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[i] - pPrevAddHarmSfb[i] > 0) pAddHarmSfb[i] = 0;
641*e5436536SAndroid Build Coastguard Worker }
642*e5436536SAndroid Build Coastguard Worker }
643*e5436536SAndroid Build Coastguard Worker }
644*e5436536SAndroid Build Coastguard Worker
645*e5436536SAndroid Build Coastguard Worker /*****************************************************************************/
646*e5436536SAndroid Build Coastguard Worker /*!
647*e5436536SAndroid Build Coastguard Worker \brief Detection for one tonality estimate.
648*e5436536SAndroid Build Coastguard Worker
649*e5436536SAndroid Build Coastguard Worker This is the actual missing harmonics detection, using information from the
650*e5436536SAndroid Build Coastguard Worker previous detection.
651*e5436536SAndroid Build Coastguard Worker
652*e5436536SAndroid Build Coastguard Worker If a missing harmonic was detected (in a previous frame) due to too high
653*e5436536SAndroid Build Coastguard Worker tonality differences, but there was not enough tonality difference in the
654*e5436536SAndroid Build Coastguard Worker current frame, the detection algorithm still continues to trace the strongest
655*e5436536SAndroid Build Coastguard Worker tone in the scalefactor band (assuming that this is the tone that is going to
656*e5436536SAndroid Build Coastguard Worker be replaced in the decoder). This is done to avoid abrupt endings of sines
657*e5436536SAndroid Build Coastguard Worker fading out (e.g. in the glockenspiel).
658*e5436536SAndroid Build Coastguard Worker
659*e5436536SAndroid Build Coastguard Worker The function also tries to estimate where one sine is going to be replaced
660*e5436536SAndroid Build Coastguard Worker with multiple sines (due to the patching). This is done by comparing the
661*e5436536SAndroid Build Coastguard Worker tonality flatness measure of the original and the SBR signal.
662*e5436536SAndroid Build Coastguard Worker
663*e5436536SAndroid Build Coastguard Worker The function also tries to estimate (for the scalefactor bands only
664*e5436536SAndroid Build Coastguard Worker containing one qmf subband) when a strong tone in the original will be
665*e5436536SAndroid Build Coastguard Worker replaced by a strong tone in the adjacent QMF subband.
666*e5436536SAndroid Build Coastguard Worker
667*e5436536SAndroid Build Coastguard Worker \return none.
668*e5436536SAndroid Build Coastguard Worker
669*e5436536SAndroid Build Coastguard Worker */
670*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
detection(FIXP_DBL * quotaBuffer,FIXP_DBL * pDiffVecScfb,INT nSfb,UCHAR * pHarmVec,const UCHAR * pFreqBandTable,FIXP_DBL * sfmOrig,FIXP_DBL * sfmSbr,GUIDE_VECTORS guideVectors,GUIDE_VECTORS newGuideVectors,THRES_HOLDS mhThresh)671*e5436536SAndroid Build Coastguard Worker static void detection(FIXP_DBL *quotaBuffer, FIXP_DBL *pDiffVecScfb, INT nSfb,
672*e5436536SAndroid Build Coastguard Worker UCHAR *pHarmVec, const UCHAR *pFreqBandTable,
673*e5436536SAndroid Build Coastguard Worker FIXP_DBL *sfmOrig, FIXP_DBL *sfmSbr,
674*e5436536SAndroid Build Coastguard Worker GUIDE_VECTORS guideVectors, GUIDE_VECTORS newGuideVectors,
675*e5436536SAndroid Build Coastguard Worker THRES_HOLDS mhThresh) {
676*e5436536SAndroid Build Coastguard Worker INT i, j, ll, lu;
677*e5436536SAndroid Build Coastguard Worker FIXP_DBL thresTemp, thresOrig;
678*e5436536SAndroid Build Coastguard Worker
679*e5436536SAndroid Build Coastguard Worker /*
680*e5436536SAndroid Build Coastguard Worker * Do detection on the difference vector, i.e. the difference between
681*e5436536SAndroid Build Coastguard Worker * the original and the transposed.
682*e5436536SAndroid Build Coastguard Worker *********************************************************************/
683*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
684*e5436536SAndroid Build Coastguard Worker thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
685*e5436536SAndroid Build Coastguard Worker ? fMax(fMult(mhThresh.decayGuideDiff,
686*e5436536SAndroid Build Coastguard Worker guideVectors.guideVectorDiff[i]),
687*e5436536SAndroid Build Coastguard Worker mhThresh.thresHoldDiffGuide)
688*e5436536SAndroid Build Coastguard Worker : mhThresh.thresHoldDiff;
689*e5436536SAndroid Build Coastguard Worker
690*e5436536SAndroid Build Coastguard Worker thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff);
691*e5436536SAndroid Build Coastguard Worker
692*e5436536SAndroid Build Coastguard Worker if (pDiffVecScfb[i] > thresTemp) {
693*e5436536SAndroid Build Coastguard Worker pHarmVec[i] = 1;
694*e5436536SAndroid Build Coastguard Worker newGuideVectors.guideVectorDiff[i] = pDiffVecScfb[i];
695*e5436536SAndroid Build Coastguard Worker } else {
696*e5436536SAndroid Build Coastguard Worker /* If the guide wasn't zero, but the current level is to low,
697*e5436536SAndroid Build Coastguard Worker start tracking the decay on the tone in the original rather
698*e5436536SAndroid Build Coastguard Worker than the difference.*/
699*e5436536SAndroid Build Coastguard Worker if (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) {
700*e5436536SAndroid Build Coastguard Worker guideVectors.guideVectorOrig[i] = mhThresh.thresHoldToneGuide;
701*e5436536SAndroid Build Coastguard Worker }
702*e5436536SAndroid Build Coastguard Worker }
703*e5436536SAndroid Build Coastguard Worker }
704*e5436536SAndroid Build Coastguard Worker
705*e5436536SAndroid Build Coastguard Worker /*
706*e5436536SAndroid Build Coastguard Worker * Trace tones in the original signal that at one point
707*e5436536SAndroid Build Coastguard Worker * have been detected because they will be replaced by
708*e5436536SAndroid Build Coastguard Worker * multiple tones in the sbr signal.
709*e5436536SAndroid Build Coastguard Worker ****************************************************/
710*e5436536SAndroid Build Coastguard Worker
711*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
712*e5436536SAndroid Build Coastguard Worker ll = pFreqBandTable[i];
713*e5436536SAndroid Build Coastguard Worker lu = pFreqBandTable[i + 1];
714*e5436536SAndroid Build Coastguard Worker
715*e5436536SAndroid Build Coastguard Worker thresOrig =
716*e5436536SAndroid Build Coastguard Worker fixMax(fMult(guideVectors.guideVectorOrig[i], mhThresh.decayGuideOrig),
717*e5436536SAndroid Build Coastguard Worker mhThresh.thresHoldToneGuide);
718*e5436536SAndroid Build Coastguard Worker thresOrig = fixMin(thresOrig, mhThresh.thresHoldTone);
719*e5436536SAndroid Build Coastguard Worker
720*e5436536SAndroid Build Coastguard Worker if (guideVectors.guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) {
721*e5436536SAndroid Build Coastguard Worker for (j = ll; j < lu; j++) {
722*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[j] > thresOrig) {
723*e5436536SAndroid Build Coastguard Worker pHarmVec[i] = 1;
724*e5436536SAndroid Build Coastguard Worker newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
725*e5436536SAndroid Build Coastguard Worker }
726*e5436536SAndroid Build Coastguard Worker }
727*e5436536SAndroid Build Coastguard Worker }
728*e5436536SAndroid Build Coastguard Worker }
729*e5436536SAndroid Build Coastguard Worker
730*e5436536SAndroid Build Coastguard Worker /*
731*e5436536SAndroid Build Coastguard Worker * Check for multiple sines in the transposed signal,
732*e5436536SAndroid Build Coastguard Worker * where there is only one in the original.
733*e5436536SAndroid Build Coastguard Worker ****************************************************/
734*e5436536SAndroid Build Coastguard Worker thresOrig = mhThresh.thresHoldTone;
735*e5436536SAndroid Build Coastguard Worker
736*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
737*e5436536SAndroid Build Coastguard Worker ll = pFreqBandTable[i];
738*e5436536SAndroid Build Coastguard Worker lu = pFreqBandTable[i + 1];
739*e5436536SAndroid Build Coastguard Worker
740*e5436536SAndroid Build Coastguard Worker if (pHarmVec[i] == 0) {
741*e5436536SAndroid Build Coastguard Worker if (lu - ll > 1) {
742*e5436536SAndroid Build Coastguard Worker for (j = ll; j < lu; j++) {
743*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[j] > thresOrig &&
744*e5436536SAndroid Build Coastguard Worker (sfmSbr[i] > mhThresh.sfmThresSbr &&
745*e5436536SAndroid Build Coastguard Worker sfmOrig[i] < mhThresh.sfmThresOrig)) {
746*e5436536SAndroid Build Coastguard Worker pHarmVec[i] = 1;
747*e5436536SAndroid Build Coastguard Worker newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
748*e5436536SAndroid Build Coastguard Worker }
749*e5436536SAndroid Build Coastguard Worker }
750*e5436536SAndroid Build Coastguard Worker } else {
751*e5436536SAndroid Build Coastguard Worker if (i < nSfb - 1) {
752*e5436536SAndroid Build Coastguard Worker ll = pFreqBandTable[i];
753*e5436536SAndroid Build Coastguard Worker
754*e5436536SAndroid Build Coastguard Worker if (i > 0) {
755*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[ll] > mhThresh.thresHoldTone &&
756*e5436536SAndroid Build Coastguard Worker (pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone ||
757*e5436536SAndroid Build Coastguard Worker pDiffVecScfb[i - 1] < mhThresh.invThresHoldTone)) {
758*e5436536SAndroid Build Coastguard Worker pHarmVec[i] = 1;
759*e5436536SAndroid Build Coastguard Worker newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
760*e5436536SAndroid Build Coastguard Worker }
761*e5436536SAndroid Build Coastguard Worker } else {
762*e5436536SAndroid Build Coastguard Worker if (quotaBuffer[ll] > mhThresh.thresHoldTone &&
763*e5436536SAndroid Build Coastguard Worker pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone) {
764*e5436536SAndroid Build Coastguard Worker pHarmVec[i] = 1;
765*e5436536SAndroid Build Coastguard Worker newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
766*e5436536SAndroid Build Coastguard Worker }
767*e5436536SAndroid Build Coastguard Worker }
768*e5436536SAndroid Build Coastguard Worker }
769*e5436536SAndroid Build Coastguard Worker }
770*e5436536SAndroid Build Coastguard Worker }
771*e5436536SAndroid Build Coastguard Worker }
772*e5436536SAndroid Build Coastguard Worker }
773*e5436536SAndroid Build Coastguard Worker
774*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
775*e5436536SAndroid Build Coastguard Worker /*!
776*e5436536SAndroid Build Coastguard Worker \brief Do detection for every tonality estimate, using forward prediction.
777*e5436536SAndroid Build Coastguard Worker
778*e5436536SAndroid Build Coastguard Worker
779*e5436536SAndroid Build Coastguard Worker \return none.
780*e5436536SAndroid Build Coastguard Worker
781*e5436536SAndroid Build Coastguard Worker */
782*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
detectionWithPrediction(FIXP_DBL ** quotaBuffer,FIXP_DBL ** pDiffVecScfb,INT ** signBuffer,INT nSfb,const UCHAR * pFreqBandTable,FIXP_DBL ** sfmOrig,FIXP_DBL ** sfmSbr,UCHAR ** detectionVectors,UCHAR * pPrevAddHarmSfb,GUIDE_VECTORS * guideVectors,INT noEstPerFrame,INT detectionStart,INT totNoEst,INT newDetectionAllowed,INT * pAddHarmFlag,UCHAR * pAddHarmSfb,FIXP_DBL * pNrgVector,const DETECTOR_PARAMETERS_MH * mhParams)783*e5436536SAndroid Build Coastguard Worker static void detectionWithPrediction(
784*e5436536SAndroid Build Coastguard Worker FIXP_DBL **quotaBuffer, FIXP_DBL **pDiffVecScfb, INT **signBuffer, INT nSfb,
785*e5436536SAndroid Build Coastguard Worker const UCHAR *pFreqBandTable, FIXP_DBL **sfmOrig, FIXP_DBL **sfmSbr,
786*e5436536SAndroid Build Coastguard Worker UCHAR **detectionVectors, UCHAR *pPrevAddHarmSfb,
787*e5436536SAndroid Build Coastguard Worker GUIDE_VECTORS *guideVectors, INT noEstPerFrame, INT detectionStart,
788*e5436536SAndroid Build Coastguard Worker INT totNoEst, INT newDetectionAllowed, INT *pAddHarmFlag,
789*e5436536SAndroid Build Coastguard Worker UCHAR *pAddHarmSfb, FIXP_DBL *pNrgVector,
790*e5436536SAndroid Build Coastguard Worker const DETECTOR_PARAMETERS_MH *mhParams) {
791*e5436536SAndroid Build Coastguard Worker INT est = 0, i;
792*e5436536SAndroid Build Coastguard Worker INT start;
793*e5436536SAndroid Build Coastguard Worker
794*e5436536SAndroid Build Coastguard Worker FDKmemclear(pAddHarmSfb, nSfb * sizeof(UCHAR));
795*e5436536SAndroid Build Coastguard Worker
796*e5436536SAndroid Build Coastguard Worker if (newDetectionAllowed) {
797*e5436536SAndroid Build Coastguard Worker /* Since we don't want to use the transient region for detection (since the
798*e5436536SAndroid Build Coastguard Worker tonality values tend to be a bit unreliable for this region) the
799*e5436536SAndroid Build Coastguard Worker guide-values are copied to the current starting point. */
800*e5436536SAndroid Build Coastguard Worker if (totNoEst > 1) {
801*e5436536SAndroid Build Coastguard Worker start = detectionStart + 1;
802*e5436536SAndroid Build Coastguard Worker
803*e5436536SAndroid Build Coastguard Worker if (start != 0) {
804*e5436536SAndroid Build Coastguard Worker FDKmemcpy(guideVectors[start].guideVectorDiff,
805*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorDiff, nSfb * sizeof(FIXP_DBL));
806*e5436536SAndroid Build Coastguard Worker FDKmemcpy(guideVectors[start].guideVectorOrig,
807*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorOrig, nSfb * sizeof(FIXP_DBL));
808*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[start - 1].guideVectorDetected,
809*e5436536SAndroid Build Coastguard Worker nSfb * sizeof(UCHAR));
810*e5436536SAndroid Build Coastguard Worker }
811*e5436536SAndroid Build Coastguard Worker } else {
812*e5436536SAndroid Build Coastguard Worker start = 0;
813*e5436536SAndroid Build Coastguard Worker }
814*e5436536SAndroid Build Coastguard Worker } else {
815*e5436536SAndroid Build Coastguard Worker start = 0;
816*e5436536SAndroid Build Coastguard Worker }
817*e5436536SAndroid Build Coastguard Worker
818*e5436536SAndroid Build Coastguard Worker for (est = start; est < totNoEst; est++) {
819*e5436536SAndroid Build Coastguard Worker /*
820*e5436536SAndroid Build Coastguard Worker * Do detection on the current frame using
821*e5436536SAndroid Build Coastguard Worker * guide-info from the previous.
822*e5436536SAndroid Build Coastguard Worker *******************************************/
823*e5436536SAndroid Build Coastguard Worker if (est > 0) {
824*e5436536SAndroid Build Coastguard Worker FDKmemcpy(guideVectors[est].guideVectorDetected,
825*e5436536SAndroid Build Coastguard Worker detectionVectors[est - 1], nSfb * sizeof(UCHAR));
826*e5436536SAndroid Build Coastguard Worker }
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker FDKmemclear(detectionVectors[est], nSfb * sizeof(UCHAR));
829*e5436536SAndroid Build Coastguard Worker
830*e5436536SAndroid Build Coastguard Worker if (est < totNoEst - 1) {
831*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est + 1].guideVectorDiff,
832*e5436536SAndroid Build Coastguard Worker nSfb * sizeof(FIXP_DBL));
833*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est + 1].guideVectorOrig,
834*e5436536SAndroid Build Coastguard Worker nSfb * sizeof(FIXP_DBL));
835*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est + 1].guideVectorDetected,
836*e5436536SAndroid Build Coastguard Worker nSfb * sizeof(UCHAR));
837*e5436536SAndroid Build Coastguard Worker
838*e5436536SAndroid Build Coastguard Worker detection(quotaBuffer[est], pDiffVecScfb[est], nSfb,
839*e5436536SAndroid Build Coastguard Worker detectionVectors[est], pFreqBandTable, sfmOrig[est],
840*e5436536SAndroid Build Coastguard Worker sfmSbr[est], guideVectors[est], guideVectors[est + 1],
841*e5436536SAndroid Build Coastguard Worker mhParams->thresHolds);
842*e5436536SAndroid Build Coastguard Worker } else {
843*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est].guideVectorDiff, nSfb * sizeof(FIXP_DBL));
844*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est].guideVectorOrig, nSfb * sizeof(FIXP_DBL));
845*e5436536SAndroid Build Coastguard Worker FDKmemclear(guideVectors[est].guideVectorDetected, nSfb * sizeof(UCHAR));
846*e5436536SAndroid Build Coastguard Worker
847*e5436536SAndroid Build Coastguard Worker detection(quotaBuffer[est], pDiffVecScfb[est], nSfb,
848*e5436536SAndroid Build Coastguard Worker detectionVectors[est], pFreqBandTable, sfmOrig[est],
849*e5436536SAndroid Build Coastguard Worker sfmSbr[est], guideVectors[est], guideVectors[est],
850*e5436536SAndroid Build Coastguard Worker mhParams->thresHolds);
851*e5436536SAndroid Build Coastguard Worker }
852*e5436536SAndroid Build Coastguard Worker }
853*e5436536SAndroid Build Coastguard Worker
854*e5436536SAndroid Build Coastguard Worker /* Clean up the detection.*/
855*e5436536SAndroid Build Coastguard Worker transientCleanUp(quotaBuffer, nSfb, detectionVectors, pAddHarmSfb,
856*e5436536SAndroid Build Coastguard Worker pPrevAddHarmSfb, signBuffer, pFreqBandTable, start, totNoEst,
857*e5436536SAndroid Build Coastguard Worker newDetectionAllowed, pNrgVector, mhParams->thresHolds);
858*e5436536SAndroid Build Coastguard Worker
859*e5436536SAndroid Build Coastguard Worker /* Set flag... */
860*e5436536SAndroid Build Coastguard Worker *pAddHarmFlag = 0;
861*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
862*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[i]) {
863*e5436536SAndroid Build Coastguard Worker *pAddHarmFlag = 1;
864*e5436536SAndroid Build Coastguard Worker break;
865*e5436536SAndroid Build Coastguard Worker }
866*e5436536SAndroid Build Coastguard Worker }
867*e5436536SAndroid Build Coastguard Worker
868*e5436536SAndroid Build Coastguard Worker FDKmemcpy(pPrevAddHarmSfb, pAddHarmSfb, nSfb * sizeof(UCHAR));
869*e5436536SAndroid Build Coastguard Worker FDKmemcpy(guideVectors[0].guideVectorDetected, pAddHarmSfb,
870*e5436536SAndroid Build Coastguard Worker nSfb * sizeof(INT));
871*e5436536SAndroid Build Coastguard Worker
872*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
873*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f);
874*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f);
875*e5436536SAndroid Build Coastguard Worker
876*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[i] == 1) {
877*e5436536SAndroid Build Coastguard Worker /* If we had a detection use the guide-value in the next frame from the
878*e5436536SAndroid Build Coastguard Worker last estimate were the detection was done.*/
879*e5436536SAndroid Build Coastguard Worker for (est = start; est < totNoEst; est++) {
880*e5436536SAndroid Build Coastguard Worker if (guideVectors[est].guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) {
881*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorDiff[i] =
882*e5436536SAndroid Build Coastguard Worker guideVectors[est].guideVectorDiff[i];
883*e5436536SAndroid Build Coastguard Worker }
884*e5436536SAndroid Build Coastguard Worker if (guideVectors[est].guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) {
885*e5436536SAndroid Build Coastguard Worker guideVectors[0].guideVectorOrig[i] =
886*e5436536SAndroid Build Coastguard Worker guideVectors[est].guideVectorOrig[i];
887*e5436536SAndroid Build Coastguard Worker }
888*e5436536SAndroid Build Coastguard Worker }
889*e5436536SAndroid Build Coastguard Worker }
890*e5436536SAndroid Build Coastguard Worker }
891*e5436536SAndroid Build Coastguard Worker }
892*e5436536SAndroid Build Coastguard Worker
893*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
894*e5436536SAndroid Build Coastguard Worker /*!
895*e5436536SAndroid Build Coastguard Worker \brief Calculates a compensation vector for the energy data.
896*e5436536SAndroid Build Coastguard Worker
897*e5436536SAndroid Build Coastguard Worker This function calculates a compensation vector for the energy data (i.e.
898*e5436536SAndroid Build Coastguard Worker envelope data) that is calculated elsewhere. This is since, one sine on
899*e5436536SAndroid Build Coastguard Worker the border of two scalefactor bands, will be replace by one sine in the
900*e5436536SAndroid Build Coastguard Worker middle of either scalefactor band. However, since the sine that is replaced
901*e5436536SAndroid Build Coastguard Worker will influence the energy estimate in both scalefactor bands (in the envelops
902*e5436536SAndroid Build Coastguard Worker calculation function) a compensation value is required in order to avoid
903*e5436536SAndroid Build Coastguard Worker noise substitution in the decoder next to the synthetic sine.
904*e5436536SAndroid Build Coastguard Worker
905*e5436536SAndroid Build Coastguard Worker \return none.
906*e5436536SAndroid Build Coastguard Worker
907*e5436536SAndroid Build Coastguard Worker */
908*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
calculateCompVector(UCHAR * pAddHarmSfb,FIXP_DBL ** pTonalityMatrix,INT ** pSignMatrix,UCHAR * pEnvComp,INT nSfb,const UCHAR * freqBandTable,INT totNoEst,INT maxComp,UCHAR * pPrevEnvComp,INT newDetectionAllowed)909*e5436536SAndroid Build Coastguard Worker static void calculateCompVector(UCHAR *pAddHarmSfb, FIXP_DBL **pTonalityMatrix,
910*e5436536SAndroid Build Coastguard Worker INT **pSignMatrix, UCHAR *pEnvComp, INT nSfb,
911*e5436536SAndroid Build Coastguard Worker const UCHAR *freqBandTable, INT totNoEst,
912*e5436536SAndroid Build Coastguard Worker INT maxComp, UCHAR *pPrevEnvComp,
913*e5436536SAndroid Build Coastguard Worker INT newDetectionAllowed) {
914*e5436536SAndroid Build Coastguard Worker INT scfBand, est, l, ll, lu, maxPosF, maxPosT;
915*e5436536SAndroid Build Coastguard Worker FIXP_DBL maxVal;
916*e5436536SAndroid Build Coastguard Worker INT compValue;
917*e5436536SAndroid Build Coastguard Worker FIXP_DBL tmp;
918*e5436536SAndroid Build Coastguard Worker
919*e5436536SAndroid Build Coastguard Worker FDKmemclear(pEnvComp, nSfb * sizeof(UCHAR));
920*e5436536SAndroid Build Coastguard Worker
921*e5436536SAndroid Build Coastguard Worker for (scfBand = 0; scfBand < nSfb; scfBand++) {
922*e5436536SAndroid Build Coastguard Worker if (pAddHarmSfb[scfBand]) { /* A missing sine was detected */
923*e5436536SAndroid Build Coastguard Worker ll = freqBandTable[scfBand];
924*e5436536SAndroid Build Coastguard Worker lu = freqBandTable[scfBand + 1];
925*e5436536SAndroid Build Coastguard Worker
926*e5436536SAndroid Build Coastguard Worker maxPosF = 0; /* First find the maximum*/
927*e5436536SAndroid Build Coastguard Worker maxPosT = 0;
928*e5436536SAndroid Build Coastguard Worker maxVal = FL2FXCONST_DBL(0.0f);
929*e5436536SAndroid Build Coastguard Worker
930*e5436536SAndroid Build Coastguard Worker for (est = 0; est < totNoEst; est++) {
931*e5436536SAndroid Build Coastguard Worker for (l = ll; l < lu; l++) {
932*e5436536SAndroid Build Coastguard Worker if (pTonalityMatrix[est][l] > maxVal) {
933*e5436536SAndroid Build Coastguard Worker maxVal = pTonalityMatrix[est][l];
934*e5436536SAndroid Build Coastguard Worker maxPosF = l;
935*e5436536SAndroid Build Coastguard Worker maxPosT = est;
936*e5436536SAndroid Build Coastguard Worker }
937*e5436536SAndroid Build Coastguard Worker }
938*e5436536SAndroid Build Coastguard Worker }
939*e5436536SAndroid Build Coastguard Worker
940*e5436536SAndroid Build Coastguard Worker /*
941*e5436536SAndroid Build Coastguard Worker * If the maximum tonality is at the lower border of the
942*e5436536SAndroid Build Coastguard Worker * scalefactor band, we check the sign of the adjacent channels
943*e5436536SAndroid Build Coastguard Worker * to see if this sine is shared by the lower channel. If so, the
944*e5436536SAndroid Build Coastguard Worker * energy of the single sine will be present in two scalefactor bands
945*e5436536SAndroid Build Coastguard Worker * in the SBR data, which will cause problems in the decoder, when we
946*e5436536SAndroid Build Coastguard Worker * add a sine to just one of the channels.
947*e5436536SAndroid Build Coastguard Worker *********************************************************************/
948*e5436536SAndroid Build Coastguard Worker if (maxPosF == ll && scfBand) {
949*e5436536SAndroid Build Coastguard Worker if (!pAddHarmSfb[scfBand - 1]) { /* No detection below*/
950*e5436536SAndroid Build Coastguard Worker if (pSignMatrix[maxPosT][maxPosF - 1] > 0 &&
951*e5436536SAndroid Build Coastguard Worker pSignMatrix[maxPosT][maxPosF] < 0) {
952*e5436536SAndroid Build Coastguard Worker /* The comp value is calulated as the tonallity value, i.e we want
953*e5436536SAndroid Build Coastguard Worker to reduce the envelope data for this channel with as much as the
954*e5436536SAndroid Build Coastguard Worker tonality that is spread from the channel above. (ld64(RELAXATION)
955*e5436536SAndroid Build Coastguard Worker = 0.31143075889) */
956*e5436536SAndroid Build Coastguard Worker tmp = fixp_abs(
957*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF - 1]) +
958*e5436536SAndroid Build Coastguard Worker RELAXATION_LD64);
959*e5436536SAndroid Build Coastguard Worker tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) +
960*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)1; /* shift one bit less for rounding */
961*e5436536SAndroid Build Coastguard Worker compValue = ((INT)(LONG)tmp) >> 1;
962*e5436536SAndroid Build Coastguard Worker
963*e5436536SAndroid Build Coastguard Worker /* limit the comp-value*/
964*e5436536SAndroid Build Coastguard Worker if (compValue > maxComp) compValue = maxComp;
965*e5436536SAndroid Build Coastguard Worker
966*e5436536SAndroid Build Coastguard Worker pEnvComp[scfBand - 1] = compValue;
967*e5436536SAndroid Build Coastguard Worker }
968*e5436536SAndroid Build Coastguard Worker }
969*e5436536SAndroid Build Coastguard Worker }
970*e5436536SAndroid Build Coastguard Worker
971*e5436536SAndroid Build Coastguard Worker /*
972*e5436536SAndroid Build Coastguard Worker * Same as above, but for the upper end of the scalefactor-band.
973*e5436536SAndroid Build Coastguard Worker ***************************************************************/
974*e5436536SAndroid Build Coastguard Worker if (maxPosF == lu - 1 && scfBand + 1 < nSfb) { /* Upper border*/
975*e5436536SAndroid Build Coastguard Worker if (!pAddHarmSfb[scfBand + 1]) {
976*e5436536SAndroid Build Coastguard Worker if (pSignMatrix[maxPosT][maxPosF] > 0 &&
977*e5436536SAndroid Build Coastguard Worker pSignMatrix[maxPosT][maxPosF + 1] < 0) {
978*e5436536SAndroid Build Coastguard Worker tmp = fixp_abs(
979*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF + 1]) +
980*e5436536SAndroid Build Coastguard Worker RELAXATION_LD64);
981*e5436536SAndroid Build Coastguard Worker tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) +
982*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)1; /* shift one bit less for rounding */
983*e5436536SAndroid Build Coastguard Worker compValue = ((INT)(LONG)tmp) >> 1;
984*e5436536SAndroid Build Coastguard Worker
985*e5436536SAndroid Build Coastguard Worker if (compValue > maxComp) compValue = maxComp;
986*e5436536SAndroid Build Coastguard Worker
987*e5436536SAndroid Build Coastguard Worker pEnvComp[scfBand + 1] = compValue;
988*e5436536SAndroid Build Coastguard Worker }
989*e5436536SAndroid Build Coastguard Worker }
990*e5436536SAndroid Build Coastguard Worker }
991*e5436536SAndroid Build Coastguard Worker }
992*e5436536SAndroid Build Coastguard Worker }
993*e5436536SAndroid Build Coastguard Worker
994*e5436536SAndroid Build Coastguard Worker if (newDetectionAllowed == 0) {
995*e5436536SAndroid Build Coastguard Worker for (scfBand = 0; scfBand < nSfb; scfBand++) {
996*e5436536SAndroid Build Coastguard Worker if (pEnvComp[scfBand] != 0 && pPrevEnvComp[scfBand] == 0)
997*e5436536SAndroid Build Coastguard Worker pEnvComp[scfBand] = 0;
998*e5436536SAndroid Build Coastguard Worker }
999*e5436536SAndroid Build Coastguard Worker }
1000*e5436536SAndroid Build Coastguard Worker
1001*e5436536SAndroid Build Coastguard Worker /* remember the value for the next frame.*/
1002*e5436536SAndroid Build Coastguard Worker FDKmemcpy(pPrevEnvComp, pEnvComp, nSfb * sizeof(UCHAR));
1003*e5436536SAndroid Build Coastguard Worker }
1004*e5436536SAndroid Build Coastguard Worker
1005*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
1006*e5436536SAndroid Build Coastguard Worker /*!
1007*e5436536SAndroid Build Coastguard Worker \brief Detects where strong tonal components will be missing after
1008*e5436536SAndroid Build Coastguard Worker HFR in the decoder.
1009*e5436536SAndroid Build Coastguard Worker
1010*e5436536SAndroid Build Coastguard Worker
1011*e5436536SAndroid Build Coastguard Worker \return none.
1012*e5436536SAndroid Build Coastguard Worker
1013*e5436536SAndroid Build Coastguard Worker */
1014*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet,FIXP_DBL ** pQuotaBuffer,INT ** pSignBuffer,SCHAR * indexVector,const SBR_FRAME_INFO * pFrameInfo,const UCHAR * pTranInfo,INT * pAddHarmonicsFlag,UCHAR * pAddHarmonicsScaleFactorBands,const UCHAR * freqBandTable,INT nSfb,UCHAR * envelopeCompensation,FIXP_DBL * pNrgVector)1015*e5436536SAndroid Build Coastguard Worker void FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(
1016*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet, FIXP_DBL **pQuotaBuffer,
1017*e5436536SAndroid Build Coastguard Worker INT **pSignBuffer, SCHAR *indexVector, const SBR_FRAME_INFO *pFrameInfo,
1018*e5436536SAndroid Build Coastguard Worker const UCHAR *pTranInfo, INT *pAddHarmonicsFlag,
1019*e5436536SAndroid Build Coastguard Worker UCHAR *pAddHarmonicsScaleFactorBands, const UCHAR *freqBandTable, INT nSfb,
1020*e5436536SAndroid Build Coastguard Worker UCHAR *envelopeCompensation, FIXP_DBL *pNrgVector) {
1021*e5436536SAndroid Build Coastguard Worker INT transientFlag = pTranInfo[1];
1022*e5436536SAndroid Build Coastguard Worker INT transientPos = pTranInfo[0];
1023*e5436536SAndroid Build Coastguard Worker INT newDetectionAllowed;
1024*e5436536SAndroid Build Coastguard Worker INT transientDetStart = 0;
1025*e5436536SAndroid Build Coastguard Worker
1026*e5436536SAndroid Build Coastguard Worker UCHAR **detectionVectors = h_sbrMHDet->detectionVectors;
1027*e5436536SAndroid Build Coastguard Worker INT move = h_sbrMHDet->move;
1028*e5436536SAndroid Build Coastguard Worker INT noEstPerFrame = h_sbrMHDet->noEstPerFrame;
1029*e5436536SAndroid Build Coastguard Worker INT totNoEst = h_sbrMHDet->totNoEst;
1030*e5436536SAndroid Build Coastguard Worker INT prevTransientFlag = h_sbrMHDet->previousTransientFlag;
1031*e5436536SAndroid Build Coastguard Worker INT prevTransientFrame = h_sbrMHDet->previousTransientFrame;
1032*e5436536SAndroid Build Coastguard Worker INT transientPosOffset = h_sbrMHDet->transientPosOffset;
1033*e5436536SAndroid Build Coastguard Worker INT prevTransientPos = h_sbrMHDet->previousTransientPos;
1034*e5436536SAndroid Build Coastguard Worker GUIDE_VECTORS *guideVectors = h_sbrMHDet->guideVectors;
1035*e5436536SAndroid Build Coastguard Worker INT deltaTime = h_sbrMHDet->mhParams->deltaTime;
1036*e5436536SAndroid Build Coastguard Worker INT maxComp = h_sbrMHDet->mhParams->maxComp;
1037*e5436536SAndroid Build Coastguard Worker
1038*e5436536SAndroid Build Coastguard Worker int est;
1039*e5436536SAndroid Build Coastguard Worker
1040*e5436536SAndroid Build Coastguard Worker /*
1041*e5436536SAndroid Build Coastguard Worker Buffer values.
1042*e5436536SAndroid Build Coastguard Worker */
1043*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(move <= (MAX_NO_OF_ESTIMATES >> 1));
1044*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(noEstPerFrame <= (MAX_NO_OF_ESTIMATES >> 1));
1045*e5436536SAndroid Build Coastguard Worker
1046*e5436536SAndroid Build Coastguard Worker FIXP_DBL *sfmSbr[MAX_NO_OF_ESTIMATES];
1047*e5436536SAndroid Build Coastguard Worker FIXP_DBL *sfmOrig[MAX_NO_OF_ESTIMATES];
1048*e5436536SAndroid Build Coastguard Worker FIXP_DBL *tonalityDiff[MAX_NO_OF_ESTIMATES];
1049*e5436536SAndroid Build Coastguard Worker
1050*e5436536SAndroid Build Coastguard Worker for (est = 0; est < MAX_NO_OF_ESTIMATES / 2; est++) {
1051*e5436536SAndroid Build Coastguard Worker sfmSbr[est] = h_sbrMHDet->sfmSbr[est];
1052*e5436536SAndroid Build Coastguard Worker sfmOrig[est] = h_sbrMHDet->sfmOrig[est];
1053*e5436536SAndroid Build Coastguard Worker tonalityDiff[est] = h_sbrMHDet->tonalityDiff[est];
1054*e5436536SAndroid Build Coastguard Worker }
1055*e5436536SAndroid Build Coastguard Worker
1056*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_START(_scratch, FIXP_DBL,
1057*e5436536SAndroid Build Coastguard Worker 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS)
1058*e5436536SAndroid Build Coastguard Worker FIXP_DBL *scratch = _scratch;
1059*e5436536SAndroid Build Coastguard Worker for (; est < MAX_NO_OF_ESTIMATES; est++) {
1060*e5436536SAndroid Build Coastguard Worker sfmSbr[est] = scratch;
1061*e5436536SAndroid Build Coastguard Worker scratch += MAX_FREQ_COEFFS;
1062*e5436536SAndroid Build Coastguard Worker sfmOrig[est] = scratch;
1063*e5436536SAndroid Build Coastguard Worker scratch += MAX_FREQ_COEFFS;
1064*e5436536SAndroid Build Coastguard Worker tonalityDiff[est] = scratch;
1065*e5436536SAndroid Build Coastguard Worker scratch += MAX_FREQ_COEFFS;
1066*e5436536SAndroid Build Coastguard Worker }
1067*e5436536SAndroid Build Coastguard Worker
1068*e5436536SAndroid Build Coastguard Worker /* Determine if we're allowed to detect "missing harmonics" that wasn't
1069*e5436536SAndroid Build Coastguard Worker detected before. In order to be allowed to do new detection, there must be
1070*e5436536SAndroid Build Coastguard Worker a transient in the current frame, or a transient in the previous frame
1071*e5436536SAndroid Build Coastguard Worker sufficiently close to the current frame. */
1072*e5436536SAndroid Build Coastguard Worker newDetectionAllowed = isDetectionOfNewToneAllowed(
1073*e5436536SAndroid Build Coastguard Worker pFrameInfo, &transientDetStart, noEstPerFrame, prevTransientFrame,
1074*e5436536SAndroid Build Coastguard Worker prevTransientPos, prevTransientFlag, transientPosOffset, transientFlag,
1075*e5436536SAndroid Build Coastguard Worker transientPos, deltaTime, h_sbrMHDet);
1076*e5436536SAndroid Build Coastguard Worker
1077*e5436536SAndroid Build Coastguard Worker /* Calulate the variables that will be used subsequently for the actual
1078*e5436536SAndroid Build Coastguard Worker * detection */
1079*e5436536SAndroid Build Coastguard Worker calculateDetectorInput(pQuotaBuffer, indexVector, tonalityDiff, sfmOrig,
1080*e5436536SAndroid Build Coastguard Worker sfmSbr, freqBandTable, nSfb, noEstPerFrame, move);
1081*e5436536SAndroid Build Coastguard Worker
1082*e5436536SAndroid Build Coastguard Worker /* Do the actual detection using information from previous detections */
1083*e5436536SAndroid Build Coastguard Worker detectionWithPrediction(pQuotaBuffer, tonalityDiff, pSignBuffer, nSfb,
1084*e5436536SAndroid Build Coastguard Worker freqBandTable, sfmOrig, sfmSbr, detectionVectors,
1085*e5436536SAndroid Build Coastguard Worker h_sbrMHDet->guideScfb, guideVectors, noEstPerFrame,
1086*e5436536SAndroid Build Coastguard Worker transientDetStart, totNoEst, newDetectionAllowed,
1087*e5436536SAndroid Build Coastguard Worker pAddHarmonicsFlag, pAddHarmonicsScaleFactorBands,
1088*e5436536SAndroid Build Coastguard Worker pNrgVector, h_sbrMHDet->mhParams);
1089*e5436536SAndroid Build Coastguard Worker
1090*e5436536SAndroid Build Coastguard Worker /* Calculate the comp vector, so that the energy can be
1091*e5436536SAndroid Build Coastguard Worker compensated for a sine between two QMF-bands. */
1092*e5436536SAndroid Build Coastguard Worker calculateCompVector(pAddHarmonicsScaleFactorBands, pQuotaBuffer, pSignBuffer,
1093*e5436536SAndroid Build Coastguard Worker envelopeCompensation, nSfb, freqBandTable, totNoEst,
1094*e5436536SAndroid Build Coastguard Worker maxComp, h_sbrMHDet->prevEnvelopeCompensation,
1095*e5436536SAndroid Build Coastguard Worker newDetectionAllowed);
1096*e5436536SAndroid Build Coastguard Worker
1097*e5436536SAndroid Build Coastguard Worker for (est = 0; est < move; est++) {
1098*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tonalityDiff[est], tonalityDiff[est + noEstPerFrame],
1099*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1100*e5436536SAndroid Build Coastguard Worker FDKmemcpy(sfmOrig[est], sfmOrig[est + noEstPerFrame],
1101*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1102*e5436536SAndroid Build Coastguard Worker FDKmemcpy(sfmSbr[est], sfmSbr[est + noEstPerFrame],
1103*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1104*e5436536SAndroid Build Coastguard Worker }
1105*e5436536SAndroid Build Coastguard Worker C_ALLOC_SCRATCH_END(_scratch, FIXP_DBL,
1106*e5436536SAndroid Build Coastguard Worker 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS)
1107*e5436536SAndroid Build Coastguard Worker }
1108*e5436536SAndroid Build Coastguard Worker
1109*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
1110*e5436536SAndroid Build Coastguard Worker /*!
1111*e5436536SAndroid Build Coastguard Worker \brief Initialize an instance of the missing harmonics detector.
1112*e5436536SAndroid Build Coastguard Worker
1113*e5436536SAndroid Build Coastguard Worker
1114*e5436536SAndroid Build Coastguard Worker \return errorCode, noError if OK.
1115*e5436536SAndroid Build Coastguard Worker
1116*e5436536SAndroid Build Coastguard Worker */
1117*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_CreateSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet,INT chan)1118*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_CreateSbrMissingHarmonicsDetector(
1119*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT chan) {
1120*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1121*e5436536SAndroid Build Coastguard Worker INT i;
1122*e5436536SAndroid Build Coastguard Worker
1123*e5436536SAndroid Build Coastguard Worker UCHAR *detectionVectors = GetRam_Sbr_detectionVectors(chan);
1124*e5436536SAndroid Build Coastguard Worker UCHAR *guideVectorDetected = GetRam_Sbr_guideVectorDetected(chan);
1125*e5436536SAndroid Build Coastguard Worker FIXP_DBL *guideVectorDiff = GetRam_Sbr_guideVectorDiff(chan);
1126*e5436536SAndroid Build Coastguard Worker FIXP_DBL *guideVectorOrig = GetRam_Sbr_guideVectorOrig(chan);
1127*e5436536SAndroid Build Coastguard Worker
1128*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs, sizeof(SBR_MISSING_HARMONICS_DETECTOR));
1129*e5436536SAndroid Build Coastguard Worker
1130*e5436536SAndroid Build Coastguard Worker hs->prevEnvelopeCompensation = GetRam_Sbr_prevEnvelopeCompensation(chan);
1131*e5436536SAndroid Build Coastguard Worker hs->guideScfb = GetRam_Sbr_guideScfb(chan);
1132*e5436536SAndroid Build Coastguard Worker
1133*e5436536SAndroid Build Coastguard Worker if ((NULL == detectionVectors) || (NULL == guideVectorDetected) ||
1134*e5436536SAndroid Build Coastguard Worker (NULL == guideVectorDiff) || (NULL == guideVectorOrig) ||
1135*e5436536SAndroid Build Coastguard Worker (NULL == hs->prevEnvelopeCompensation) || (NULL == hs->guideScfb)) {
1136*e5436536SAndroid Build Coastguard Worker goto bail;
1137*e5436536SAndroid Build Coastguard Worker }
1138*e5436536SAndroid Build Coastguard Worker
1139*e5436536SAndroid Build Coastguard Worker for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) {
1140*e5436536SAndroid Build Coastguard Worker hs->guideVectors[i].guideVectorDiff =
1141*e5436536SAndroid Build Coastguard Worker guideVectorDiff + (i * MAX_FREQ_COEFFS);
1142*e5436536SAndroid Build Coastguard Worker hs->guideVectors[i].guideVectorOrig =
1143*e5436536SAndroid Build Coastguard Worker guideVectorOrig + (i * MAX_FREQ_COEFFS);
1144*e5436536SAndroid Build Coastguard Worker hs->detectionVectors[i] = detectionVectors + (i * MAX_FREQ_COEFFS);
1145*e5436536SAndroid Build Coastguard Worker hs->guideVectors[i].guideVectorDetected =
1146*e5436536SAndroid Build Coastguard Worker guideVectorDetected + (i * MAX_FREQ_COEFFS);
1147*e5436536SAndroid Build Coastguard Worker }
1148*e5436536SAndroid Build Coastguard Worker
1149*e5436536SAndroid Build Coastguard Worker return 0;
1150*e5436536SAndroid Build Coastguard Worker
1151*e5436536SAndroid Build Coastguard Worker bail:
1152*e5436536SAndroid Build Coastguard Worker hs->guideVectors[0].guideVectorDiff = guideVectorDiff;
1153*e5436536SAndroid Build Coastguard Worker hs->guideVectors[0].guideVectorOrig = guideVectorOrig;
1154*e5436536SAndroid Build Coastguard Worker hs->detectionVectors[0] = detectionVectors;
1155*e5436536SAndroid Build Coastguard Worker hs->guideVectors[0].guideVectorDetected = guideVectorDetected;
1156*e5436536SAndroid Build Coastguard Worker
1157*e5436536SAndroid Build Coastguard Worker FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(hs);
1158*e5436536SAndroid Build Coastguard Worker return -1;
1159*e5436536SAndroid Build Coastguard Worker }
1160*e5436536SAndroid Build Coastguard Worker
1161*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
1162*e5436536SAndroid Build Coastguard Worker /*!
1163*e5436536SAndroid Build Coastguard Worker \brief Initialize an instance of the missing harmonics detector.
1164*e5436536SAndroid Build Coastguard Worker
1165*e5436536SAndroid Build Coastguard Worker
1166*e5436536SAndroid Build Coastguard Worker \return errorCode, noError if OK.
1167*e5436536SAndroid Build Coastguard Worker
1168*e5436536SAndroid Build Coastguard Worker */
1169*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_InitSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet,INT sampleFreq,INT frameSize,INT nSfb,INT qmfNoChannels,INT totNoEst,INT move,INT noEstPerFrame,UINT sbrSyntaxFlags)1170*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_InitSbrMissingHarmonicsDetector(
1171*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT sampleFreq,
1172*e5436536SAndroid Build Coastguard Worker INT frameSize, INT nSfb, INT qmfNoChannels, INT totNoEst, INT move,
1173*e5436536SAndroid Build Coastguard Worker INT noEstPerFrame, UINT sbrSyntaxFlags) {
1174*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1175*e5436536SAndroid Build Coastguard Worker int i;
1176*e5436536SAndroid Build Coastguard Worker
1177*e5436536SAndroid Build Coastguard Worker FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES);
1178*e5436536SAndroid Build Coastguard Worker
1179*e5436536SAndroid Build Coastguard Worker if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1180*e5436536SAndroid Build Coastguard Worker switch (frameSize) {
1181*e5436536SAndroid Build Coastguard Worker case 1024:
1182*e5436536SAndroid Build Coastguard Worker case 512:
1183*e5436536SAndroid Build Coastguard Worker hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
1184*e5436536SAndroid Build Coastguard Worker hs->timeSlots = 16;
1185*e5436536SAndroid Build Coastguard Worker break;
1186*e5436536SAndroid Build Coastguard Worker case 960:
1187*e5436536SAndroid Build Coastguard Worker case 480:
1188*e5436536SAndroid Build Coastguard Worker hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
1189*e5436536SAndroid Build Coastguard Worker hs->timeSlots = 15;
1190*e5436536SAndroid Build Coastguard Worker break;
1191*e5436536SAndroid Build Coastguard Worker default:
1192*e5436536SAndroid Build Coastguard Worker return -1;
1193*e5436536SAndroid Build Coastguard Worker }
1194*e5436536SAndroid Build Coastguard Worker } else {
1195*e5436536SAndroid Build Coastguard Worker switch (frameSize) {
1196*e5436536SAndroid Build Coastguard Worker case 2048:
1197*e5436536SAndroid Build Coastguard Worker case 1024:
1198*e5436536SAndroid Build Coastguard Worker hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
1199*e5436536SAndroid Build Coastguard Worker hs->timeSlots = NUMBER_TIME_SLOTS_2048;
1200*e5436536SAndroid Build Coastguard Worker break;
1201*e5436536SAndroid Build Coastguard Worker case 1920:
1202*e5436536SAndroid Build Coastguard Worker case 960:
1203*e5436536SAndroid Build Coastguard Worker hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
1204*e5436536SAndroid Build Coastguard Worker hs->timeSlots = NUMBER_TIME_SLOTS_1920;
1205*e5436536SAndroid Build Coastguard Worker break;
1206*e5436536SAndroid Build Coastguard Worker default:
1207*e5436536SAndroid Build Coastguard Worker return -1;
1208*e5436536SAndroid Build Coastguard Worker }
1209*e5436536SAndroid Build Coastguard Worker }
1210*e5436536SAndroid Build Coastguard Worker
1211*e5436536SAndroid Build Coastguard Worker if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1212*e5436536SAndroid Build Coastguard Worker hs->mhParams = ¶msAacLd;
1213*e5436536SAndroid Build Coastguard Worker } else
1214*e5436536SAndroid Build Coastguard Worker hs->mhParams = ¶msAac;
1215*e5436536SAndroid Build Coastguard Worker
1216*e5436536SAndroid Build Coastguard Worker hs->qmfNoChannels = qmfNoChannels;
1217*e5436536SAndroid Build Coastguard Worker hs->sampleFreq = sampleFreq;
1218*e5436536SAndroid Build Coastguard Worker hs->nSfb = nSfb;
1219*e5436536SAndroid Build Coastguard Worker
1220*e5436536SAndroid Build Coastguard Worker hs->totNoEst = totNoEst;
1221*e5436536SAndroid Build Coastguard Worker hs->move = move;
1222*e5436536SAndroid Build Coastguard Worker hs->noEstPerFrame = noEstPerFrame;
1223*e5436536SAndroid Build Coastguard Worker
1224*e5436536SAndroid Build Coastguard Worker for (i = 0; i < totNoEst; i++) {
1225*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->guideVectors[i].guideVectorDiff,
1226*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1227*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->guideVectors[i].guideVectorOrig,
1228*e5436536SAndroid Build Coastguard Worker sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1229*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->detectionVectors[i], sizeof(UCHAR) * MAX_FREQ_COEFFS);
1230*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->guideVectors[i].guideVectorDetected,
1231*e5436536SAndroid Build Coastguard Worker sizeof(UCHAR) * MAX_FREQ_COEFFS);
1232*e5436536SAndroid Build Coastguard Worker }
1233*e5436536SAndroid Build Coastguard Worker
1234*e5436536SAndroid Build Coastguard Worker // for(i=0; i<totNoEst/2; i++) {
1235*e5436536SAndroid Build Coastguard Worker for (i = 0; i < MAX_NO_OF_ESTIMATES / 2; i++) {
1236*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->tonalityDiff[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1237*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->sfmOrig[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1238*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->sfmSbr[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS);
1239*e5436536SAndroid Build Coastguard Worker }
1240*e5436536SAndroid Build Coastguard Worker
1241*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->prevEnvelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS);
1242*e5436536SAndroid Build Coastguard Worker FDKmemclear(hs->guideScfb, sizeof(UCHAR) * MAX_FREQ_COEFFS);
1243*e5436536SAndroid Build Coastguard Worker
1244*e5436536SAndroid Build Coastguard Worker hs->previousTransientFlag = 0;
1245*e5436536SAndroid Build Coastguard Worker hs->previousTransientFrame = 0;
1246*e5436536SAndroid Build Coastguard Worker hs->previousTransientPos = 0;
1247*e5436536SAndroid Build Coastguard Worker
1248*e5436536SAndroid Build Coastguard Worker return (0);
1249*e5436536SAndroid Build Coastguard Worker }
1250*e5436536SAndroid Build Coastguard Worker
1251*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
1252*e5436536SAndroid Build Coastguard Worker /*!
1253*e5436536SAndroid Build Coastguard Worker \brief Deletes an instance of the missing harmonics detector.
1254*e5436536SAndroid Build Coastguard Worker
1255*e5436536SAndroid Build Coastguard Worker
1256*e5436536SAndroid Build Coastguard Worker \return none.
1257*e5436536SAndroid Build Coastguard Worker
1258*e5436536SAndroid Build Coastguard Worker */
1259*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet)1260*e5436536SAndroid Build Coastguard Worker void FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(
1261*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet) {
1262*e5436536SAndroid Build Coastguard Worker if (hSbrMHDet) {
1263*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1264*e5436536SAndroid Build Coastguard Worker
1265*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_detectionVectors(&hs->detectionVectors[0]);
1266*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_guideVectorDetected(&hs->guideVectors[0].guideVectorDetected);
1267*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_guideVectorDiff(&hs->guideVectors[0].guideVectorDiff);
1268*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_guideVectorOrig(&hs->guideVectors[0].guideVectorOrig);
1269*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_prevEnvelopeCompensation(&hs->prevEnvelopeCompensation);
1270*e5436536SAndroid Build Coastguard Worker FreeRam_Sbr_guideScfb(&hs->guideScfb);
1271*e5436536SAndroid Build Coastguard Worker }
1272*e5436536SAndroid Build Coastguard Worker }
1273*e5436536SAndroid Build Coastguard Worker
1274*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
1275*e5436536SAndroid Build Coastguard Worker /*!
1276*e5436536SAndroid Build Coastguard Worker \brief Resets an instance of the missing harmonics detector.
1277*e5436536SAndroid Build Coastguard Worker
1278*e5436536SAndroid Build Coastguard Worker
1279*e5436536SAndroid Build Coastguard Worker \return error code, noError if OK.
1280*e5436536SAndroid Build Coastguard Worker
1281*e5436536SAndroid Build Coastguard Worker */
1282*e5436536SAndroid Build Coastguard Worker /**************************************************************************/
FDKsbrEnc_ResetSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,INT nSfb)1283*e5436536SAndroid Build Coastguard Worker INT FDKsbrEnc_ResetSbrMissingHarmonicsDetector(
1284*e5436536SAndroid Build Coastguard Worker HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,
1285*e5436536SAndroid Build Coastguard Worker INT nSfb) {
1286*e5436536SAndroid Build Coastguard Worker int i;
1287*e5436536SAndroid Build Coastguard Worker FIXP_DBL tempGuide[MAX_FREQ_COEFFS];
1288*e5436536SAndroid Build Coastguard Worker UCHAR tempGuideInt[MAX_FREQ_COEFFS];
1289*e5436536SAndroid Build Coastguard Worker INT nSfbPrev;
1290*e5436536SAndroid Build Coastguard Worker
1291*e5436536SAndroid Build Coastguard Worker nSfbPrev = hSbrMissingHarmonicsDetector->nSfb;
1292*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->nSfb = nSfb;
1293*e5436536SAndroid Build Coastguard Worker
1294*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tempGuideInt, hSbrMissingHarmonicsDetector->guideScfb,
1295*e5436536SAndroid Build Coastguard Worker nSfbPrev * sizeof(UCHAR));
1296*e5436536SAndroid Build Coastguard Worker
1297*e5436536SAndroid Build Coastguard Worker if (nSfb > nSfbPrev) {
1298*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (nSfb - nSfbPrev); i++) {
1299*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideScfb[i] = 0;
1300*e5436536SAndroid Build Coastguard Worker }
1301*e5436536SAndroid Build Coastguard Worker
1302*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfbPrev; i++) {
1303*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideScfb[i + (nSfb - nSfbPrev)] =
1304*e5436536SAndroid Build Coastguard Worker tempGuideInt[i];
1305*e5436536SAndroid Build Coastguard Worker }
1306*e5436536SAndroid Build Coastguard Worker } else {
1307*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
1308*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideScfb[i] =
1309*e5436536SAndroid Build Coastguard Worker tempGuideInt[i + (nSfbPrev - nSfb)];
1310*e5436536SAndroid Build Coastguard Worker }
1311*e5436536SAndroid Build Coastguard Worker }
1312*e5436536SAndroid Build Coastguard Worker
1313*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tempGuide,
1314*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff,
1315*e5436536SAndroid Build Coastguard Worker nSfbPrev * sizeof(FIXP_DBL));
1316*e5436536SAndroid Build Coastguard Worker
1317*e5436536SAndroid Build Coastguard Worker if (nSfb > nSfbPrev) {
1318*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (nSfb - nSfbPrev); i++) {
1319*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] =
1320*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.0f);
1321*e5436536SAndroid Build Coastguard Worker }
1322*e5436536SAndroid Build Coastguard Worker
1323*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfbPrev; i++) {
1324*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0]
1325*e5436536SAndroid Build Coastguard Worker .guideVectorDiff[i + (nSfb - nSfbPrev)] = tempGuide[i];
1326*e5436536SAndroid Build Coastguard Worker }
1327*e5436536SAndroid Build Coastguard Worker } else {
1328*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
1329*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] =
1330*e5436536SAndroid Build Coastguard Worker tempGuide[i + (nSfbPrev - nSfb)];
1331*e5436536SAndroid Build Coastguard Worker }
1332*e5436536SAndroid Build Coastguard Worker }
1333*e5436536SAndroid Build Coastguard Worker
1334*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tempGuide,
1335*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig,
1336*e5436536SAndroid Build Coastguard Worker nSfbPrev * sizeof(FIXP_DBL));
1337*e5436536SAndroid Build Coastguard Worker
1338*e5436536SAndroid Build Coastguard Worker if (nSfb > nSfbPrev) {
1339*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (nSfb - nSfbPrev); i++) {
1340*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] =
1341*e5436536SAndroid Build Coastguard Worker FL2FXCONST_DBL(0.0f);
1342*e5436536SAndroid Build Coastguard Worker }
1343*e5436536SAndroid Build Coastguard Worker
1344*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfbPrev; i++) {
1345*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0]
1346*e5436536SAndroid Build Coastguard Worker .guideVectorOrig[i + (nSfb - nSfbPrev)] = tempGuide[i];
1347*e5436536SAndroid Build Coastguard Worker }
1348*e5436536SAndroid Build Coastguard Worker } else {
1349*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
1350*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] =
1351*e5436536SAndroid Build Coastguard Worker tempGuide[i + (nSfbPrev - nSfb)];
1352*e5436536SAndroid Build Coastguard Worker }
1353*e5436536SAndroid Build Coastguard Worker }
1354*e5436536SAndroid Build Coastguard Worker
1355*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tempGuideInt,
1356*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected,
1357*e5436536SAndroid Build Coastguard Worker nSfbPrev * sizeof(UCHAR));
1358*e5436536SAndroid Build Coastguard Worker
1359*e5436536SAndroid Build Coastguard Worker if (nSfb > nSfbPrev) {
1360*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (nSfb - nSfbPrev); i++) {
1361*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = 0;
1362*e5436536SAndroid Build Coastguard Worker }
1363*e5436536SAndroid Build Coastguard Worker
1364*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfbPrev; i++) {
1365*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0]
1366*e5436536SAndroid Build Coastguard Worker .guideVectorDetected[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
1367*e5436536SAndroid Build Coastguard Worker }
1368*e5436536SAndroid Build Coastguard Worker } else {
1369*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
1370*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] =
1371*e5436536SAndroid Build Coastguard Worker tempGuideInt[i + (nSfbPrev - nSfb)];
1372*e5436536SAndroid Build Coastguard Worker }
1373*e5436536SAndroid Build Coastguard Worker }
1374*e5436536SAndroid Build Coastguard Worker
1375*e5436536SAndroid Build Coastguard Worker FDKmemcpy(tempGuideInt,
1376*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->prevEnvelopeCompensation,
1377*e5436536SAndroid Build Coastguard Worker nSfbPrev * sizeof(UCHAR));
1378*e5436536SAndroid Build Coastguard Worker
1379*e5436536SAndroid Build Coastguard Worker if (nSfb > nSfbPrev) {
1380*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (nSfb - nSfbPrev); i++) {
1381*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = 0;
1382*e5436536SAndroid Build Coastguard Worker }
1383*e5436536SAndroid Build Coastguard Worker
1384*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfbPrev; i++) {
1385*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector
1386*e5436536SAndroid Build Coastguard Worker ->prevEnvelopeCompensation[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
1387*e5436536SAndroid Build Coastguard Worker }
1388*e5436536SAndroid Build Coastguard Worker } else {
1389*e5436536SAndroid Build Coastguard Worker for (i = 0; i < nSfb; i++) {
1390*e5436536SAndroid Build Coastguard Worker hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] =
1391*e5436536SAndroid Build Coastguard Worker tempGuideInt[i + (nSfbPrev - nSfb)];
1392*e5436536SAndroid Build Coastguard Worker }
1393*e5436536SAndroid Build Coastguard Worker }
1394*e5436536SAndroid Build Coastguard Worker
1395*e5436536SAndroid Build Coastguard Worker return 0;
1396*e5436536SAndroid Build Coastguard Worker }
1397