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