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