1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 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     Do detection for one tonality estimate.
669 
670 
671   \return    none.
672 
673 */
674 /**************************************************************************/
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)675 static void detection(FIXP_DBL *quotaBuffer,
676                       FIXP_DBL *pDiffVecScfb,
677                       INT nSfb,
678                       UCHAR *pHarmVec,
679                       const UCHAR *pFreqBandTable,
680                       FIXP_DBL *sfmOrig,
681                       FIXP_DBL *sfmSbr,
682                       GUIDE_VECTORS guideVectors,
683                       GUIDE_VECTORS newGuideVectors,
684                       THRES_HOLDS mhThresh)
685 {
686 
687   INT i,j,ll, lu;
688   FIXP_DBL thresTemp,thresOrig;
689 
690   /*
691    * Do detection on the difference vector, i.e. the difference between
692    * the original and the transposed.
693    *********************************************************************/
694   for(i=0;i<nSfb;i++){
695 
696     thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f))
697                   ? fixMax(fMult(mhThresh.decayGuideDiff,guideVectors.guideVectorDiff[i]), mhThresh.thresHoldDiffGuide)
698                   : mhThresh.thresHoldDiff;
699 
700     thresTemp = fixMin(thresTemp, mhThresh.thresHoldDiff);
701 
702     if(pDiffVecScfb[i] > thresTemp){
703       pHarmVec[i] = 1;
704       newGuideVectors.guideVectorDiff[i] = pDiffVecScfb[i];
705     }
706     else{
707       /* If the guide wasn't zero, but the current level is to low,
708          start tracking the decay on the tone in the original rather
709          than the difference.*/
710       if(guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)){
711         guideVectors.guideVectorOrig[i] = mhThresh.thresHoldToneGuide;
712       }
713     }
714   }
715 
716   /*
717    * Trace tones in the original signal that at one point
718    * have been detected because they will be replaced by
719    * multiple tones in the sbr signal.
720    ****************************************************/
721 
722   for(i=0;i<nSfb;i++){
723     ll = pFreqBandTable[i];
724     lu = pFreqBandTable[i+1];
725 
726     thresOrig = fixMax(fMult(guideVectors.guideVectorOrig[i], mhThresh.decayGuideOrig), mhThresh.thresHoldToneGuide);
727     thresOrig = fixMin(thresOrig, mhThresh.thresHoldTone);
728 
729     if(guideVectors.guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)){
730       for(j= ll;j<lu;j++){
731         if(quotaBuffer[j] > thresOrig){
732           pHarmVec[i] = 1;
733           newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
734         }
735       }
736     }
737   }
738 
739   /*
740    * Check for multiple sines in the transposed signal,
741    * where there is only one in the original.
742    ****************************************************/
743   thresOrig = mhThresh.thresHoldTone;
744 
745   for(i=0;i<nSfb;i++){
746     ll = pFreqBandTable[i];
747     lu = pFreqBandTable[i+1];
748 
749     if(pHarmVec[i] == 0){
750       if(lu -ll > 1){
751         for(j= ll;j<lu;j++){
752           if(quotaBuffer[j] > thresOrig && (sfmSbr[i] > mhThresh.sfmThresSbr && sfmOrig[i] < mhThresh.sfmThresOrig)){
753             pHarmVec[i] = 1;
754             newGuideVectors.guideVectorOrig[i] = quotaBuffer[j];
755           }
756         }
757       }
758       else{
759         if(i < nSfb -1){
760           ll = pFreqBandTable[i];
761 
762           if(i>0){
763             if(quotaBuffer[ll] > mhThresh.thresHoldTone && (pDiffVecScfb[i+1] < mhThresh.invThresHoldTone || pDiffVecScfb[i-1] < mhThresh.invThresHoldTone)){
764                 pHarmVec[i] = 1;
765                 newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
766             }
767           }
768           else{
769             if(quotaBuffer[ll] > mhThresh.thresHoldTone && pDiffVecScfb[i+1] < mhThresh.invThresHoldTone){
770                 pHarmVec[i] = 1;
771                 newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll];
772             }
773           }
774         }
775       }
776     }
777   }
778 }
779 
780 
781 /**************************************************************************/
782 /*!
783   \brief     Do detection for every tonality estimate, using forward prediction.
784 
785 
786   \return    none.
787 
788 */
789 /**************************************************************************/
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)790 static void detectionWithPrediction(FIXP_DBL **quotaBuffer,
791                                     FIXP_DBL **pDiffVecScfb,
792                                     INT ** signBuffer,
793                                     INT nSfb,
794                                     const UCHAR* pFreqBandTable,
795                                     FIXP_DBL **sfmOrig,
796                                     FIXP_DBL **sfmSbr,
797                                     UCHAR **detectionVectors,
798                                     UCHAR *pPrevAddHarmSfb,
799                                     GUIDE_VECTORS *guideVectors,
800                                     INT noEstPerFrame,
801                                     INT detectionStart,
802                                     INT totNoEst,
803                                     INT newDetectionAllowed,
804                                     INT *pAddHarmFlag,
805                                     UCHAR *pAddHarmSfb,
806                                     FIXP_DBL *pNrgVector,
807                                     const DETECTOR_PARAMETERS_MH *mhParams)
808 {
809   INT est = 0,i;
810   INT start;
811 
812   FDKmemclear(pAddHarmSfb,nSfb*sizeof(UCHAR));
813 
814   if(newDetectionAllowed){
815 
816     if(totNoEst > 1){
817       start = detectionStart;
818 
819       if (start != 0) {
820         FDKmemcpy(guideVectors[start].guideVectorDiff,guideVectors[0].guideVectorDiff,nSfb*sizeof(FIXP_DBL));
821         FDKmemcpy(guideVectors[start].guideVectorOrig,guideVectors[0].guideVectorOrig,nSfb*sizeof(FIXP_DBL));
822         FDKmemclear(guideVectors[start-1].guideVectorDetected,nSfb*sizeof(UCHAR));
823       }
824     }
825     else{
826       start = 0;
827     }
828   }
829   else{
830     start = 0;
831   }
832 
833 
834   for(est = start; est < totNoEst; est++){
835 
836     /*
837     * Do detection on the current frame using
838     * guide-info from the previous.
839     *******************************************/
840     if(est > 0){
841       FDKmemcpy(guideVectors[est].guideVectorDetected,detectionVectors[est-1],nSfb*sizeof(UCHAR));
842     }
843 
844     FDKmemclear(detectionVectors[est], nSfb*sizeof(UCHAR));
845 
846     if(est < totNoEst-1){
847       FDKmemclear(guideVectors[est+1].guideVectorDiff,nSfb*sizeof(FIXP_DBL));
848       FDKmemclear(guideVectors[est+1].guideVectorOrig,nSfb*sizeof(FIXP_DBL));
849       FDKmemclear(guideVectors[est+1].guideVectorDetected,nSfb*sizeof(UCHAR));
850 
851       detection(quotaBuffer[est],
852                 pDiffVecScfb[est],
853                 nSfb,
854                 detectionVectors[est],
855                 pFreqBandTable,
856                 sfmOrig[est],
857                 sfmSbr[est],
858                 guideVectors[est],
859                 guideVectors[est+1],
860                 mhParams->thresHolds);
861     }
862     else{
863       FDKmemclear(guideVectors[est].guideVectorDiff,nSfb*sizeof(FIXP_DBL));
864       FDKmemclear(guideVectors[est].guideVectorOrig,nSfb*sizeof(FIXP_DBL));
865       FDKmemclear(guideVectors[est].guideVectorDetected,nSfb*sizeof(UCHAR));
866 
867       detection(quotaBuffer[est],
868                 pDiffVecScfb[est],
869                 nSfb,
870                 detectionVectors[est],
871                 pFreqBandTable,
872                 sfmOrig[est],
873                 sfmSbr[est],
874                 guideVectors[est],
875                 guideVectors[est],
876                 mhParams->thresHolds);
877     }
878   }
879 
880 
881   /* Clean up the detection.*/
882   transientCleanUp(quotaBuffer,
883                    nSfb,
884                    detectionVectors,
885                    pAddHarmSfb,
886                    pPrevAddHarmSfb,
887                    signBuffer,
888                    pFreqBandTable,
889                    start,
890                    totNoEst,
891                    newDetectionAllowed,
892                    pNrgVector,
893                    mhParams->thresHolds);
894 
895 
896   /* Set flag... */
897   *pAddHarmFlag = 0;
898   for(i=0; i<nSfb; i++){
899     if(pAddHarmSfb[i]){
900       *pAddHarmFlag = 1;
901       break;
902     }
903   }
904 
905   FDKmemcpy(pPrevAddHarmSfb, pAddHarmSfb, nSfb*sizeof(UCHAR));
906   FDKmemcpy(guideVectors[0].guideVectorDetected,pAddHarmSfb,nSfb*sizeof(INT));
907 
908   for(i=0; i<nSfb ; i++){
909 
910     guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f);
911     guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f);
912 
913     if(pAddHarmSfb[i] == 1){
914       /* If we had a detection use the guide-value in the next frame from the last estimate were the detection
915       was done.*/
916       for(est=start; est < totNoEst; est++){
917         if(guideVectors[est].guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)){
918           guideVectors[0].guideVectorDiff[i] = guideVectors[est].guideVectorDiff[i];
919         }
920         if(guideVectors[est].guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)){
921           guideVectors[0].guideVectorOrig[i] = guideVectors[est].guideVectorOrig[i];
922         }
923       }
924     }
925   }
926 
927 }
928 
929 
930 /**************************************************************************/
931 /*!
932   \brief     Calculates a compensation vector for the energy data.
933 
934   This function calculates a compensation vector for the energy data (i.e.
935   envelope data) that is calculated elsewhere. This is since, one sine on
936   the border of two scalefactor bands, will be replace by one sine in the
937   middle of either scalefactor band. However, since the sine that is replaced
938   will influence the energy estimate in both scalefactor bands (in the envelops
939   calculation function) a compensation value is required in order to avoid
940   noise substitution in the decoder next to the synthetic sine.
941 
942   \return    none.
943 
944 */
945 /**************************************************************************/
calculateCompVector(UCHAR * pAddHarmSfb,FIXP_DBL ** pTonalityMatrix,INT ** pSignMatrix,UCHAR * pEnvComp,INT nSfb,const UCHAR * freqBandTable,INT totNoEst,INT maxComp,UCHAR * pPrevEnvComp,INT newDetectionAllowed)946 static void calculateCompVector(UCHAR *pAddHarmSfb,
947                                 FIXP_DBL **pTonalityMatrix,
948                                 INT ** pSignMatrix,
949                                 UCHAR *pEnvComp,
950                                 INT nSfb,
951                                 const UCHAR *freqBandTable,
952                                 INT totNoEst,
953                                 INT maxComp,
954                                 UCHAR *pPrevEnvComp,
955                                 INT newDetectionAllowed)
956 {
957 
958   INT scfBand,est,l,ll,lu,maxPosF,maxPosT;
959   FIXP_DBL maxVal;
960   INT compValue;
961   FIXP_DBL tmp;
962 
963   FDKmemclear(pEnvComp,nSfb*sizeof(UCHAR));
964 
965   for(scfBand=0; scfBand < nSfb; scfBand++){
966 
967     if(pAddHarmSfb[scfBand]){ /* A missing sine was detected */
968       ll = freqBandTable[scfBand];
969       lu = freqBandTable[scfBand+1];
970 
971       maxPosF = 0;                        /* First find the maximum*/
972       maxPosT = 0;
973       maxVal = FL2FXCONST_DBL(0.0f);
974 
975       for(est=0;est<totNoEst;est++){
976         for(l=ll; l<lu; l++){
977           if(pTonalityMatrix[est][l] > maxVal){
978             maxVal = pTonalityMatrix[est][l];
979             maxPosF = l;
980             maxPosT = est;
981           }
982         }
983       }
984 
985       /*
986        * If the maximum tonality is at the lower border of the
987        * scalefactor band, we check the sign of the adjacent channels
988        * to see if this sine is shared by the lower channel. If so, the
989        * energy of the single sine will be present in two scalefactor bands
990        * in the SBR data, which will cause problems in the decoder, when we
991        * add a sine to just one of the channels.
992        *********************************************************************/
993       if(maxPosF == ll && scfBand){
994         if(!pAddHarmSfb[scfBand - 1]) {     /* No detection below*/
995           if (pSignMatrix[maxPosT][maxPosF - 1] > 0 && pSignMatrix[maxPosT][maxPosF] < 0) {
996             /* The comp value is calulated as the tonallity value, i.e we want to
997                reduce the envelope data for this channel with as much as the tonality
998                that is spread from the channel above. (ld64(RELAXATION) = 0.31143075889) */
999             tmp = fixp_abs((FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF - 1]) + RELAXATION_LD64);
1000             tmp = (tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT-1)) + (FIXP_DBL)1;  /* shift one bit less for rounding */
1001             compValue = ((INT)(LONG)tmp) >> 1;
1002 
1003 						      /* limit the comp-value*/
1004             if (compValue > maxComp)
1005               compValue = maxComp;
1006 
1007             pEnvComp[scfBand-1] = compValue;
1008 					     }
1009 				    }
1010       }
1011 
1012       /*
1013        * Same as above, but for the upper end of the scalefactor-band.
1014        ***************************************************************/
1015       if(maxPosF == lu-1 && scfBand+1 < nSfb){        /* Upper border*/
1016         if(!pAddHarmSfb[scfBand + 1]) {
1017           if (pSignMatrix[maxPosT][maxPosF] > 0 && pSignMatrix[maxPosT][maxPosF + 1] < 0) {
1018             tmp = fixp_abs((FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF + 1]) + RELAXATION_LD64);
1019             tmp = (tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT-1)) + (FIXP_DBL)1;  /* shift one bit less for rounding */
1020             compValue = ((INT)(LONG)tmp) >> 1;
1021 
1022             if (compValue > maxComp)
1023               compValue = maxComp;
1024 
1025             pEnvComp[scfBand+1] = compValue;
1026 					 }
1027 				 }
1028       }
1029 		 }
1030 	 }
1031 
1032   if(newDetectionAllowed == 0){
1033     for(scfBand=0;scfBand<nSfb;scfBand++){
1034       if(pEnvComp[scfBand] != 0 && pPrevEnvComp[scfBand] == 0)
1035         pEnvComp[scfBand] = 0;
1036     }
1037   }
1038 
1039   /* remember the value for the next frame.*/
1040   FDKmemcpy(pPrevEnvComp,pEnvComp,nSfb*sizeof(UCHAR));
1041 }
1042 
1043 
1044 /**************************************************************************/
1045 /*!
1046   \brief     Detects where strong tonal components will be missing after
1047              HFR in the decoder.
1048 
1049 
1050   \return    none.
1051 
1052 */
1053 /**************************************************************************/
1054 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)1055 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet,
1056                                FIXP_DBL ** pQuotaBuffer,
1057                                INT ** pSignBuffer,
1058                                SCHAR* indexVector,
1059                                const SBR_FRAME_INFO *pFrameInfo,
1060                                const UCHAR* pTranInfo,
1061                                INT* pAddHarmonicsFlag,
1062                                UCHAR* pAddHarmonicsScaleFactorBands,
1063                                const UCHAR* freqBandTable,
1064                                INT nSfb,
1065                                UCHAR* envelopeCompensation,
1066                                FIXP_DBL *pNrgVector)
1067 {
1068   INT transientFlag = pTranInfo[1];
1069   INT transientPos  = pTranInfo[0];
1070   INT newDetectionAllowed;
1071   INT transientDetStart = 0;
1072 
1073   UCHAR ** detectionVectors  = h_sbrMHDet->detectionVectors;
1074   INT move                = h_sbrMHDet->move;
1075   INT noEstPerFrame       = h_sbrMHDet->noEstPerFrame;
1076   INT totNoEst            = h_sbrMHDet->totNoEst;
1077   INT prevTransientFlag   = h_sbrMHDet->previousTransientFlag;
1078   INT prevTransientFrame  = h_sbrMHDet->previousTransientFrame;
1079   INT transientPosOffset  = h_sbrMHDet->transientPosOffset;
1080   INT prevTransientPos    = h_sbrMHDet->previousTransientPos;
1081   GUIDE_VECTORS* guideVectors = h_sbrMHDet->guideVectors;
1082   INT deltaTime = h_sbrMHDet->mhParams->deltaTime;
1083   INT maxComp = h_sbrMHDet->mhParams->maxComp;
1084 
1085   int est;
1086 
1087   /*
1088   Buffer values.
1089   */
1090   FDK_ASSERT(move<=(MAX_NO_OF_ESTIMATES>>1));
1091   FDK_ASSERT(noEstPerFrame<=(MAX_NO_OF_ESTIMATES>>1));
1092 
1093   FIXP_DBL *sfmSbr[MAX_NO_OF_ESTIMATES];
1094   FIXP_DBL *sfmOrig[MAX_NO_OF_ESTIMATES];
1095   FIXP_DBL *tonalityDiff[MAX_NO_OF_ESTIMATES];
1096 
1097   for (est=0; est < MAX_NO_OF_ESTIMATES/2; est++) {
1098     sfmSbr[est]       = h_sbrMHDet->sfmSbr[est];
1099     sfmOrig[est]      = h_sbrMHDet->sfmOrig[est];
1100     tonalityDiff[est] = h_sbrMHDet->tonalityDiff[est];
1101   }
1102 
1103   C_ALLOC_SCRATCH_START(scratch_mem, FIXP_DBL, (3*MAX_NO_OF_ESTIMATES/2*MAX_FREQ_COEFFS));
1104   FIXP_DBL *scratch = scratch_mem;
1105   for (; est < MAX_NO_OF_ESTIMATES; est++) {
1106     sfmSbr[est]       = scratch; scratch+=MAX_FREQ_COEFFS;
1107     sfmOrig[est]      = scratch; scratch+=MAX_FREQ_COEFFS;
1108     tonalityDiff[est] = scratch; scratch+=MAX_FREQ_COEFFS;
1109   }
1110 
1111 
1112 
1113   /* Determine if we're allowed to detect "missing harmonics" that wasn't detected before.
1114      In order to be allowed to do new detection, there must be a transient in the current
1115      frame, or a transient in the previous frame sufficiently close to the current frame. */
1116   newDetectionAllowed = isDetectionOfNewToneAllowed(pFrameInfo,
1117                                                     &transientDetStart,
1118                                                     noEstPerFrame,
1119                                                     prevTransientFrame,
1120                                                     prevTransientPos,
1121                                                     prevTransientFlag,
1122                                                     transientPosOffset,
1123                                                     transientFlag,
1124                                                     transientPos,
1125                                                     deltaTime,
1126                                                     h_sbrMHDet);
1127 
1128   /* Calulate the variables that will be used subsequently for the actual detection */
1129   calculateDetectorInput(pQuotaBuffer,
1130                          indexVector,
1131                          tonalityDiff,
1132                          sfmOrig,
1133                          sfmSbr,
1134                          freqBandTable,
1135                          nSfb,
1136                          noEstPerFrame,
1137                          move);
1138 
1139   /* Do the actual detection using information from previous detections */
1140   detectionWithPrediction(pQuotaBuffer,
1141                           tonalityDiff,
1142                           pSignBuffer,
1143                           nSfb,
1144                           freqBandTable,
1145                           sfmOrig,
1146                           sfmSbr,
1147                           detectionVectors,
1148                           h_sbrMHDet->guideScfb,
1149                           guideVectors,
1150                           noEstPerFrame,
1151                           transientDetStart,
1152                           totNoEst,
1153                           newDetectionAllowed,
1154                           pAddHarmonicsFlag,
1155                           pAddHarmonicsScaleFactorBands,
1156                           pNrgVector,
1157                           h_sbrMHDet->mhParams);
1158 
1159   /* Calculate the comp vector, so that the energy can be
1160      compensated for a sine between two QMF-bands. */
1161   calculateCompVector(pAddHarmonicsScaleFactorBands,
1162                       pQuotaBuffer,
1163                       pSignBuffer,
1164                       envelopeCompensation,
1165                       nSfb,
1166                       freqBandTable,
1167                       totNoEst,
1168                       maxComp,
1169                       h_sbrMHDet->prevEnvelopeCompensation,
1170                       newDetectionAllowed);
1171 
1172   for (est=0; est < move; est++) {
1173     FDKmemcpy(tonalityDiff[est], tonalityDiff[est + noEstPerFrame], sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1174     FDKmemcpy(sfmOrig[est], sfmOrig[est + noEstPerFrame], sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1175     FDKmemcpy(sfmSbr[est], sfmSbr[est + noEstPerFrame], sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1176   }
1177   C_ALLOC_SCRATCH_END(scratch, FIXP_DBL, (3*MAX_NO_OF_ESTIMATES/2*MAX_FREQ_COEFFS));
1178 
1179 
1180 }
1181 
1182 /**************************************************************************/
1183 /*!
1184   \brief     Initialize an instance of the missing harmonics detector.
1185 
1186 
1187   \return    errorCode, noError if OK.
1188 
1189 */
1190 /**************************************************************************/
1191 INT
FDKsbrEnc_CreateSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet,INT chan)1192 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (
1193                                    HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet,
1194                                    INT chan)
1195 {
1196   HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1197   INT i;
1198 
1199   UCHAR* detectionVectors    = GetRam_Sbr_detectionVectors(chan);
1200   UCHAR* guideVectorDetected = GetRam_Sbr_guideVectorDetected(chan);
1201   FIXP_DBL* guideVectorDiff  = GetRam_Sbr_guideVectorDiff(chan);
1202   FIXP_DBL* guideVectorOrig  = GetRam_Sbr_guideVectorOrig(chan);
1203 
1204   FDKmemclear (hs,sizeof(SBR_MISSING_HARMONICS_DETECTOR));
1205 
1206   hs->prevEnvelopeCompensation = GetRam_Sbr_prevEnvelopeCompensation(chan);
1207   hs->guideScfb                = GetRam_Sbr_guideScfb(chan);
1208 
1209   for(i=0; i<MAX_NO_OF_ESTIMATES; i++) {
1210     hs->guideVectors[i].guideVectorDiff = guideVectorDiff + (i*MAX_FREQ_COEFFS);
1211     hs->guideVectors[i].guideVectorOrig = guideVectorOrig + (i*MAX_FREQ_COEFFS);
1212     hs->detectionVectors[i] = detectionVectors + (i*MAX_FREQ_COEFFS);
1213     hs->guideVectors[i].guideVectorDetected = guideVectorDetected + (i*MAX_FREQ_COEFFS);
1214   }
1215 
1216   return 0;
1217 }
1218 
1219 
1220 /**************************************************************************/
1221 /*!
1222   \brief     Initialize an instance of the missing harmonics detector.
1223 
1224 
1225   \return    errorCode, noError if OK.
1226 
1227 */
1228 /**************************************************************************/
1229 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)1230 FDKsbrEnc_InitSbrMissingHarmonicsDetector (
1231                                    HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet,
1232                                    INT sampleFreq,
1233                                    INT frameSize,
1234                                    INT nSfb,
1235                                    INT qmfNoChannels,
1236                                    INT totNoEst,
1237                                    INT move,
1238                                    INT noEstPerFrame,
1239                                    UINT sbrSyntaxFlags
1240                                   )
1241 {
1242   HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1243   int i;
1244 
1245   FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES);
1246 
1247   if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)
1248   {
1249     switch(frameSize){
1250     case 1024:
1251     case 512:
1252         hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
1253         hs->timeSlots          = 16;
1254         break;
1255     case 960:
1256     case 480:
1257         hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD;
1258         hs->timeSlots          = 15;
1259         break;
1260     default:
1261         return -1;
1262     }
1263   } else
1264   {
1265     switch(frameSize){
1266     case 2048:
1267     case 1024:
1268         hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048;
1269         hs->timeSlots          = NUMBER_TIME_SLOTS_2048;
1270         break;
1271     case 1920:
1272     case 960:
1273         hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920;
1274         hs->timeSlots          = NUMBER_TIME_SLOTS_1920;
1275         break;
1276     default:
1277         return -1;
1278     }
1279   }
1280 
1281   if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) {
1282     hs->mhParams = &paramsAacLd;
1283   } else
1284   hs->mhParams = &paramsAac;
1285 
1286   hs->qmfNoChannels = qmfNoChannels;
1287   hs->sampleFreq = sampleFreq;
1288   hs->nSfb = nSfb;
1289 
1290   hs->totNoEst = totNoEst;
1291   hs->move = move;
1292   hs->noEstPerFrame = noEstPerFrame;
1293 
1294   for(i=0; i<totNoEst; i++) {
1295     FDKmemclear (hs->guideVectors[i].guideVectorDiff,sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1296     FDKmemclear (hs->guideVectors[i].guideVectorOrig,sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1297     FDKmemclear (hs->detectionVectors[i],sizeof(UCHAR)*MAX_FREQ_COEFFS);
1298     FDKmemclear (hs->guideVectors[i].guideVectorDetected,sizeof(UCHAR)*MAX_FREQ_COEFFS);
1299   }
1300 
1301   //for(i=0; i<totNoEst/2; i++) {
1302   for(i=0; i<MAX_NO_OF_ESTIMATES/2; i++) {
1303     FDKmemclear (hs->tonalityDiff[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1304     FDKmemclear (hs->sfmOrig[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1305     FDKmemclear (hs->sfmSbr[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS);
1306   }
1307 
1308   FDKmemclear ( hs->prevEnvelopeCompensation, sizeof(UCHAR)*MAX_FREQ_COEFFS);
1309   FDKmemclear ( hs->guideScfb, sizeof(UCHAR)*MAX_FREQ_COEFFS);
1310 
1311   hs->previousTransientFlag = 0;
1312   hs->previousTransientFrame = 0;
1313   hs->previousTransientPos = 0;
1314 
1315   return (0);
1316 }
1317 
1318 /**************************************************************************/
1319 /*!
1320   \brief     Deletes an instance of the missing harmonics detector.
1321 
1322 
1323   \return    none.
1324 
1325 */
1326 /**************************************************************************/
1327 void
FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet)1328 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet)
1329 {
1330   if (hSbrMHDet) {
1331     HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet;
1332 
1333     FreeRam_Sbr_detectionVectors(&hs->detectionVectors[0]);
1334     FreeRam_Sbr_guideVectorDetected(&hs->guideVectors[0].guideVectorDetected);
1335     FreeRam_Sbr_guideVectorDiff(&hs->guideVectors[0].guideVectorDiff);
1336     FreeRam_Sbr_guideVectorOrig(&hs->guideVectors[0].guideVectorOrig);
1337     FreeRam_Sbr_prevEnvelopeCompensation(&hs->prevEnvelopeCompensation);
1338     FreeRam_Sbr_guideScfb(&hs->guideScfb);
1339 
1340   }
1341 }
1342 
1343 /**************************************************************************/
1344 /*!
1345   \brief     Resets an instance of the missing harmonics detector.
1346 
1347 
1348   \return    error code, noError if OK.
1349 
1350 */
1351 /**************************************************************************/
1352 INT
FDKsbrEnc_ResetSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,INT nSfb)1353 FDKsbrEnc_ResetSbrMissingHarmonicsDetector (HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector,
1354                                   INT nSfb)
1355 {
1356   int i;
1357   FIXP_DBL tempGuide[MAX_FREQ_COEFFS];
1358   UCHAR tempGuideInt[MAX_FREQ_COEFFS];
1359   INT nSfbPrev;
1360 
1361   nSfbPrev = hSbrMissingHarmonicsDetector->nSfb;
1362   hSbrMissingHarmonicsDetector->nSfb = nSfb;
1363 
1364   FDKmemcpy( tempGuideInt, hSbrMissingHarmonicsDetector->guideScfb, nSfbPrev * sizeof(UCHAR) );
1365 
1366   if ( nSfb > nSfbPrev ) {
1367     for ( i = 0; i < (nSfb - nSfbPrev); i++ ) {
1368       hSbrMissingHarmonicsDetector->guideScfb[i] = 0;
1369     }
1370 
1371     for ( i = 0; i < nSfbPrev; i++ ) {
1372       hSbrMissingHarmonicsDetector->guideScfb[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
1373     }
1374   }
1375   else {
1376     for ( i = 0; i < nSfb; i++ ) {
1377       hSbrMissingHarmonicsDetector->guideScfb[i] = tempGuideInt[i + (nSfbPrev-nSfb)];
1378     }
1379   }
1380 
1381   FDKmemcpy ( tempGuide, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff, nSfbPrev * sizeof(FIXP_DBL) );
1382 
1383   if (nSfb > nSfbPrev ) {
1384     for ( i = 0; i < (nSfb - nSfbPrev); i++ ) {
1385       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f);
1386     }
1387 
1388     for ( i = 0; i < nSfbPrev; i++ ) {
1389       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i + (nSfb - nSfbPrev)] = tempGuide[i];
1390     }
1391   }
1392   else {
1393     for ( i = 0; i < nSfb; i++  ) {
1394       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = tempGuide[i + (nSfbPrev-nSfb)];
1395     }
1396   }
1397 
1398   FDKmemcpy ( tempGuide, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig, nSfbPrev * sizeof(FIXP_DBL) );
1399 
1400   if ( nSfb > nSfbPrev ) {
1401     for ( i = 0; i< (nSfb - nSfbPrev); i++ ) {
1402       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f);
1403     }
1404 
1405     for ( i = 0; i < nSfbPrev; i++ ) {
1406       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i + (nSfb - nSfbPrev)] = tempGuide[i];
1407     }
1408   }
1409   else {
1410     for ( i = 0; i < nSfb; i++ ) {
1411       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = tempGuide[i + (nSfbPrev-nSfb)];
1412     }
1413   }
1414 
1415   FDKmemcpy ( tempGuideInt, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected, nSfbPrev * sizeof(UCHAR) );
1416 
1417   if ( nSfb > nSfbPrev ) {
1418     for ( i = 0; i < (nSfb - nSfbPrev); i++ ) {
1419       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = 0;
1420     }
1421 
1422     for ( i = 0; i < nSfbPrev; i++ ) {
1423       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
1424     }
1425   }
1426   else {
1427     for ( i = 0; i < nSfb; i++ ) {
1428       hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = tempGuideInt[i + (nSfbPrev-nSfb)];
1429     }
1430   }
1431 
1432   FDKmemcpy ( tempGuideInt, hSbrMissingHarmonicsDetector->prevEnvelopeCompensation, nSfbPrev * sizeof(UCHAR) );
1433 
1434   if ( nSfb > nSfbPrev ) {
1435     for ( i = 0; i < (nSfb - nSfbPrev); i++ ) {
1436       hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = 0;
1437     }
1438 
1439     for ( i = 0; i < nSfbPrev; i++ ) {
1440       hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i + (nSfb - nSfbPrev)] = tempGuideInt[i];
1441     }
1442   }
1443   else {
1444     for ( i = 0; i < nSfb; i++ ) {
1445       hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = tempGuideInt[i + (nSfbPrev-nSfb)];
1446     }
1447   }
1448 
1449   return 0;
1450 }
1451 
1452