1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 /**************************************************************************/ 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 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 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 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 switch(frameSize){ 1248 case 2048: 1249 hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048; 1250 hs->timeSlots = NUMBER_TIME_SLOTS_2048; 1251 break; 1252 case 1920: 1253 hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920; 1254 hs->timeSlots = NUMBER_TIME_SLOTS_1920; 1255 break; 1256 case 1024: 1257 hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 1258 hs->timeSlots = 16; 1259 break; 1260 case 960: 1261 hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 1262 hs->timeSlots = 15; 1263 break; 1264 default: 1265 return -1; 1266 } 1267 1268 if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { 1269 hs->mhParams = ¶msAacLd; 1270 } else 1271 hs->mhParams = ¶msAac; 1272 1273 hs->qmfNoChannels = qmfNoChannels; 1274 hs->sampleFreq = sampleFreq; 1275 hs->nSfb = nSfb; 1276 1277 hs->totNoEst = totNoEst; 1278 hs->move = move; 1279 hs->noEstPerFrame = noEstPerFrame; 1280 1281 for(i=0; i<totNoEst; i++) { 1282 FDKmemclear (hs->guideVectors[i].guideVectorDiff,sizeof(FIXP_DBL)*MAX_FREQ_COEFFS); 1283 FDKmemclear (hs->guideVectors[i].guideVectorOrig,sizeof(FIXP_DBL)*MAX_FREQ_COEFFS); 1284 FDKmemclear (hs->detectionVectors[i],sizeof(UCHAR)*MAX_FREQ_COEFFS); 1285 FDKmemclear (hs->guideVectors[i].guideVectorDetected,sizeof(UCHAR)*MAX_FREQ_COEFFS); 1286 } 1287 1288 //for(i=0; i<totNoEst/2; i++) { 1289 for(i=0; i<MAX_NO_OF_ESTIMATES/2; i++) { 1290 FDKmemclear (hs->tonalityDiff[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS); 1291 FDKmemclear (hs->sfmOrig[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS); 1292 FDKmemclear (hs->sfmSbr[i],sizeof(FIXP_DBL)*MAX_FREQ_COEFFS); 1293 } 1294 1295 FDKmemclear ( hs->prevEnvelopeCompensation, sizeof(UCHAR)*MAX_FREQ_COEFFS); 1296 FDKmemclear ( hs->guideScfb, sizeof(UCHAR)*MAX_FREQ_COEFFS); 1297 1298 hs->previousTransientFlag = 0; 1299 hs->previousTransientFrame = 0; 1300 hs->previousTransientPos = 0; 1301 1302 return (0); 1303 } 1304 1305 /**************************************************************************/ 1306 /*! 1307 \brief Deletes an instance of the missing harmonics detector. 1308 1309 1310 \return none. 1311 1312 */ 1313 /**************************************************************************/ 1314 void 1315 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet) 1316 { 1317 if (hSbrMHDet) { 1318 HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet; 1319 1320 FreeRam_Sbr_detectionVectors(&hs->detectionVectors[0]); 1321 FreeRam_Sbr_guideVectorDetected(&hs->guideVectors[0].guideVectorDetected); 1322 FreeRam_Sbr_guideVectorDiff(&hs->guideVectors[0].guideVectorDiff); 1323 FreeRam_Sbr_guideVectorOrig(&hs->guideVectors[0].guideVectorOrig); 1324 FreeRam_Sbr_prevEnvelopeCompensation(&hs->prevEnvelopeCompensation); 1325 FreeRam_Sbr_guideScfb(&hs->guideScfb); 1326 1327 } 1328 } 1329 1330 /**************************************************************************/ 1331 /*! 1332 \brief Resets an instance of the missing harmonics detector. 1333 1334 1335 \return error code, noError if OK. 1336 1337 */ 1338 /**************************************************************************/ 1339 INT 1340 FDKsbrEnc_ResetSbrMissingHarmonicsDetector (HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector, 1341 INT nSfb) 1342 { 1343 int i; 1344 FIXP_DBL tempGuide[MAX_FREQ_COEFFS]; 1345 UCHAR tempGuideInt[MAX_FREQ_COEFFS]; 1346 INT nSfbPrev; 1347 1348 nSfbPrev = hSbrMissingHarmonicsDetector->nSfb; 1349 hSbrMissingHarmonicsDetector->nSfb = nSfb; 1350 1351 FDKmemcpy( tempGuideInt, hSbrMissingHarmonicsDetector->guideScfb, nSfbPrev * sizeof(UCHAR) ); 1352 1353 if ( nSfb > nSfbPrev ) { 1354 for ( i = 0; i < (nSfb - nSfbPrev); i++ ) { 1355 hSbrMissingHarmonicsDetector->guideScfb[i] = 0; 1356 } 1357 1358 for ( i = 0; i < nSfbPrev; i++ ) { 1359 hSbrMissingHarmonicsDetector->guideScfb[i + (nSfb - nSfbPrev)] = tempGuideInt[i]; 1360 } 1361 } 1362 else { 1363 for ( i = 0; i < nSfb; i++ ) { 1364 hSbrMissingHarmonicsDetector->guideScfb[i] = tempGuideInt[i + (nSfbPrev-nSfb)]; 1365 } 1366 } 1367 1368 FDKmemcpy ( tempGuide, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff, nSfbPrev * sizeof(FIXP_DBL) ); 1369 1370 if (nSfb > nSfbPrev ) { 1371 for ( i = 0; i < (nSfb - nSfbPrev); i++ ) { 1372 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f); 1373 } 1374 1375 for ( i = 0; i < nSfbPrev; i++ ) { 1376 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i + (nSfb - nSfbPrev)] = tempGuide[i]; 1377 } 1378 } 1379 else { 1380 for ( i = 0; i < nSfb; i++ ) { 1381 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = tempGuide[i + (nSfbPrev-nSfb)]; 1382 } 1383 } 1384 1385 FDKmemcpy ( tempGuide, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig, nSfbPrev * sizeof(FIXP_DBL) ); 1386 1387 if ( nSfb > nSfbPrev ) { 1388 for ( i = 0; i< (nSfb - nSfbPrev); i++ ) { 1389 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f); 1390 } 1391 1392 for ( i = 0; i < nSfbPrev; i++ ) { 1393 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i + (nSfb - nSfbPrev)] = tempGuide[i]; 1394 } 1395 } 1396 else { 1397 for ( i = 0; i < nSfb; i++ ) { 1398 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = tempGuide[i + (nSfbPrev-nSfb)]; 1399 } 1400 } 1401 1402 FDKmemcpy ( tempGuideInt, hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected, nSfbPrev * sizeof(UCHAR) ); 1403 1404 if ( nSfb > nSfbPrev ) { 1405 for ( i = 0; i < (nSfb - nSfbPrev); i++ ) { 1406 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = 0; 1407 } 1408 1409 for ( i = 0; i < nSfbPrev; i++ ) { 1410 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i + (nSfb - nSfbPrev)] = tempGuideInt[i]; 1411 } 1412 } 1413 else { 1414 for ( i = 0; i < nSfb; i++ ) { 1415 hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = tempGuideInt[i + (nSfbPrev-nSfb)]; 1416 } 1417 } 1418 1419 FDKmemcpy ( tempGuideInt, hSbrMissingHarmonicsDetector->prevEnvelopeCompensation, nSfbPrev * sizeof(UCHAR) ); 1420 1421 if ( nSfb > nSfbPrev ) { 1422 for ( i = 0; i < (nSfb - nSfbPrev); i++ ) { 1423 hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = 0; 1424 } 1425 1426 for ( i = 0; i < nSfbPrev; i++ ) { 1427 hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i + (nSfb - nSfbPrev)] = tempGuideInt[i]; 1428 } 1429 } 1430 else { 1431 for ( i = 0; i < nSfb; i++ ) { 1432 hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = tempGuideInt[i + (nSfbPrev-nSfb)]; 1433 } 1434 } 1435 1436 return 0; 1437 } 1438 1439