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