2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
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.
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.
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.
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.
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:
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.
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.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
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.
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."
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.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
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.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
90 #include "genericStds.h"
92 #define SFM_SHIFT 2 /* Attention: SFM_SCALE depends on SFM_SHIFT */
93 #define SFM_SCALE (MAXVAL_DBL >> SFM_SHIFT) /* 1.0 >> SFM_SHIFT */
96 /*!< Detector Parameters for AAC core codec. */
97 static const DETECTOR_PARAMETERS_MH paramsAac
= {
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 */
116 /*!< Detector Parameters for AAC LD core codec. */
117 static const DETECTOR_PARAMETERS_MH paramsAacLd
= {
118 16, /*!< Delta time. */
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 */
137 /**************************************************************************/
139 \brief Calculates the difference in tonality between original and SBR
140 for a given time and frequency region.
142 The values for pDiffMapped2Scfb are scaled by RELAXATION
147 /**************************************************************************/
148 static void diff(FIXP_DBL
*RESTRICT pTonalityOrig
,
149 FIXP_DBL
*pDiffMapped2Scfb
,
150 const UCHAR
*RESTRICT pFreqBandTable
,
155 FIXP_DBL maxValOrig
, maxValSbr
, tmp
;
158 for(i
=0; i
< nScfb
; i
++){
159 ll
= pFreqBandTable
[i
];
160 lu
= pFreqBandTable
[i
+1];
162 maxValOrig
= FL2FXCONST_DBL(0.0f
);
163 maxValSbr
= FL2FXCONST_DBL(0.0f
);
166 maxValOrig
= fixMax(maxValOrig
, pTonalityOrig
[k
]);
167 maxValSbr
= fixMax(maxValSbr
, pTonalityOrig
[indexVector
[k
]]);
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
)));
175 pDiffMapped2Scfb
[i
] = maxValOrig
;
181 /**************************************************************************/
183 \brief Calculates a flatness measure of the tonality measures.
185 Calculation of the power function and using scalefactor for basis:
188 z' = CalcLd(z) = y*CalcLd(x) + y*k;
193 z' = CalcLd64(z) = y*CalcLd64(x)/64 + y*k/64;
196 The values pSfmOrigVec and pSfmSbrVec are scaled by the factor 1/4.0
201 /**************************************************************************/
202 static void calculateFlatnessMeasure(FIXP_DBL
*pQuotaBuffer
,
204 FIXP_DBL
*pSfmOrigVec
,
205 FIXP_DBL
*pSfmSbrVec
,
206 const UCHAR
*pFreqBandTable
,
210 FIXP_DBL invBands
,tmp1
,tmp2
;
211 INT shiftFac0
,shiftFacSum0
;
212 INT shiftFac1
,shiftFacSum1
;
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);
223 FIXP_DBL amOrig
,amTransp
,gmOrig
,gmTransp
,sfmOrig
,sfmTransp
;
224 invBands
= GetInvInt(lu
-ll
);
227 amOrig
= amTransp
= FL2FXCONST_DBL(0.0f
);
228 gmOrig
= gmTransp
= (FIXP_DBL
)MAXVAL_DBL
;
230 for(j
= ll
; j
<lu
; j
++) {
231 sfmOrig
= pQuotaBuffer
[j
];
232 sfmTransp
= pQuotaBuffer
[indexVector
[j
]];
234 amOrig
+= fMult(sfmOrig
, invBands
);
235 amTransp
+= fMult(sfmTransp
, invBands
);
237 shiftFac0
= CountLeadingBits(sfmOrig
);
238 shiftFac1
= CountLeadingBits(sfmTransp
);
240 gmOrig
= fMult(gmOrig
, sfmOrig
<<shiftFac0
);
241 gmTransp
= fMult(gmTransp
, sfmTransp
<<shiftFac1
);
243 shiftFacSum0
+= shiftFac0
;
244 shiftFacSum1
+= shiftFac1
;
247 if (gmOrig
> FL2FXCONST_DBL(0.0f
)) {
249 tmp1
= CalcLdData(gmOrig
); /* CalcLd64(x)/64 */
250 tmp1
= fMult(invBands
, tmp1
); /* y*CalcLd64(x)/64 */
253 accu
= (FIXP_DBL
)-shiftFacSum0
<< (DFRACT_BITS
-1-8);
254 tmp2
= fMultDiv2(invBands
, accu
) << (2+1);
256 tmp2
= tmp1
+ tmp2
; /* y*CalcLd64(x)/64 + y*k/64 */
257 gmOrig
= CalcInvLdData(tmp2
); /* CalcInvLd64(z'); */
260 gmOrig
= FL2FXCONST_DBL(0.0f
);
263 if (gmTransp
> FL2FXCONST_DBL(0.0f
)) {
265 tmp1
= CalcLdData(gmTransp
); /* CalcLd64(x)/64 */
266 tmp1
= fMult(invBands
, tmp1
); /* y*CalcLd64(x)/64 */
269 accu
= (FIXP_DBL
)-shiftFacSum1
<< (DFRACT_BITS
-1-8);
270 tmp2
= fMultDiv2(invBands
, accu
) << (2+1);
272 tmp2
= tmp1
+ tmp2
; /* y*CalcLd64(x)/64 + y*k/64 */
273 gmTransp
= CalcInvLdData(tmp2
); /* CalcInvLd64(z'); */
276 gmTransp
= FL2FXCONST_DBL(0.0f
);
278 if ( amOrig
!= FL2FXCONST_DBL(0.0f
) )
279 pSfmOrigVec
[i
] = FDKsbrEnc_LSI_divide_scale_fract(gmOrig
,amOrig
,SFM_SCALE
);
281 if ( amTransp
!= FL2FXCONST_DBL(0.0f
) )
282 pSfmSbrVec
[i
] = FDKsbrEnc_LSI_divide_scale_fract(gmTransp
,amTransp
,SFM_SCALE
);
287 /**************************************************************************/
289 \brief Calculates the input to the missing harmonics detection.
295 /**************************************************************************/
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
,
311 for (est
=0; est
< noEstPerFrame
; est
++) {
313 diff(pQuotaBuffer
[est
+move
],
314 tonalityDiff
[est
+move
],
319 calculateFlatnessMeasure(pQuotaBuffer
[est
+ move
],
321 pSfmOrig
[est
+ move
],
329 /**************************************************************************/
331 \brief Checks that the detection is not due to a LP filter
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
340 /**************************************************************************/
341 static void removeLowPassDetection(UCHAR
*RESTRICT pAddHarmSfb
,
342 UCHAR
**RESTRICT pDetectionVectors
,
346 const UCHAR
*RESTRICT pFreqBandTable
,
347 FIXP_DBL
*RESTRICT pNrgVector
,
348 THRES_HOLDS mhThresh
)
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
;
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];
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
){
370 maxValLD64
= valLD64
;
372 if(maxValLD64
> mhThresh
.derivThresMaxLD64
) {
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];
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
;
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
;
405 if(maxValLD64
> mhThresh
.derivThresMaxLD64
&& maxValAboveLD64
< mhThresh
.derivThresAboveLD64
){
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
) {
427 if(maxDerivPos
>= pFreqBandTable
[i
] && maxDerivPos
< pFreqBandTable
[i
+1])
433 for(est
= start
; est
< stop
; est
++){
434 pDetectionVectors
[est
][i
] = 0;
440 /**************************************************************************/
442 \brief Checks if it is allowed to detect a missing tone, that wasn't
446 \return newDetectionAllowed flag.
449 /**************************************************************************/
450 static INT
isDetectionOfNewToneAllowed(const SBR_FRAME_INFO
*pFrameInfo
,
451 INT
*pDetectionStartPos
,
453 INT prevTransientFrame
,
454 INT prevTransientPos
,
455 INT prevTransientFlag
,
456 INT transientPosOffset
,
460 HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector
)
462 INT transientFrame
, newDetectionAllowed
;
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 *****************************************************************************/
471 if(transientPos
+ transientPosOffset
< pFrameInfo
->borders
[pFrameInfo
->nEnvelopes
])
473 if(noEstPerFrame
> 1){
474 if(transientPos
+ transientPosOffset
> h_sbrMissingHarmonicsDetector
->timeSlots
>> 1){
475 *pDetectionStartPos
= noEstPerFrame
;
478 *pDetectionStartPos
= noEstPerFrame
>> 1;
483 *pDetectionStartPos
= noEstPerFrame
;
487 if(prevTransientFlag
&& !prevTransientFrame
){
489 *pDetectionStartPos
= 0;
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;
501 newDetectionAllowed
= 1;
504 if(prevTransientFrame
&&
505 fixp_abs(pFrameInfo
->borders
[0] - (prevTransientPos
+ transientPosOffset
-
506 h_sbrMissingHarmonicsDetector
->timeSlots
)) < deltaTime
)
507 newDetectionAllowed
= 1;
508 *pDetectionStartPos
= 0;
511 h_sbrMissingHarmonicsDetector
->previousTransientFlag
= transientFlag
;
512 h_sbrMissingHarmonicsDetector
->previousTransientFrame
= transientFrame
;
513 h_sbrMissingHarmonicsDetector
->previousTransientPos
= transientPos
;
515 return (newDetectionAllowed
);
519 /**************************************************************************/
521 \brief Cleans up the detection after a transient.
527 /**************************************************************************/
528 static void transientCleanUp(FIXP_DBL
**quotaBuffer
,
530 UCHAR
**detectionVectors
,
532 UCHAR
*pPrevAddHarmSfb
,
534 const UCHAR
*pFreqBandTable
,
537 INT newDetectionAllowed
,
538 FIXP_DBL
*pNrgVector
,
539 THRES_HOLDS mhThresh
)
543 for(est
=start
; est
< stop
; est
++) {
544 for(i
=0; i
<nSfb
; i
++) {
545 pAddHarmSfb
[i
] = pAddHarmSfb
[i
] || detectionVectors
[est
][i
];
549 if(newDetectionAllowed
== 1){
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];
558 /* detection in adjacent channels.*/
559 if(pAddHarmSfb
[i
] && pAddHarmSfb
[i
+1]) {
560 FIXP_DBL maxVal1
, maxVal2
;
561 INT maxPos1
, maxPos2
, maxPosTime1
, maxPosTime2
;
563 li
= pFreqBandTable
[i
];
564 ui
= pFreqBandTable
[i
+1];
566 /* Find maximum tonality in the the two scf bands.*/
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
];
580 li
= pFreqBandTable
[i
+1];
581 ui
= pFreqBandTable
[i
+2];
583 /* Find maximum tonality in the the two scf bands.*/
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
];
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){
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;
609 if(pPrevAddHarmSfb
[i
] == 0 && pPrevAddHarmSfb
[i
+1] == 1){
610 /* Keep the upper, remove the lower.*/
612 for(est
=start
; est
<stop
; est
++){
613 detectionVectors
[est
][i
] = 0;
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;
629 if(signBuffer
[maxPosTime2
][maxPos2
] < 0 && signBuffer
[maxPosTime2
][maxPos1
] > 0){
630 /* Keep the upper, remove the lower.*/
632 for(est
=start
; est
<stop
; est
++){
633 detectionVectors
[est
][i
] = 0;
643 /* Make sure that the detection is not the cut-off of a low pass filter. */
644 removeLowPassDetection(pAddHarmSfb
,
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 *************************************************************************/
659 if(pAddHarmSfb
[i
] - pPrevAddHarmSfb
[i
] > 0)
666 /**************************************************************************/
668 \brief Do detection for one tonality estimate.
674 /**************************************************************************/
675 static void detection(FIXP_DBL
*quotaBuffer
,
676 FIXP_DBL
*pDiffVecScfb
,
679 const UCHAR
*pFreqBandTable
,
682 GUIDE_VECTORS guideVectors
,
683 GUIDE_VECTORS newGuideVectors
,
684 THRES_HOLDS mhThresh
)
688 FIXP_DBL thresTemp
,thresOrig
;
691 * Do detection on the difference vector, i.e. the difference between
692 * the original and the transposed.
693 *********************************************************************/
696 thresTemp
= (guideVectors
.guideVectorDiff
[i
] != FL2FXCONST_DBL(0.0f
))
697 ? fixMax(fMult(mhThresh
.decayGuideDiff
,guideVectors
.guideVectorDiff
[i
]), mhThresh
.thresHoldDiffGuide
)
698 : mhThresh
.thresHoldDiff
;
700 thresTemp
= fixMin(thresTemp
, mhThresh
.thresHoldDiff
);
702 if(pDiffVecScfb
[i
] > thresTemp
){
704 newGuideVectors
.guideVectorDiff
[i
] = pDiffVecScfb
[i
];
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
;
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 ****************************************************/
723 ll
= pFreqBandTable
[i
];
724 lu
= pFreqBandTable
[i
+1];
726 thresOrig
= fixMax(fMult(guideVectors
.guideVectorOrig
[i
], mhThresh
.decayGuideOrig
), mhThresh
.thresHoldToneGuide
);
727 thresOrig
= fixMin(thresOrig
, mhThresh
.thresHoldTone
);
729 if(guideVectors
.guideVectorOrig
[i
] != FL2FXCONST_DBL(0.0f
)){
731 if(quotaBuffer
[j
] > thresOrig
){
733 newGuideVectors
.guideVectorOrig
[i
] = quotaBuffer
[j
];
740 * Check for multiple sines in the transposed signal,
741 * where there is only one in the original.
742 ****************************************************/
743 thresOrig
= mhThresh
.thresHoldTone
;
746 ll
= pFreqBandTable
[i
];
747 lu
= pFreqBandTable
[i
+1];
749 if(pHarmVec
[i
] == 0){
752 if(quotaBuffer
[j
] > thresOrig
&& (sfmSbr
[i
] > mhThresh
.sfmThresSbr
&& sfmOrig
[i
] < mhThresh
.sfmThresOrig
)){
754 newGuideVectors
.guideVectorOrig
[i
] = quotaBuffer
[j
];
760 ll
= pFreqBandTable
[i
];
763 if(quotaBuffer
[ll
] > mhThresh
.thresHoldTone
&& (pDiffVecScfb
[i
+1] < mhThresh
.invThresHoldTone
|| pDiffVecScfb
[i
-1] < mhThresh
.invThresHoldTone
)){
765 newGuideVectors
.guideVectorOrig
[i
] = quotaBuffer
[ll
];
769 if(quotaBuffer
[ll
] > mhThresh
.thresHoldTone
&& pDiffVecScfb
[i
+1] < mhThresh
.invThresHoldTone
){
771 newGuideVectors
.guideVectorOrig
[i
] = quotaBuffer
[ll
];
781 /**************************************************************************/
783 \brief Do detection for every tonality estimate, using forward prediction.
789 /**************************************************************************/
790 static void detectionWithPrediction(FIXP_DBL
**quotaBuffer
,
791 FIXP_DBL
**pDiffVecScfb
,
794 const UCHAR
* pFreqBandTable
,
797 UCHAR
**detectionVectors
,
798 UCHAR
*pPrevAddHarmSfb
,
799 GUIDE_VECTORS
*guideVectors
,
803 INT newDetectionAllowed
,
806 FIXP_DBL
*pNrgVector
,
807 const DETECTOR_PARAMETERS_MH
*mhParams
)
812 FDKmemclear(pAddHarmSfb
,nSfb
*sizeof(UCHAR
));
814 if(newDetectionAllowed
){
817 start
= detectionStart
;
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
));
834 for(est
= start
; est
< totNoEst
; est
++){
837 * Do detection on the current frame using
838 * guide-info from the previous.
839 *******************************************/
841 FDKmemcpy(guideVectors
[est
].guideVectorDetected
,detectionVectors
[est
-1],nSfb
*sizeof(UCHAR
));
844 FDKmemclear(detectionVectors
[est
], nSfb
*sizeof(UCHAR
));
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
));
851 detection(quotaBuffer
[est
],
854 detectionVectors
[est
],
860 mhParams
->thresHolds
);
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
));
867 detection(quotaBuffer
[est
],
870 detectionVectors
[est
],
876 mhParams
->thresHolds
);
881 /* Clean up the detection.*/
882 transientCleanUp(quotaBuffer
,
893 mhParams
->thresHolds
);
898 for(i
=0; i
<nSfb
; i
++){
905 FDKmemcpy(pPrevAddHarmSfb
, pAddHarmSfb
, nSfb
*sizeof(UCHAR
));
906 FDKmemcpy(guideVectors
[0].guideVectorDetected
,pAddHarmSfb
,nSfb
*sizeof(INT
));
908 for(i
=0; i
<nSfb
; i
++){
910 guideVectors
[0].guideVectorDiff
[i
] = FL2FXCONST_DBL(0.0f
);
911 guideVectors
[0].guideVectorOrig
[i
] = FL2FXCONST_DBL(0.0f
);
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
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
];
920 if(guideVectors
[est
].guideVectorOrig
[i
] != FL2FXCONST_DBL(0.0f
)){
921 guideVectors
[0].guideVectorOrig
[i
] = guideVectors
[est
].guideVectorOrig
[i
];
930 /**************************************************************************/
932 \brief Calculates a compensation vector for the energy data.
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.
945 /**************************************************************************/
946 static void calculateCompVector(UCHAR
*pAddHarmSfb
,
947 FIXP_DBL
**pTonalityMatrix
,
951 const UCHAR
*freqBandTable
,
955 INT newDetectionAllowed
)
958 INT scfBand
,est
,l
,ll
,lu
,maxPosF
,maxPosT
;
963 FDKmemclear(pEnvComp
,nSfb
*sizeof(UCHAR
));
965 for(scfBand
=0; scfBand
< nSfb
; scfBand
++){
967 if(pAddHarmSfb
[scfBand
]){ /* A missing sine was detected */
968 ll
= freqBandTable
[scfBand
];
969 lu
= freqBandTable
[scfBand
+1];
971 maxPosF
= 0; /* First find the maximum*/
973 maxVal
= FL2FXCONST_DBL(0.0f
);
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
];
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;
1003 /* limit the comp-value*/
1004 if (compValue
> maxComp
)
1005 compValue
= maxComp
;
1007 pEnvComp
[scfBand
-1] = compValue
;
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;
1022 if (compValue
> maxComp
)
1023 compValue
= maxComp
;
1025 pEnvComp
[scfBand
+1] = compValue
;
1032 if(newDetectionAllowed
== 0){
1033 for(scfBand
=0;scfBand
<nSfb
;scfBand
++){
1034 if(pEnvComp
[scfBand
] != 0 && pPrevEnvComp
[scfBand
] == 0)
1035 pEnvComp
[scfBand
] = 0;
1039 /* remember the value for the next frame.*/
1040 FDKmemcpy(pPrevEnvComp
,pEnvComp
,nSfb
*sizeof(UCHAR
));
1044 /**************************************************************************/
1046 \brief Detects where strong tonal components will be missing after
1053 /**************************************************************************/
1055 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet
,
1056 FIXP_DBL
** pQuotaBuffer
,
1059 const SBR_FRAME_INFO
*pFrameInfo
,
1060 const UCHAR
* pTranInfo
,
1061 INT
* pAddHarmonicsFlag
,
1062 UCHAR
* pAddHarmonicsScaleFactorBands
,
1063 const UCHAR
* freqBandTable
,
1065 UCHAR
* envelopeCompensation
,
1066 FIXP_DBL
*pNrgVector
)
1068 INT transientFlag
= pTranInfo
[1];
1069 INT transientPos
= pTranInfo
[0];
1070 INT newDetectionAllowed
;
1071 INT transientDetStart
= 0;
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
;
1090 FDK_ASSERT(move
<=(MAX_NO_OF_ESTIMATES
>>1));
1091 FDK_ASSERT(noEstPerFrame
<=(MAX_NO_OF_ESTIMATES
>>1));
1093 FIXP_DBL
*sfmSbr
[MAX_NO_OF_ESTIMATES
];
1094 FIXP_DBL
*sfmOrig
[MAX_NO_OF_ESTIMATES
];
1095 FIXP_DBL
*tonalityDiff
[MAX_NO_OF_ESTIMATES
];
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
];
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
;
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
,
1128 /* Calulate the variables that will be used subsequently for the actual detection */
1129 calculateDetectorInput(pQuotaBuffer
,
1139 /* Do the actual detection using information from previous detections */
1140 detectionWithPrediction(pQuotaBuffer
,
1148 h_sbrMHDet
->guideScfb
,
1153 newDetectionAllowed
,
1155 pAddHarmonicsScaleFactorBands
,
1157 h_sbrMHDet
->mhParams
);
1159 /* Calculate the comp vector, so that the energy can be
1160 compensated for a sine between two QMF-bands. */
1161 calculateCompVector(pAddHarmonicsScaleFactorBands
,
1164 envelopeCompensation
,
1169 h_sbrMHDet
->prevEnvelopeCompensation
,
1170 newDetectionAllowed
);
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
);
1177 C_ALLOC_SCRATCH_END(scratch
, FIXP_DBL
, (3*MAX_NO_OF_ESTIMATES
/2*MAX_FREQ_COEFFS
));
1182 /**************************************************************************/
1184 \brief Initialize an instance of the missing harmonics detector.
1187 \return errorCode, noError if OK.
1190 /**************************************************************************/
1192 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (
1193 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet
,
1196 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs
= hSbrMHDet
;
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
);
1204 FDKmemclear (hs
,sizeof(SBR_MISSING_HARMONICS_DETECTOR
));
1206 hs
->prevEnvelopeCompensation
= GetRam_Sbr_prevEnvelopeCompensation(chan
);
1207 hs
->guideScfb
= GetRam_Sbr_guideScfb(chan
);
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
);
1220 /**************************************************************************/
1222 \brief Initialize an instance of the missing harmonics detector.
1225 \return errorCode, noError if OK.
1228 /**************************************************************************/
1230 FDKsbrEnc_InitSbrMissingHarmonicsDetector (
1231 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet
,
1242 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs
= hSbrMHDet
;
1245 FDK_ASSERT(totNoEst
<= MAX_NO_OF_ESTIMATES
);
1247 if (sbrSyntaxFlags
& SBR_SYNTAX_LOW_DELAY
)
1252 hs
->transientPosOffset
= FRAME_MIDDLE_SLOT_512LD
;
1257 hs
->transientPosOffset
= FRAME_MIDDLE_SLOT_512LD
;
1268 hs
->transientPosOffset
= FRAME_MIDDLE_SLOT_2048
;
1269 hs
->timeSlots
= NUMBER_TIME_SLOTS_2048
;
1273 hs
->transientPosOffset
= FRAME_MIDDLE_SLOT_1920
;
1274 hs
->timeSlots
= NUMBER_TIME_SLOTS_1920
;
1281 if (sbrSyntaxFlags
& SBR_SYNTAX_LOW_DELAY
) {
1282 hs
->mhParams
= ¶msAacLd
;
1284 hs
->mhParams
= ¶msAac
;
1286 hs
->qmfNoChannels
= qmfNoChannels
;
1287 hs
->sampleFreq
= sampleFreq
;
1290 hs
->totNoEst
= totNoEst
;
1292 hs
->noEstPerFrame
= noEstPerFrame
;
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
);
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
);
1308 FDKmemclear ( hs
->prevEnvelopeCompensation
, sizeof(UCHAR
)*MAX_FREQ_COEFFS
);
1309 FDKmemclear ( hs
->guideScfb
, sizeof(UCHAR
)*MAX_FREQ_COEFFS
);
1311 hs
->previousTransientFlag
= 0;
1312 hs
->previousTransientFrame
= 0;
1313 hs
->previousTransientPos
= 0;
1318 /**************************************************************************/
1320 \brief Deletes an instance of the missing harmonics detector.
1326 /**************************************************************************/
1328 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet
)
1331 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs
= hSbrMHDet
;
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
);
1343 /**************************************************************************/
1345 \brief Resets an instance of the missing harmonics detector.
1348 \return error code, noError if OK.
1351 /**************************************************************************/
1353 FDKsbrEnc_ResetSbrMissingHarmonicsDetector (HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector
,
1357 FIXP_DBL tempGuide
[MAX_FREQ_COEFFS
];
1358 UCHAR tempGuideInt
[MAX_FREQ_COEFFS
];
1361 nSfbPrev
= hSbrMissingHarmonicsDetector
->nSfb
;
1362 hSbrMissingHarmonicsDetector
->nSfb
= nSfb
;
1364 FDKmemcpy( tempGuideInt
, hSbrMissingHarmonicsDetector
->guideScfb
, nSfbPrev
* sizeof(UCHAR
) );
1366 if ( nSfb
> nSfbPrev
) {
1367 for ( i
= 0; i
< (nSfb
- nSfbPrev
); i
++ ) {
1368 hSbrMissingHarmonicsDetector
->guideScfb
[i
] = 0;
1371 for ( i
= 0; i
< nSfbPrev
; i
++ ) {
1372 hSbrMissingHarmonicsDetector
->guideScfb
[i
+ (nSfb
- nSfbPrev
)] = tempGuideInt
[i
];
1376 for ( i
= 0; i
< nSfb
; i
++ ) {
1377 hSbrMissingHarmonicsDetector
->guideScfb
[i
] = tempGuideInt
[i
+ (nSfbPrev
-nSfb
)];
1381 FDKmemcpy ( tempGuide
, hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDiff
, nSfbPrev
* sizeof(FIXP_DBL
) );
1383 if (nSfb
> nSfbPrev
) {
1384 for ( i
= 0; i
< (nSfb
- nSfbPrev
); i
++ ) {
1385 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDiff
[i
] = FL2FXCONST_DBL(0.0f
);
1388 for ( i
= 0; i
< nSfbPrev
; i
++ ) {
1389 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDiff
[i
+ (nSfb
- nSfbPrev
)] = tempGuide
[i
];
1393 for ( i
= 0; i
< nSfb
; i
++ ) {
1394 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDiff
[i
] = tempGuide
[i
+ (nSfbPrev
-nSfb
)];
1398 FDKmemcpy ( tempGuide
, hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorOrig
, nSfbPrev
* sizeof(FIXP_DBL
) );
1400 if ( nSfb
> nSfbPrev
) {
1401 for ( i
= 0; i
< (nSfb
- nSfbPrev
); i
++ ) {
1402 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorOrig
[i
] = FL2FXCONST_DBL(0.0f
);
1405 for ( i
= 0; i
< nSfbPrev
; i
++ ) {
1406 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorOrig
[i
+ (nSfb
- nSfbPrev
)] = tempGuide
[i
];
1410 for ( i
= 0; i
< nSfb
; i
++ ) {
1411 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorOrig
[i
] = tempGuide
[i
+ (nSfbPrev
-nSfb
)];
1415 FDKmemcpy ( tempGuideInt
, hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDetected
, nSfbPrev
* sizeof(UCHAR
) );
1417 if ( nSfb
> nSfbPrev
) {
1418 for ( i
= 0; i
< (nSfb
- nSfbPrev
); i
++ ) {
1419 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDetected
[i
] = 0;
1422 for ( i
= 0; i
< nSfbPrev
; i
++ ) {
1423 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDetected
[i
+ (nSfb
- nSfbPrev
)] = tempGuideInt
[i
];
1427 for ( i
= 0; i
< nSfb
; i
++ ) {
1428 hSbrMissingHarmonicsDetector
->guideVectors
[0].guideVectorDetected
[i
] = tempGuideInt
[i
+ (nSfbPrev
-nSfb
)];
1432 FDKmemcpy ( tempGuideInt
, hSbrMissingHarmonicsDetector
->prevEnvelopeCompensation
, nSfbPrev
* sizeof(UCHAR
) );
1434 if ( nSfb
> nSfbPrev
) {
1435 for ( i
= 0; i
< (nSfb
- nSfbPrev
); i
++ ) {
1436 hSbrMissingHarmonicsDetector
->prevEnvelopeCompensation
[i
] = 0;
1439 for ( i
= 0; i
< nSfbPrev
; i
++ ) {
1440 hSbrMissingHarmonicsDetector
->prevEnvelopeCompensation
[i
+ (nSfb
- nSfbPrev
)] = tempGuideInt
[i
];
1444 for ( i
= 0; i
< nSfb
; i
++ ) {
1445 hSbrMissingHarmonicsDetector
->prevEnvelopeCompensation
[i
] = tempGuideInt
[i
+ (nSfbPrev
-nSfb
)];