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 "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 307 C_ALLOC_SCRATCH_END(realBuf, FIXP_DBL, 2*BAND_V_SIZE*NUM_V_COMBINE); 308 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1); 309 } 310 311 /**************************************************************************/ 312 /*! 313 \brief Extracts the parameters required in the decoder to obtain the 314 correct tonal to noise ratio after SBR. 315 316 Estimates the tonal to noise ratio of the original signal (using LPC). 317 Predicts the tonal to noise ration of the SBR signal (in the decoder) by 318 patching the tonal to noise ratio values similar to the patching of the 319 lowband in the decoder. Given the tonal to noise ratio of the original 320 and the SBR signal, it estimates the required amount of inverse filtering, 321 additional noise as well as any additional sines. 322 323 \return none. 324 325 */ 326 /**************************************************************************/ 327 void 328 FDKsbrEnc_TonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr,/*!< Handle to SBR_TON_CORR struct. */ 329 INVF_MODE* infVec, /*!< Vector where the inverse filtering levels will be stored. */ 330 FIXP_DBL * noiseLevels, /*!< Vector where the noise levels will be stored. */ 331 INT* missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any strong sines are missing.*/ 332 UCHAR * missingHarmonicsIndex, /*!< Vector indicating where sines are missing. */ 333 UCHAR * envelopeCompensation, /*!< Vector to store compensation values for the energies in. */ 334 const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time and frequency grid of the current frame.*/ 335 UCHAR* transientInfo, /*!< Transient info.*/ 336 UCHAR* freqBandTable, /*!< Frequency band tables for high-res.*/ 337 INT nSfb, /*!< Number of scalefactor bands for high-res. */ 338 XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/ 339 UINT sbrSyntaxFlags 340 ) 341 { 342 INT band; 343 INT transientFlag = transientInfo[1] ; /*!< Flag indicating if a transient is present in the current frame. */ 344 INT transientPos = transientInfo[0]; /*!< Position of the transient.*/ 345 INT transientFrame, transientFrameInvfEst; 346 INVF_MODE* infVecPtr; 347 348 349 /* Determine if this is a frame where a transient starts... 350 351 The detection of noise-floor, missing harmonics and invf_est, is not in sync for the 352 non-buf-opt decoder such as AAC. Hence we need to keep track on the transient in the 353 present frame as well as in the next. 354 */ 355 transientFrame = 0; 356 if(hTonCorr->transientNextFrame){ /* The transient was detected in the previous frame, but is actually */ 357 transientFrame = 1; 358 hTonCorr->transientNextFrame = 0; 359 360 if(transientFlag){ 361 if(transientPos + hTonCorr->transientPosOffset >= frameInfo->borders[frameInfo->nEnvelopes]){ 362 hTonCorr->transientNextFrame = 1; 363 } 364 } 365 } 366 else{ 367 if(transientFlag){ 368 if(transientPos + hTonCorr->transientPosOffset < frameInfo->borders[frameInfo->nEnvelopes]){ 369 transientFrame = 1; 370 hTonCorr->transientNextFrame = 0; 371 } 372 else{ 373 hTonCorr->transientNextFrame = 1; 374 } 375 } 376 } 377 transientFrameInvfEst = transientFrame; 378 379 380 /* 381 Estimate the required invese filtereing level. 382 */ 383 if (hTonCorr->switchInverseFilt) 384 FDKsbrEnc_qmfInverseFilteringDetector(&hTonCorr->sbrInvFilt, 385 hTonCorr->quotaMatrix, 386 hTonCorr->nrgVector, 387 hTonCorr->indexVector, 388 hTonCorr->frameStartIndexInvfEst, 389 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst, 390 transientFrameInvfEst, 391 infVec); 392 393 /* 394 Detect what tones will be missing. 395 */ 396 if (xposType == XPOS_LC ){ 397 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf(&hTonCorr->sbrMissingHarmonicsDetector, 398 hTonCorr->quotaMatrix, 399 hTonCorr->signMatrix, 400 hTonCorr->indexVector, 401 frameInfo, 402 transientInfo, 403 missingHarmonicFlag, 404 missingHarmonicsIndex, 405 freqBandTable, 406 nSfb, 407 envelopeCompensation, 408 hTonCorr->nrgVectorFreq); 409 } 410 else{ 411 *missingHarmonicFlag = 0; 412 FDKmemclear(missingHarmonicsIndex,nSfb*sizeof(UCHAR)); 413 } 414 415 416 417 /* 418 Noise floor estimation 419 */ 420 421 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode; 422 423 FDKsbrEnc_sbrNoiseFloorEstimateQmf(&hTonCorr->sbrNoiseFloorEstimate, 424 frameInfo, 425 noiseLevels, 426 hTonCorr->quotaMatrix, 427 hTonCorr->indexVector, 428 *missingHarmonicFlag, 429 hTonCorr->frameStartIndex, 430 hTonCorr->numberOfEstimatesPerFrame, 431 transientFrame, 432 infVecPtr, 433 sbrSyntaxFlags); 434 435 436 /* Store the invfVec data for the next frame...*/ 437 for(band = 0 ; band < hTonCorr->sbrInvFilt.noDetectorBands; band++){ 438 hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band]; 439 } 440 } 441 442 /**************************************************************************/ 443 /*! 444 \brief Searches for the closest match in the frequency master table. 445 446 447 448 \return closest entry. 449 450 */ 451 /**************************************************************************/ 452 static INT 453 findClosestEntry(INT goalSb, 454 UCHAR *v_k_master, 455 INT numMaster, 456 INT direction) 457 { 458 INT index; 459 460 if( goalSb <= v_k_master[0] ) 461 return v_k_master[0]; 462 463 if( goalSb >= v_k_master[numMaster] ) 464 return v_k_master[numMaster]; 465 466 if(direction) { 467 index = 0; 468 while( v_k_master[index] < goalSb ) { 469 index++; 470 } 471 } else { 472 index = numMaster; 473 while( v_k_master[index] > goalSb ) { 474 index--; 475 } 476 } 477 478 return v_k_master[index]; 479 } 480 481 482 /**************************************************************************/ 483 /*! 484 \brief resets the patch 485 486 487 488 \return errorCode, noError if successful. 489 490 */ 491 /**************************************************************************/ 492 static INT 493 resetPatch(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 494 INT xposctrl, /*!< Different patch modes. */ 495 INT highBandStartSb, /*!< Start band of the SBR range. */ 496 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/ 497 INT numMaster, /*!< Number of elements in the master table. */ 498 INT fs, /*!< Sampling frequency. */ 499 INT noChannels) /*!< Number of QMF-channels. */ 500 { 501 INT patch,k,i; 502 INT targetStopBand; 503 504 PATCH_PARAM *patchParam = hTonCorr->patchParam; 505 506 INT sbGuard = hTonCorr->guard; 507 INT sourceStartBand; 508 INT patchDistance; 509 INT numBandsInPatch; 510 511 INT lsb = v_k_master[0]; /* Lowest subband related to the synthesis filterbank */ 512 INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis filterbank */ 513 INT xoverOffset = highBandStartSb - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */ 514 515 INT goalSb; 516 517 518 /* 519 * Initialize the patching parameter 520 */ 521 522 if (xposctrl == 1) { 523 lsb += xoverOffset; 524 xoverOffset = 0; 525 } 526 527 goalSb = (INT)( (2 * noChannels * 16000 + (fs>>1)) / fs ); /* 16 kHz band */ 528 goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 1); /* Adapt region to master-table */ 529 530 /* First patch */ 531 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset; 532 targetStopBand = lsb + xoverOffset; 533 534 /* even (odd) numbered channel must be patched to even (odd) numbered channel */ 535 patch = 0; 536 while(targetStopBand < usb) { 537 538 /* To many patches */ 539 if (patch >= MAX_NUM_PATCHES) 540 return(1); /*Number of patches to high */ 541 542 patchParam[patch].guardStartBand = targetStopBand; 543 targetStopBand += sbGuard; 544 patchParam[patch].targetStartBand = targetStopBand; 545 546 numBandsInPatch = goalSb - targetStopBand; /* get the desired range of the patch */ 547 548 if ( numBandsInPatch >= lsb - sourceStartBand ) { 549 /* desired number bands are not available -> patch whole source range */ 550 patchDistance = targetStopBand - sourceStartBand; /* get the targetOffset */ 551 patchDistance = patchDistance & ~1; /* rounding off odd numbers and make all even */ 552 numBandsInPatch = lsb - (targetStopBand - patchDistance); 553 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) - 554 targetStopBand; /* Adapt region to master-table */ 555 } 556 557 /* desired number bands are available -> get the minimal even patching distance */ 558 patchDistance = numBandsInPatch + targetStopBand - lsb; /* get minimal distance */ 559 patchDistance = (patchDistance + 1) & ~1; /* rounding up odd numbers and make all even */ 560 561 if (numBandsInPatch <= 0) { 562 patch--; 563 } else { 564 patchParam[patch].sourceStartBand = targetStopBand - patchDistance; 565 patchParam[patch].targetBandOffs = patchDistance; 566 patchParam[patch].numBandsInPatch = numBandsInPatch; 567 patchParam[patch].sourceStopBand = patchParam[patch].sourceStartBand + numBandsInPatch; 568 569 targetStopBand += patchParam[patch].numBandsInPatch; 570 } 571 572 /* All patches but first */ 573 sourceStartBand = hTonCorr->shiftStartSb; 574 575 /* Check if we are close to goalSb */ 576 if( fixp_abs(targetStopBand - goalSb) < 3) { 577 goalSb = usb; 578 } 579 580 patch++; 581 582 } 583 584 patch--; 585 586 /* if highest patch contains less than three subband: skip it */ 587 if ( patchParam[patch].numBandsInPatch < 3 && patch > 0 ) { 588 patch--; 589 targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch; 590 } 591 592 hTonCorr->noOfPatches = patch + 1; 593 594 595 /* Assign the index-vector, so we know where to look for the high-band. 596 -1 represents a guard-band. */ 597 for(k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++) 598 hTonCorr->indexVector[k] = k; 599 600 for(i = 0; i < hTonCorr->noOfPatches; i++) 601 { 602 INT sourceStart = hTonCorr->patchParam[i].sourceStartBand; 603 INT targetStart = hTonCorr->patchParam[i].targetStartBand; 604 INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch; 605 INT startGuardBand = hTonCorr->patchParam[i].guardStartBand; 606 607 for(k = 0; k < (targetStart- startGuardBand); k++) 608 hTonCorr->indexVector[startGuardBand+k] = -1; 609 610 for(k = 0; k < numberOfBands; k++) 611 hTonCorr->indexVector[targetStart+k] = sourceStart+k; 612 } 613 614 return (0); 615 } 616 617 /**************************************************************************/ 618 /*! 619 \brief Creates an instance of the tonality correction parameter module. 620 621 The module includes modules for inverse filtering level estimation, 622 missing harmonics detection and noise floor level estimation. 623 624 \return errorCode, noError if successful. 625 */ 626 /**************************************************************************/ 627 INT 628 FDKsbrEnc_CreateTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 629 INT chan) /*!< Channel index, needed for mem allocation */ 630 { 631 INT i; 632 FIXP_DBL* quotaMatrix = GetRam_Sbr_quotaMatrix(chan); 633 INT* signMatrix = GetRam_Sbr_signMatrix(chan); 634 635 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST)); 636 637 for (i=0; i<MAX_NO_OF_ESTIMATES; i++) { 638 hTonCorr->quotaMatrix[i] = quotaMatrix + (i*QMF_CHANNELS); 639 hTonCorr->signMatrix[i] = signMatrix + (i*QMF_CHANNELS); 640 } 641 642 FDKsbrEnc_CreateSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, chan); 643 644 return 0; 645 } 646 647 648 649 /**************************************************************************/ 650 /*! 651 \brief Initialize an instance of the tonality correction parameter module. 652 653 The module includes modules for inverse filtering level estimation, 654 missing harmonics detection and noise floor level estimation. 655 656 \return errorCode, noError if successful. 657 */ 658 /**************************************************************************/ 659 INT 660 FDKsbrEnc_InitTonCorrParamExtr (INT frameSize, /*!< Current SBR frame size. */ 661 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 662 HANDLE_SBR_CONFIG_DATA sbrCfg, /*!< Pointer to SBR configuration parameters. */ 663 INT timeSlots, /*!< Number of time-slots per frame */ 664 INT xposCtrl, /*!< Different patch modes. */ 665 INT ana_max_level, /*!< Maximum level of the adaptive noise. */ 666 INT noiseBands, /*!< Number of noise bands per octave. */ 667 INT noiseFloorOffset, /*!< Noise floor offset. */ 668 UINT useSpeechConfig) /*!< Speech or music tuning. */ 669 { 670 INT nCols = sbrCfg->noQmfSlots; 671 INT fs = sbrCfg->sampleFreq; 672 INT noQmfChannels = sbrCfg->noQmfBands; 673 674 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0]; 675 UCHAR *v_k_master = sbrCfg->v_k_master; 676 INT numMaster = sbrCfg->num_Master; 677 678 UCHAR **freqBandTable = sbrCfg->freqBandTable; 679 INT *nSfb = sbrCfg->nSfb; 680 681 INT i; 682 683 /* 684 Reset the patching and allocate memory for the quota matrix. 685 Assuming parameters for the LPC analysis. 686 */ 687 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { 688 switch (timeSlots) { 689 case NUMBER_TIME_SLOTS_1920: 690 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 691 hTonCorr->lpcLength[1] = 7 - LPC_ORDER; 692 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 693 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */ 694 hTonCorr->frameStartIndexInvfEst = 0; 695 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 696 break; 697 case NUMBER_TIME_SLOTS_2048: 698 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 699 hTonCorr->lpcLength[1] = 8 - LPC_ORDER; 700 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 701 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */ 702 hTonCorr->frameStartIndexInvfEst = 0; 703 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 704 break; 705 } 706 } else 707 switch (timeSlots) { 708 case NUMBER_TIME_SLOTS_2048: 709 hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */ 710 hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */ 711 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 712 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16; 713 hTonCorr->frameStartIndexInvfEst = 0; 714 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048; 715 break; 716 case NUMBER_TIME_SLOTS_1920: 717 hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */ 718 hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */ 719 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 720 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15; 721 hTonCorr->frameStartIndexInvfEst = 0; 722 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920; 723 break; 724 default: 725 return -1; 726 } 727 728 hTonCorr->bufferLength = nCols; 729 hTonCorr->stepSize = hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */ 730 731 hTonCorr->nextSample = LPC_ORDER; /* firstSample */ 732 hTonCorr->move = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates to move when buffering.*/ 733 hTonCorr->startIndexMatrix = hTonCorr->numberOfEstimates - hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest estimations in the tonality Matrix.*/ 734 hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current frame (to be sent to the decoder) starts. */ 735 hTonCorr->prevTransientFlag = 0; 736 hTonCorr->transientNextFrame = 0; 737 738 hTonCorr->noQmfChannels = noQmfChannels; 739 740 for (i=0; i<hTonCorr->numberOfEstimates; i++) { 741 FDKmemclear (hTonCorr->quotaMatrix[i] , sizeof(FIXP_DBL)*noQmfChannels); 742 FDKmemclear (hTonCorr->signMatrix[i] , sizeof(INT)*noQmfChannels); 743 } 744 745 /* Reset the patch.*/ 746 hTonCorr->guard = 0; 747 hTonCorr->shiftStartSb = 1; 748 749 if(resetPatch(hTonCorr, 750 xposCtrl, 751 highBandStartSb, 752 v_k_master, 753 numMaster, 754 fs, 755 noQmfChannels)) 756 return(1); 757 758 if(FDKsbrEnc_InitSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate, 759 ana_max_level, 760 freqBandTable[LO], 761 nSfb[LO], 762 noiseBands, 763 noiseFloorOffset, 764 timeSlots, 765 useSpeechConfig)) 766 return(1); 767 768 769 if(FDKsbrEnc_initInvFiltDetector(&hTonCorr->sbrInvFilt, 770 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 771 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, 772 useSpeechConfig)) 773 return(1); 774 775 776 777 if(FDKsbrEnc_InitSbrMissingHarmonicsDetector( 778 &hTonCorr->sbrMissingHarmonicsDetector, 779 fs, 780 frameSize, 781 nSfb[HI], 782 noQmfChannels, 783 hTonCorr->numberOfEstimates, 784 hTonCorr->move, 785 hTonCorr->numberOfEstimatesPerFrame, 786 sbrCfg->sbrSyntaxFlags)) 787 return(1); 788 789 790 791 return (0); 792 } 793 794 795 796 /**************************************************************************/ 797 /*! 798 \brief resets tonality correction parameter module. 799 800 801 802 \return errorCode, noError if successful. 803 804 */ 805 /**************************************************************************/ 806 INT 807 FDKsbrEnc_ResetTonCorrParamExtr(HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 808 INT xposctrl, /*!< Different patch modes. */ 809 INT highBandStartSb, /*!< Start band of the SBR range. */ 810 UCHAR *v_k_master, /*!< Master frequency table from which all other table are derived.*/ 811 INT numMaster, /*!< Number of elements in the master table. */ 812 INT fs, /*!< Sampling frequency (of the SBR part). */ 813 UCHAR ** freqBandTable, /*!< Frequency band table for low-res and high-res. */ 814 INT* nSfb, /*!< Number of frequency bands (hig-res and low-res). */ 815 INT noQmfChannels /*!< Number of QMF channels. */ 816 ) 817 { 818 819 /* Reset the patch.*/ 820 hTonCorr->guard = 0; 821 hTonCorr->shiftStartSb = 1; 822 823 if(resetPatch(hTonCorr, 824 xposctrl, 825 highBandStartSb, 826 v_k_master, 827 numMaster, 828 fs, 829 noQmfChannels)) 830 return(1); 831 832 833 834 /* Reset the noise floor estimate.*/ 835 if(FDKsbrEnc_resetSbrNoiseFloorEstimate (&hTonCorr->sbrNoiseFloorEstimate, 836 freqBandTable[LO], 837 nSfb[LO])) 838 return(1); 839 840 /* 841 Reset the inveerse filtereing detector. 842 */ 843 if(FDKsbrEnc_resetInvFiltDetector(&hTonCorr->sbrInvFilt, 844 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 845 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands)) 846 return(1); 847 /* Reset the missing harmonics detector. */ 848 if(FDKsbrEnc_ResetSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector, 849 nSfb[HI])) 850 return(1); 851 852 return (0); 853 } 854 855 856 857 858 859 /**************************************************************************/ 860 /*! 861 \brief Deletes the tonality correction paramtere module. 862 863 864 865 \return none 866 867 */ 868 /**************************************************************************/ 869 void 870 FDKsbrEnc_DeleteTonCorrParamExtr (HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */ 871 { 872 873 if (hTonCorr) { 874 875 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix); 876 877 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix); 878 879 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector (&hTonCorr->sbrMissingHarmonicsDetector); 880 } 881 } 882