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 "ton_corr.h" 85 86 #include "sbr_ram.h" 87 #include "sbr_misc.h" 88 #include "genericStds.h" 89 #include "autocorr2nd.h" 90 91 92 93 /*************************************************************************** 94 95 Send autoCorrSecondOrder to mlfile 96 97 ****************************************************************************/ 98 99 /**************************************************************************/ 100 /*! 101 \brief Calculates the tonal to noise ration for different frequency bands 102 and time segments. 103 104 The ratio between the predicted energy (tonal energy A) and the total 105 energy (A + B) is calculated. This is converted to the ratio between 106 the predicted energy (tonal energy A) and the non-predictable energy 107 (noise energy B). Hence the quota-matrix contains A/B = q/(1-q). 108 109 The samples in nrgVector are scaled by 1.0/16.0 110 The samples in pNrgVectorFreq are scaled by 1.0/2.0 111 The samples in quotaMatrix are scaled by RELAXATION 112 113 \return none. 114 115 */ 116 /**************************************************************************/ 117 118 void 119 FDKsbrEnc_CalculateTonalityQuotas( HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 120 FIXP_DBL **RESTRICT sourceBufferReal, /*!< The real part of the QMF-matrix. */ 121 FIXP_DBL **RESTRICT sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */ 122 INT usb, /*!< upper side band, highest + 1 QMF band in the SBR range. */ 123 INT qmfScale /*!< sclefactor of QMF subsamples */ 124 ) 125 { 126 INT i, k, r, r2, timeIndex, autoCorrScaling; 127 128 INT startIndexMatrix = hTonCorr->startIndexMatrix; 129 INT totNoEst = hTonCorr->numberOfEstimates; 130 INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame; 131 INT move = hTonCorr->move; 132 INT noQmfChannels = hTonCorr->noQmfChannels; /* Numer of Bands */ 133 INT buffLen = hTonCorr->bufferLength; /* Numer of Slots */ 134 INT stepSize = hTonCorr->stepSize; 135 INT *pBlockLength = hTonCorr->lpcLength; 136 INT** RESTRICT signMatrix = hTonCorr->signMatrix; 137 FIXP_DBL* RESTRICT nrgVector = hTonCorr->nrgVector; 138 FIXP_DBL** RESTRICT quotaMatrix = hTonCorr->quotaMatrix; 139 FIXP_DBL* RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq; 140 141 #define BAND_V_SIZE QMF_MAX_TIME_SLOTS 142 #define NUM_V_COMBINE 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */ 143 144 FIXP_DBL *realBuf; 145 FIXP_DBL *imagBuf; 146 147 FIXP_DBL alphar[2],alphai[2],fac; 148 149 C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1); 150 C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE); 151 152 realBuf = realBufRef; 153 imagBuf = realBuf + BAND_V_SIZE*NUM_V_COMBINE; 154 155 156 FDK_ASSERT(buffLen <= BAND_V_SIZE); 157 FDK_ASSERT(sizeof(FIXP_DBL)*NUM_V_COMBINE*BAND_V_SIZE*2 < (1024*sizeof(FIXP_DBL)-sizeof(ACORR_COEFS)) ); 158 159 /* 160 * Buffering of the quotaMatrix and the quotaMatrixTransp. 161 *********************************************************/ 162 for(i = 0 ; i < move; i++){ 163 FDKmemcpy(quotaMatrix[i],quotaMatrix[i + noEstPerFrame],noQmfChannels * sizeof(FIXP_DBL)); 164 FDKmemcpy(signMatrix[i],signMatrix[i + noEstPerFrame],noQmfChannels * sizeof(INT)); 165 } 166 167 FDKmemmove(nrgVector,nrgVector+noEstPerFrame,move*sizeof(FIXP_DBL)); 168 FDKmemclear(nrgVector+startIndexMatrix,(totNoEst-startIndexMatrix)*sizeof(FIXP_DBL)); 169 FDKmemclear(pNrgVectorFreq,noQmfChannels * sizeof(FIXP_DBL)); 170 171 /* 172 * Calculate the quotas for the current time steps. 173 **************************************************/ 174 175 for (r = 0; r < usb; r++) 176 { 177 int blockLength; 178 179 k = hTonCorr->nextSample; /* startSample */ 180 timeIndex = startIndexMatrix; 181 /* Copy as many as possible Band accross all Slots at once */ 182 if (realBuf != realBufRef) { 183 realBuf -= BAND_V_SIZE; 184 imagBuf -= BAND_V_SIZE; 185 } else { 186 realBuf += BAND_V_SIZE*(NUM_V_COMBINE-1); 187 imagBuf += BAND_V_SIZE*(NUM_V_COMBINE-1); 188 for (i = 0; i < buffLen; i++) { 189 int v; 190 FIXP_DBL *ptr; 191 ptr = realBuf+i; 192 for (v=0; v<NUM_V_COMBINE; v++) 193 { 194 ptr[0] = sourceBufferReal[i][r+v]; 195 ptr[0+BAND_V_SIZE*NUM_V_COMBINE] = sourceBufferImag[i][r+v]; 196 ptr -= BAND_V_SIZE; 197 } 198 } 199 } 200 201 blockLength = pBlockLength[0]; 202 203 while(k <= buffLen - blockLength) 204 { 205 autoCorrScaling = fixMin(getScalefactor(&realBuf[k-LPC_ORDER], LPC_ORDER+blockLength), getScalefactor(&imagBuf[k-LPC_ORDER], LPC_ORDER+blockLength)); 206 autoCorrScaling = fixMax(0, autoCorrScaling-1); 207 208 scaleValues(&realBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling); 209 scaleValues(&imagBuf[k-LPC_ORDER], LPC_ORDER+blockLength, autoCorrScaling); 210 211 autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */ 212 autoCorrScaling += autoCorr2nd_cplx ( ac, realBuf+k, imagBuf+k, blockLength ); 213 214 215 if(ac->det == FL2FXCONST_DBL(0.0f)){ 216 alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f); 217 218 alphar[0] = (ac->r01r)>>2; 219 alphai[0] = (ac->r01i)>>2; 220 221 fac = fMultDiv2(ac->r00r, ac->r11r)>>1; 222 } 223 else{ 224 alphar[1] = (fMultDiv2(ac->r01r, ac->r12r)>>1) - (fMultDiv2(ac->r01i, ac->r12i)>>1) - (fMultDiv2(ac->r02r, ac->r11r)>>1); 225 alphai[1] = (fMultDiv2(ac->r01i, ac->r12r)>>1) + (fMultDiv2(ac->r01r, ac->r12i)>>1) - (fMultDiv2(ac->r02i, ac->r11r)>>1); 226 227 alphar[0] = (fMultDiv2(ac->r01r, ac->det)>>(ac->det_scale+1)) + fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i); 228 alphai[0] = (fMultDiv2(ac->r01i, ac->det)>>(ac->det_scale+1)) + fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i); 229 230 fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r))>>(ac->det_scale+1); 231 } 232 233 if(fac == FL2FXCONST_DBL(0.0f)){ 234 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); 235 signMatrix[timeIndex][r] = 0; 236 } 237 else { 238 /* quotaMatrix is scaled with the factor RELAXATION 239 parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 * 2^RELAXATION_SHIFT) */ 240 FIXP_DBL tmp,num,denom; 241 INT numShift,denomShift,commonShift; 242 INT sign; 243 244 num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) - fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) - fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r)); 245 num = fixp_abs(num); 246 247 denom = (fac>>1) + (fMultDiv2(fac,RELAXATION_FRACT)>>RELAXATION_SHIFT) - num; 248 denom = fixp_abs(denom); 249 250 num = fMult(num,RELAXATION_FRACT); 251 252 numShift = CountLeadingBits(num) - 2; 253 num = scaleValue(num, numShift); 254 255 denomShift = CountLeadingBits(denom); 256 denom = (FIXP_DBL)denom << denomShift; 257 258 if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) { 259 commonShift = fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS-1); 260 if (commonShift < 0) { 261 commonShift = -commonShift; 262 tmp = schur_div(num,denom,16); 263 commonShift = fixMin(commonShift,CountLeadingBits(tmp)); 264 quotaMatrix[timeIndex][r] = tmp << commonShift; 265 } 266 else { 267 quotaMatrix[timeIndex][r] = schur_div(num,denom,16) >> commonShift; 268 } 269 } 270 else { 271 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); 272 } 273 274 if (ac->r11r != FL2FXCONST_DBL(0.0f)) { 275 if ( ( (ac->r01r >= FL2FXCONST_DBL(0.0f) ) && ( ac->r11r >= FL2FXCONST_DBL(0.0f) ) ) 276 ||( (ac->r01r < FL2FXCONST_DBL(0.0f) ) && ( ac->r11r < FL2FXCONST_DBL(0.0f) ) ) ) { 277 sign = 1; 278 } 279 else { 280 sign = -1; 281 } 282 } 283 else { 284 sign = 1; 285 } 286 287 if(sign < 0) { 288 r2 = r; /* (INT) pow(-1, band); */ 289 } 290 else { 291 r2 = r + 1; /* (INT) pow(-1, band+1); */ 292 } 293 signMatrix[timeIndex][r] = 1 - 2*(r2 & 0x1); 294 } 295 296 nrgVector[timeIndex] += ((ac->r00r) >> fixMin(DFRACT_BITS-1,(2*qmfScale+autoCorrScaling + SCALE_NRGVEC))); 297 /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced division by shifting with one */ 298 pNrgVectorFreq[r] = pNrgVectorFreq[r] + ((ac->r00r) >> fixMin(DFRACT_BITS-1,(2*qmfScale+autoCorrScaling + SCALE_NRGVEC))); 299 300 blockLength = pBlockLength[1]; 301 k += stepSize; 302 timeIndex++; 303 } 304 } 305 306 FDK_ASSERT(noEstPerFrame == 2); 307 308 309 C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE); 310 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1); 311 } 312 313 /**************************************************************************/ 314 /*! 315 \brief Extracts the parameters required in the decoder to obtain the 316 correct tonal to noise ratio after SBR. 317 318 Estimates the tonal to noise ratio of the original signal (using LPC). 319 Predicts the tonal to noise ration of the SBR signal (in the decoder) by 320 patching the tonal to noise ratio values similar to the patching of the 321 lowband in the decoder. Given the tonal to noise ratio of the original 322 and the SBR signal, it estimates the required amount of inverse filtering, 323 additional noise as well as any additional sines. 324 325 \return none. 326 327 */ 328 /**************************************************************************/ 329 void 330 FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,/*!< Handle to SBR_TON_CORR struct. */ 331 INVF_MODE* infVec, /*!< Vector where the inverse filtering levels will be stored. */ 332 FIXP_DBL * noiseLevels, /*!< Vector where the noise levels will be stored. */ 333 INT* missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/ 334 UCHAR * missingHarmonicsIndex, /*!< Vector indicating where sines are missing. */ 335 UCHAR * envelopeCompensation, /*!< Vector to store compensation values for the energies in. */ 336 const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/ 337 UCHAR* transientInfo, /*!< Transient info.*/ 338 UCHAR* freqBandTable, /*!< Frequency band tables for high-res.*/ 339 INT nSfb, /*!< Number of scalefactor bands for high-res. */ 340 XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/ 341 UINT sbrSyntaxFlags 342 ) 343 { 344 INT band; 345 INT transientFlag = transientInfo[1] ; /*!< Flag indicating if a transient is present in the current frame. */ 346 INT transientPos = transientInfo[0]; /*!< Position of the transient.*/ 347 INT transientFrame, transientFrameInvfEst; 348 INVF_MODE* infVecPtr; 349 350 351 /* Determine if this is a frame where a transient starts... 352 353 The detection of noise-floor, missing harmonics and invf_est, is not in sync for the 354 non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the 355 present frame as well as in the next. 356 */ 357 transientFrame = 0; 358 if(hTonCorr->transientNextFrame){ /* The transient was detected in the previous frame, but is actually */ 359 transientFrame = 1; 360 hTonCorr->transientNextFrame = 0; 361 362 if(transientFlag){ 363 if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){ 364 hTonCorr->transientNextFrame = 1; 365 } 366 } 367 } 368 else{ 369 if(transientFlag){ 370 if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){ 371 transientFrame = 1; 372 hTonCorr->transientNextFrame = 0; 373 } 374 else{ 375 hTonCorr->transientNextFrame = 1; 376 } 377 } 378 } 379 transientFrameInvfEst = transientFrame; 380 381 382 /* 383 Estimate the required invese filtereing level. 384 */ 385 if (hTonCorr->switchInverseFilt) 386 FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt, 387 hTonCorr->quotaMatrix, 388 hTonCorr->nrgVector, 389 hTonCorr->indexVector, 390 hTonCorr->frameStartIndexInvfEst, 391 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst, 392 transientFrameInvfEst, 393 infVec); 394 395 /* 396 Detect what tones will be missing. 397 */ 398 if (xposType == XPOS_LC ){ 399 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector, 400 hTonCorr->quotaMatrix, 401 hTonCorr->signMatrix, 402 hTonCorr->indexVector, 403 frameInfo, 404 transientInfo, 405 missingHarmonicFlag, 406 missingHarmonicsIndex, 407 freqBandTable, 408 nSfb, 409 envelopeCompensation, 410 hTonCorr->nrgVectorFreq); 411 } 412 else{ 413 *missingHarmonicFlag = 0; 414 FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR)); 415 } 416 417 418 419 /* 420 Noise floor estimation 421 */ 422 423 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode; 424 425 FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate, 426 frameInfo, 427 noiseLevels, 428 hTonCorr->quotaMatrix, 429 hTonCorr->indexVector, 430 *missingHarmonicFlag, 431 hTonCorr->frameStartIndex, 432 hTonCorr->numberOfEstimatesPerFrame, 433 transientFrame, 434 infVecPtr, 435 sbrSyntaxFlags); 436 437 438 /* Store the invfVec data for the next frame...*/ 439 for(band = 0 ; band < hTonCorr->sbrInvFilt.noDetectorBands; band++){ 440 hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band]; 441 } 442 } 443 444 /**************************************************************************/ 445 /*! 446 \brief Searches for the closest match in the frequency master table. 447 448 449 450 \return closest entry. 451 452 */ 453 /**************************************************************************/ 454 static INT 455 findClosestEntry(INT goalSb, 456 UCHAR *v_k_master, 457 INT numMaster, 458 INT direction) 459 { 460 INT index; 461 462 if( goalSb <= v_k_master[0] ) 463 return v_k_master[0]; 464 465 if( goalSb >= v_k_master[numMaster] ) 466 return v_k_master[numMaster]; 467 468 if(direction) { 469 index = 0; 470 while( v_k_master[index] < goalSb ) { 471 index++; 472 } 473 } else { 474 index = numMaster; 475 while( v_k_master[index] > goalSb ) { 476 index--; 477 } 478 } 479 480 return v_k_master[index]; 481 } 482 483 484 /**************************************************************************/ 485 /*! 486 \brief resets the patch 487 488 489 490 \return errorCode, noError if successful. 491 492 */ 493 /**************************************************************************/ 494 static INT 495 resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 496 INT xposctrl, /*!< Different patch modes. */ 497 INT highBandStartSb, /*!< Start band of the SBR range. */ 498 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/ 499 INT numMaster, /*!< Number of elements in the master table. */ 500 INT fs, /*!< Sampling frequency. */ 501 INT noChannels) /*!< Number of QMF-channels. */ 502 { 503 INT patch,k,i; 504 INT targetStopBand; 505 506 PATCH_PARAM *patchParam = hTonCorr->patchParam; 507 508 INT sbGuard = hTonCorr->guard; 509 INT sourceStartBand; 510 INT patchDistance; 511 INT numBandsInPatch; 512 513 INT lsb = v_k_master[0]; /* Lowest subband related to the synthesis filterbank */ 514 INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis filterbank */ 515 INT xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */ 516 517 INT goalSb; 518 519 520 /* 521 * Initialize the patching parameter 522 */ 523 524 if (xposctrl == 1) { 525 lsb += xoverOffset; 526 xoverOffset = 0; 527 } 528 529 goalSb = (INT)( (2 * noChannels * 16000 + (fs>>1)) / fs ); /* 16 kHz band */ 530 goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 1); /* Adapt region to master-table */ 531 532 /* First patch */ 533 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset; 534 targetStopBand = lsb + xoverOffset; 535 536 /* even (odd) numbered channel must be patched to even (odd) numbered channel */ 537 patch = 0; 538 while(targetStopBand < usb) { 539 540 /* To many patches */ 541 if (patch >= MAX_NUM_PATCHES) 542 return(1); /*Number of patches to high */ 543 544 patchParam[patch].guardStartBand = targetStopBand; 545 targetStopBand += sbGuard; 546 patchParam[patch].targetStartBand = targetStopBand; 547 548 numBandsInPatch = goalSb - targetStopBand; /* get the desired range of the patch */ 549 550 if ( numBandsInPatch >= lsb - sourceStartBand ) { 551 /* desired number bands are not available -> patch whole source range */ 552 patchDistance = targetStopBand - sourceStartBand; /* get the targetOffset */ 553 patchDistance = patchDistance & ~1; /* rounding off odd numbers and make all even */ 554 numBandsInPatch = lsb - (targetStopBand - patchDistance); 555 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) - 556 targetStopBand; /* Adapt region to master-table */ 557 } 558 559 /* desired number bands are available -> get the minimal even patching distance */ 560 patchDistance = numBandsInPatch + targetStopBand - lsb; /* get minimal distance */ 561 patchDistance = (patchDistance + 1) & ~1; /* rounding up odd numbers and make all even */ 562 563 if (numBandsInPatch <= 0) { 564 patch--; 565 } else { 566 patchParam[patch].sourceStartBand = targetStopBand - patchDistance; 567 patchParam[patch].targetBandOffs = patchDistance; 568 patchParam[patch].numBandsInPatch = numBandsInPatch; 569 patchParam[patch].sourceStopBand = patchParam[patch].sourceStartBand + numBandsInPatch; 570 571 targetStopBand += patchParam[patch].numBandsInPatch; 572 } 573 574 /* All patches but first */ 575 sourceStartBand = hTonCorr->shiftStartSb; 576 577 /* Check if we are close to goalSb */ 578 if( fixp_abs(targetStopBand - goalSb) < 3) { 579 goalSb = usb; 580 } 581 582 patch++; 583 584 } 585 586 patch--; 587 588 /* if highest patch contains less than three subband: skip it */ 589 if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) { 590 patch--; 591 targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch; 592 } 593 594 hTonCorr->noOfPatches = patch + 1; 595 596 597 /* Assign the index-vector, so we know where to look for the high-band. 598 -1 represents a guard-band. */ 599 for(k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++) 600 hTonCorr->indexVector[k] = k; 601 602 for(i = 0; i < hTonCorr->noOfPatches; i++) 603 { 604 INT sourceStart = hTonCorr->patchParam[i].sourceStartBand; 605 INT targetStart = hTonCorr->patchParam[i].targetStartBand; 606 INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch; 607 INT startGuardBand = hTonCorr->patchParam[i].guardStartBand; 608 609 for(k = 0; k < (targetStart- startGuardBand); k++) 610 hTonCorr->indexVector[startGuardBand+k] = -1; 611 612 for(k = 0; k < numberOfBands; k++) 613 hTonCorr->indexVector[targetStart+k] = sourceStart+k; 614 } 615 616 return (0); 617 } 618 619 /**************************************************************************/ 620 /*! 621 \brief Creates an instance of the tonality correction parameter module. 622 623 The module includes modules for inverse filtering level estimation, 624 missing harmonics detection and noise floor level estimation. 625 626 \return errorCode, noError if successful. 627 */ 628 /**************************************************************************/ 629 INT 630 FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 631 INT chan) /*!< Channel index, needed for mem allocation */ 632 { 633 INT i; 634 FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan); 635 INT* signMatrix = GetRam_Sbr_signMatrix(chan); 636 637 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST)); 638 639 for (i=0; i<MAX_NO_OF_ESTIMATES; i++) { 640 hTonCorr->quotaMatrix[i] = quotaMatrix + (i*QMF_CHANNELS); 641 hTonCorr->signMatrix[i] = signMatrix + (i*QMF_CHANNELS); 642 } 643 644 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan); 645 646 return 0; 647 } 648 649 650 651 /**************************************************************************/ 652 /*! 653 \brief Initialize an instance of the tonality correction parameter module. 654 655 The module includes modules for inverse filtering level estimation, 656 missing harmonics detection and noise floor level estimation. 657 658 \return errorCode, noError if successful. 659 */ 660 /**************************************************************************/ 661 INT 662 FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current SBR frame size. */ 663 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 664 HANDLE_SBR_CONFIG_DATA sbrCfg, /*!< Pointer to SBR configuration parameters. */ 665 INT timeSlots, /*!< Number of time-slots per frame */ 666 INT xposCtrl, /*!< Different patch modes. */ 667 INT ana_max_level, /*!< Maximum level of the adaptive noise. */ 668 INT noiseBands, /*!< Number of noise bands per octave. */ 669 INT noiseFloorOffset, /*!< Noise floor offset. */ 670 UINT useSpeechConfig) /*!< Speech or music tuning. */ 671 { 672 INT nCols = sbrCfg->noQmfSlots; 673 INT fs = sbrCfg->sampleFreq; 674 INT noQmfChannels = sbrCfg->noQmfBands; 675 676 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0]; 677 UCHAR *v_k_master = sbrCfg->v_k_master; 678 INT numMaster = sbrCfg->num_Master; 679 680 UCHAR **freqBandTable = sbrCfg->freqBandTable; 681 INT *nSfb = sbrCfg->nSfb; 682 683 INT i; 684 685 /* 686 Reset the patching and allocate memory for the quota matrix. 687 Assing parameters for the LPC analysis. 688 */ 689 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { 690 switch (timeSlots) { 691 case NUMBER_TIME_SLOTS_1920: 692 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 693 hTonCorr->lpcLength[1] = 7 - LPC_ORDER; 694 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 695 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 7; 696 hTonCorr->frameStartIndexInvfEst = 0; 697 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 698 break; 699 case NUMBER_TIME_SLOTS_2048: 700 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 701 hTonCorr->lpcLength[1] = 8 - LPC_ORDER; 702 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 703 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 8; 704 hTonCorr->frameStartIndexInvfEst = 0; 705 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 706 break; 707 } 708 } else 709 switch (timeSlots) { 710 case NUMBER_TIME_SLOTS_2048: 711 hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */ 712 hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */ 713 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 714 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16; 715 hTonCorr->frameStartIndexInvfEst = 0; 716 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048; 717 break; 718 case NUMBER_TIME_SLOTS_1920: 719 hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */ 720 hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */ 721 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 722 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15; 723 hTonCorr->frameStartIndexInvfEst = 0; 724 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920; 725 break; 726 default: 727 return -1; 728 } 729 730 hTonCorr->bufferLength = nCols; 731 hTonCorr->stepSize = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */ 732 733 hTonCorr->nextSample = LPC_ORDER; /* firstSample */ 734 hTonCorr->move = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates to move when buffering.*/ 735 hTonCorr->startIndexMatrix = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest estimations in the tonality Matrix.*/ 736 hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */ 737 hTonCorr->prevTransientFlag = 0; 738 hTonCorr->transientNextFrame = 0; 739 740 hTonCorr->noQmfChannels = noQmfChannels; 741 742 for (i=0; i<hTonCorr->numberOfEstimates; i++) { 743 FDKmemclear (hTonCorr->quotaMatrix[i] , sizeof(FIXP_DBL)*noQmfChannels); 744 FDKmemclear (hTonCorr->signMatrix[i] , sizeof(INT)*noQmfChannels); 745 } 746 747 /* Reset the patch.*/ 748 hTonCorr->guard = 0; 749 hTonCorr->shiftStartSb = 1; 750 751 if(resetPatch(hTonCorr, 752 xposCtrl, 753 highBandStartSb, 754 v_k_master, 755 numMaster, 756 fs, 757 noQmfChannels)) 758 return(1); 759 760 if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate, 761 ana_max_level, 762 freqBandTable[LO], 763 nSfb[LO], 764 noiseBands, 765 noiseFloorOffset, 766 timeSlots, 767 useSpeechConfig)) 768 return(1); 769 770 771 if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt, 772 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 773 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, 774 useSpeechConfig)) 775 return(1); 776 777 778 779 if(FDKsbrEnc_InitSbrMissingHarmonicsDetector( 780 &hTonCorr->sbrMissingHarmonicsDetector, 781 fs, 782 frameSize, 783 nSfb[HI], 784 noQmfChannels, 785 hTonCorr->numberOfEstimates, 786 hTonCorr->move, 787 hTonCorr->numberOfEstimatesPerFrame, 788 sbrCfg->sbrSyntaxFlags)) 789 return(1); 790 791 792 793 return (0); 794 } 795 796 797 798 /**************************************************************************/ 799 /*! 800 \brief resets tonality correction parameter module. 801 802 803 804 \return errorCode, noError if successful. 805 806 */ 807 /**************************************************************************/ 808 INT 809 FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 810 INT xposctrl, /*!< Different patch modes. */ 811 INT highBandStartSb, /*!< Start band of the SBR range. */ 812 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/ 813 INT numMaster, /*!< Number of elements in the master table. */ 814 INT fs, /*!< Sampling frequency (of the SBR part). */ 815 UCHAR ** freqBandTable, /*!< Frequency band table for low-res and high-res. */ 816 INT* nSfb, /*!< Number of frequency bands (hig-res and low-res). */ 817 INT noQmfChannels /*!< Number of QMF channels. */ 818 ) 819 { 820 821 /* Reset the patch.*/ 822 hTonCorr->guard = 0; 823 hTonCorr->shiftStartSb = 1; 824 825 if(resetPatch(hTonCorr, 826 xposctrl, 827 highBandStartSb, 828 v_k_master, 829 numMaster, 830 fs, 831 noQmfChannels)) 832 return(1); 833 834 835 836 /* Reset the noise floor estimate.*/ 837 if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate, 838 freqBandTable[LO], 839 nSfb[LO])) 840 return(1); 841 842 /* 843 Reset the inveerse filtereing detector. 844 */ 845 if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt, 846 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 847 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands)) 848 return(1); 849 /* Reset the missing harmonics detector. */ 850 if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, 851 nSfb[HI])) 852 return(1); 853 854 return (0); 855 } 856 857 858 859 860 861 /**************************************************************************/ 862 /*! 863 \brief Deletes the tonality correction paramtere module. 864 865 866 867 \return none 868 869 */ 870 /**************************************************************************/ 871 void 872 FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */ 873 { 874 875 if (hTonCorr) { 876 877 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix); 878 879 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix); 880 881 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector); 882 } 883 } 884