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 = &paramsAacLd;
1303   } else
1304   hs->mhParams = &paramsAac;
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