1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten 5 Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10 scheme for digital audio. This FDK AAC Codec software is intended to be used on 11 a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14 general perceptual audio codecs. AAC-ELD is considered the best-performing 15 full-bandwidth communications codec by independent studies and is widely 16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17 specifications. 18 19 Patent licenses for necessary patent claims for the FDK AAC Codec (including 20 those of Fraunhofer) may be obtained through Via Licensing 21 (www.vialicensing.com) or through the respective patent owners individually for 22 the purpose of encoding or decoding bit streams in products that are compliant 23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24 Android devices already license these patent claims through Via Licensing or 25 directly from the patent owners, and therefore FDK AAC Codec software may 26 already be covered under those patent licenses when it is used for those 27 licensed purposes only. 28 29 Commercially-licensed AAC software libraries, including floating-point versions 30 with enhanced sound quality, are also available from Fraunhofer. Users are 31 encouraged to check the Fraunhofer website for additional applications 32 information and documentation. 33 34 2. COPYRIGHT LICENSE 35 36 Redistribution and use in source and binary forms, with or without modification, 37 are permitted without payment of copyright license fees provided that you 38 satisfy the following conditions: 39 40 You must retain the complete text of this software license in redistributions of 41 the FDK AAC Codec or your modifications thereto in source code form. 42 43 You must retain the complete text of this software license in the documentation 44 and/or other materials provided with redistributions of the FDK AAC Codec or 45 your modifications thereto in binary form. You must make available free of 46 charge copies of the complete source code of the FDK AAC Codec and your 47 modifications thereto to recipients of copies in binary form. 48 49 The name of Fraunhofer may not be used to endorse or promote products derived 50 from this library without prior written permission. 51 52 You may not charge copyright license fees for anyone to use, copy or distribute 53 the FDK AAC Codec software or your modifications thereto. 54 55 Your modified versions of the FDK AAC Codec must carry prominent notices stating 56 that you changed the software and the date of any change. For modified versions 57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59 AAC Codec Library for Android." 60 61 3. NO PATENT LICENSE 62 63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65 Fraunhofer provides no warranty of patent non-infringement with respect to this 66 software. 67 68 You may use this FDK AAC Codec software or modifications thereto only for 69 purposes that are authorized by appropriate patent licenses. 70 71 4. DISCLAIMER 72 73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75 including but not limited to the implied warranties of merchantability and 76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78 or consequential damages, including but not limited to procurement of substitute 79 goods or services; loss of use, data, or profits, or business interruption, 80 however caused and on any theory of liability, whether in contract, strict 81 liability, or tort (including negligence), arising in any way out of the use of 82 this software, even if advised of the possibility of such damage. 83 84 5. CONTACT INFORMATION 85 86 Fraunhofer Institute for Integrated Circuits IIS 87 Attention: Audio and Multimedia Departments - FDK AAC LL 88 Am Wolfsmantel 33 89 91058 Erlangen, Germany 90 91 www.iis.fraunhofer.de/amm 92 amm-info (at) iis.fraunhofer.de 93 ----------------------------------------------------------------------------- */ 94 95 /**************************** SBR encoder library ****************************** 96 97 Author(s): 98 99 Description: 100 101 *******************************************************************************/ 102 103 #include "ton_corr.h" 104 105 #include "sbrenc_ram.h" 106 #include "sbr_misc.h" 107 #include "genericStds.h" 108 #include "autocorr2nd.h" 109 110 #define BAND_V_SIZE 32 111 #define NUM_V_COMBINE \ 112 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */ 113 114 /**************************************************************************/ 115 /*! 116 \brief Calculates the tonal to noise ration for different frequency bands 117 and time segments. 118 119 The ratio between the predicted energy (tonal energy A) and the total 120 energy (A + B) is calculated. This is converted to the ratio between 121 the predicted energy (tonal energy A) and the non-predictable energy 122 (noise energy B). Hence the quota-matrix contains A/B = q/(1-q). 123 124 The samples in nrgVector are scaled by 1.0/16.0 125 The samples in pNrgVectorFreq are scaled by 1.0/2.0 126 The samples in quotaMatrix are scaled by RELAXATION 127 128 \return none. 129 130 */ 131 /**************************************************************************/ 132 133 void FDKsbrEnc_CalculateTonalityQuotas( 134 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 135 FIXP_DBL **RESTRICT 136 sourceBufferReal, /*!< The real part of the QMF-matrix. */ 137 FIXP_DBL **RESTRICT 138 sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */ 139 INT usb, /*!< upper side band, highest + 1 QMF band in the SBR range. */ 140 INT qmfScale /*!< sclefactor of QMF subsamples */ 141 ) { 142 INT i, k, r, r2, timeIndex, autoCorrScaling; 143 144 INT startIndexMatrix = hTonCorr->startIndexMatrix; 145 INT totNoEst = hTonCorr->numberOfEstimates; 146 INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame; 147 INT move = hTonCorr->move; 148 INT noQmfChannels = hTonCorr->noQmfChannels; /* Number of Bands */ 149 INT buffLen = hTonCorr->bufferLength; /* Number of Slots */ 150 INT stepSize = hTonCorr->stepSize; 151 INT *pBlockLength = hTonCorr->lpcLength; 152 INT **RESTRICT signMatrix = hTonCorr->signMatrix; 153 FIXP_DBL *RESTRICT nrgVector = hTonCorr->nrgVector; 154 FIXP_DBL **RESTRICT quotaMatrix = hTonCorr->quotaMatrix; 155 FIXP_DBL *RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq; 156 157 FIXP_DBL *realBuf; 158 FIXP_DBL *imagBuf; 159 160 FIXP_DBL alphar[2], alphai[2], fac; 161 162 C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1) 163 C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE) 164 realBuf = realBufRef; 165 imagBuf = realBuf + BAND_V_SIZE * NUM_V_COMBINE; 166 167 FDK_ASSERT(buffLen <= BAND_V_SIZE); 168 FDK_ASSERT(sizeof(FIXP_DBL) * NUM_V_COMBINE * BAND_V_SIZE * 2 < 169 (1024 * sizeof(FIXP_DBL) - sizeof(ACORR_COEFS))); 170 171 /* 172 * Buffering of the quotaMatrix and the quotaMatrixTransp. 173 *********************************************************/ 174 for (i = 0; i < move; i++) { 175 FDKmemcpy(quotaMatrix[i], quotaMatrix[i + noEstPerFrame], 176 noQmfChannels * sizeof(FIXP_DBL)); 177 FDKmemcpy(signMatrix[i], signMatrix[i + noEstPerFrame], 178 noQmfChannels * sizeof(INT)); 179 } 180 181 FDKmemmove(nrgVector, nrgVector + noEstPerFrame, move * sizeof(FIXP_DBL)); 182 FDKmemclear(nrgVector + startIndexMatrix, 183 (totNoEst - startIndexMatrix) * sizeof(FIXP_DBL)); 184 FDKmemclear(pNrgVectorFreq, noQmfChannels * sizeof(FIXP_DBL)); 185 186 /* 187 * Calculate the quotas for the current time steps. 188 **************************************************/ 189 190 for (r = 0; r < usb; r++) { 191 int blockLength; 192 193 k = hTonCorr->nextSample; /* startSample */ 194 timeIndex = startIndexMatrix; 195 /* Copy as many as possible Band across all Slots at once */ 196 if (realBuf != realBufRef) { 197 realBuf -= BAND_V_SIZE; 198 imagBuf -= BAND_V_SIZE; 199 } else { 200 realBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1); 201 imagBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1); 202 203 for (i = 0; i < buffLen; i++) { 204 int v; 205 FIXP_DBL *ptr; 206 ptr = realBuf + i; 207 for (v = 0; v < NUM_V_COMBINE; v++) { 208 ptr[0] = sourceBufferReal[i][r + v]; 209 ptr[0 + BAND_V_SIZE * NUM_V_COMBINE] = sourceBufferImag[i][r + v]; 210 ptr -= BAND_V_SIZE; 211 } 212 } 213 } 214 215 blockLength = pBlockLength[0]; 216 217 while (k <= buffLen - blockLength) { 218 autoCorrScaling = fixMin( 219 getScalefactor(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength), 220 getScalefactor(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength)); 221 autoCorrScaling = fixMax(0, autoCorrScaling - 1); 222 223 scaleValues(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength, 224 autoCorrScaling); 225 scaleValues(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength, 226 autoCorrScaling); 227 228 autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */ 229 autoCorrScaling += 230 autoCorr2nd_cplx(ac, realBuf + k, imagBuf + k, blockLength); 231 232 if (ac->det == FL2FXCONST_DBL(0.0f)) { 233 alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f); 234 235 alphar[0] = (ac->r01r) >> 2; 236 alphai[0] = (ac->r01i) >> 2; 237 238 fac = fMultDiv2(ac->r00r, ac->r11r) >> 1; 239 } else { 240 alphar[1] = (fMultDiv2(ac->r01r, ac->r12r) >> 1) - 241 (fMultDiv2(ac->r01i, ac->r12i) >> 1) - 242 (fMultDiv2(ac->r02r, ac->r11r) >> 1); 243 alphai[1] = (fMultDiv2(ac->r01i, ac->r12r) >> 1) + 244 (fMultDiv2(ac->r01r, ac->r12i) >> 1) - 245 (fMultDiv2(ac->r02i, ac->r11r) >> 1); 246 247 alphar[0] = (fMultDiv2(ac->r01r, ac->det) >> (ac->det_scale + 1)) + 248 fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i); 249 alphai[0] = (fMultDiv2(ac->r01i, ac->det) >> (ac->det_scale + 1)) + 250 fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i); 251 252 fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r)) >> 253 (ac->det_scale + 1); 254 } 255 256 if (fac == FL2FXCONST_DBL(0.0f)) { 257 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); 258 signMatrix[timeIndex][r] = 0; 259 } else { 260 /* quotaMatrix is scaled with the factor RELAXATION 261 parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 * 262 2^RELAXATION_SHIFT) */ 263 FIXP_DBL tmp, num, denom; 264 INT numShift, denomShift, commonShift; 265 INT sign; 266 267 num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) - 268 fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) - 269 fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r)); 270 num = fixp_abs(num); 271 272 denom = (fac >> 1) + 273 (fMultDiv2(fac, RELAXATION_FRACT) >> RELAXATION_SHIFT) - num; 274 denom = fixp_abs(denom); 275 276 num = fMult(num, RELAXATION_FRACT); 277 278 numShift = CountLeadingBits(num) - 2; 279 num = scaleValue(num, numShift); 280 281 denomShift = CountLeadingBits(denom); 282 denom = (FIXP_DBL)denom << denomShift; 283 284 if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) { 285 commonShift = 286 fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS - 1); 287 if (commonShift < 0) { 288 commonShift = -commonShift; 289 tmp = schur_div(num, denom, 16); 290 commonShift = fixMin(commonShift, CountLeadingBits(tmp)); 291 quotaMatrix[timeIndex][r] = tmp << commonShift; 292 } else { 293 quotaMatrix[timeIndex][r] = 294 schur_div(num, denom, 16) >> commonShift; 295 } 296 } else { 297 quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); 298 } 299 300 if (ac->r11r != FL2FXCONST_DBL(0.0f)) { 301 if (((ac->r01r >= FL2FXCONST_DBL(0.0f)) && 302 (ac->r11r >= FL2FXCONST_DBL(0.0f))) || 303 ((ac->r01r < FL2FXCONST_DBL(0.0f)) && 304 (ac->r11r < FL2FXCONST_DBL(0.0f)))) { 305 sign = 1; 306 } else { 307 sign = -1; 308 } 309 } else { 310 sign = 1; 311 } 312 313 if (sign < 0) { 314 r2 = r; /* (INT) pow(-1, band); */ 315 } else { 316 r2 = r + 1; /* (INT) pow(-1, band+1); */ 317 } 318 signMatrix[timeIndex][r] = 1 - 2 * (r2 & 0x1); 319 } 320 321 nrgVector[timeIndex] += 322 ((ac->r00r) >> 323 fixMin(DFRACT_BITS - 1, 324 (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC))); 325 /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced 326 * division by shifting with one */ 327 pNrgVectorFreq[r] = 328 pNrgVectorFreq[r] + 329 ((ac->r00r) >> 330 fixMin(DFRACT_BITS - 1, 331 (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC))); 332 333 blockLength = pBlockLength[1]; 334 k += stepSize; 335 timeIndex++; 336 } 337 } 338 339 C_ALLOC_SCRATCH_END(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE) 340 C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1) 341 } 342 343 /**************************************************************************/ 344 /*! 345 \brief Extracts the parameters required in the decoder to obtain the 346 correct tonal to noise ratio after SBR. 347 348 Estimates the tonal to noise ratio of the original signal (using LPC). 349 Predicts the tonal to noise ration of the SBR signal (in the decoder) by 350 patching the tonal to noise ratio values similar to the patching of the 351 lowband in the decoder. Given the tonal to noise ratio of the original 352 and the SBR signal, it estimates the required amount of inverse filtering, 353 additional noise as well as any additional sines. 354 355 \return none. 356 357 */ 358 /**************************************************************************/ 359 void FDKsbrEnc_TonCorrParamExtr( 360 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 361 INVF_MODE *infVec, /*!< Vector where the inverse filtering levels will be 362 stored. */ 363 FIXP_DBL *noiseLevels, /*!< Vector where the noise levels will be stored. */ 364 INT *missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any 365 strong sines are missing.*/ 366 UCHAR *missingHarmonicsIndex, /*!< Vector indicating where sines are 367 missing. */ 368 UCHAR *envelopeCompensation, /*!< Vector to store compensation values for 369 the energies in. */ 370 const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time 371 and frequency grid of the current 372 frame.*/ 373 UCHAR *transientInfo, /*!< Transient info.*/ 374 UCHAR *freqBandTable, /*!< Frequency band tables for high-res.*/ 375 INT nSfb, /*!< Number of scalefactor bands for high-res. */ 376 XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/ 377 UINT sbrSyntaxFlags) { 378 INT band; 379 INT transientFlag = transientInfo[1]; /*!< Flag indicating if a transient is 380 present in the current frame. */ 381 INT transientPos = transientInfo[0]; /*!< Position of the transient.*/ 382 INT transientFrame, transientFrameInvfEst; 383 INVF_MODE *infVecPtr; 384 385 /* Determine if this is a frame where a transient starts... 386 387 The detection of noise-floor, missing harmonics and invf_est, is not in sync 388 for the non-buf-opt decoder such as AAC. Hence we need to keep track on the 389 transient in the present frame as well as in the next. 390 */ 391 transientFrame = 0; 392 if (hTonCorr->transientNextFrame) { /* The transient was detected in the 393 previous frame, but is actually */ 394 transientFrame = 1; 395 hTonCorr->transientNextFrame = 0; 396 397 if (transientFlag) { 398 if (transientPos + hTonCorr->transientPosOffset >= 399 frameInfo->borders[frameInfo->nEnvelopes]) { 400 hTonCorr->transientNextFrame = 1; 401 } 402 } 403 } else { 404 if (transientFlag) { 405 if (transientPos + hTonCorr->transientPosOffset < 406 frameInfo->borders[frameInfo->nEnvelopes]) { 407 transientFrame = 1; 408 hTonCorr->transientNextFrame = 0; 409 } else { 410 hTonCorr->transientNextFrame = 1; 411 } 412 } 413 } 414 transientFrameInvfEst = transientFrame; 415 416 /* 417 Estimate the required invese filtereing level. 418 */ 419 if (hTonCorr->switchInverseFilt) 420 FDKsbrEnc_qmfInverseFilteringDetector( 421 &hTonCorr->sbrInvFilt, hTonCorr->quotaMatrix, hTonCorr->nrgVector, 422 hTonCorr->indexVector, hTonCorr->frameStartIndexInvfEst, 423 hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst, 424 transientFrameInvfEst, infVec); 425 426 /* 427 Detect what tones will be missing. 428 */ 429 if (xposType == XPOS_LC) { 430 FDKsbrEnc_SbrMissingHarmonicsDetectorQmf( 431 &hTonCorr->sbrMissingHarmonicsDetector, hTonCorr->quotaMatrix, 432 hTonCorr->signMatrix, hTonCorr->indexVector, frameInfo, transientInfo, 433 missingHarmonicFlag, missingHarmonicsIndex, freqBandTable, nSfb, 434 envelopeCompensation, hTonCorr->nrgVectorFreq); 435 } else { 436 *missingHarmonicFlag = 0; 437 FDKmemclear(missingHarmonicsIndex, nSfb * sizeof(UCHAR)); 438 } 439 440 /* 441 Noise floor estimation 442 */ 443 444 infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode; 445 446 FDKsbrEnc_sbrNoiseFloorEstimateQmf( 447 &hTonCorr->sbrNoiseFloorEstimate, frameInfo, noiseLevels, 448 hTonCorr->quotaMatrix, hTonCorr->indexVector, *missingHarmonicFlag, 449 hTonCorr->frameStartIndex, hTonCorr->numberOfEstimatesPerFrame, 450 transientFrame, infVecPtr, sbrSyntaxFlags); 451 452 /* Store the invfVec data for the next frame...*/ 453 for (band = 0; band < hTonCorr->sbrInvFilt.noDetectorBands; band++) { 454 hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band]; 455 } 456 } 457 458 /**************************************************************************/ 459 /*! 460 \brief Searches for the closest match in the frequency master table. 461 462 463 464 \return closest entry. 465 466 */ 467 /**************************************************************************/ 468 static INT findClosestEntry(INT goalSb, UCHAR *v_k_master, INT numMaster, 469 INT direction) { 470 INT index; 471 472 if (goalSb <= v_k_master[0]) return v_k_master[0]; 473 474 if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster]; 475 476 if (direction) { 477 index = 0; 478 while (v_k_master[index] < goalSb) { 479 index++; 480 } 481 } else { 482 index = numMaster; 483 while (v_k_master[index] > goalSb) { 484 index--; 485 } 486 } 487 488 return v_k_master[index]; 489 } 490 491 /**************************************************************************/ 492 /*! 493 \brief resets the patch 494 495 496 497 \return errorCode, noError if successful. 498 499 */ 500 /**************************************************************************/ 501 static INT resetPatch( 502 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 503 INT xposctrl, /*!< Different patch modes. */ 504 INT highBandStartSb, /*!< Start band of the SBR range. */ 505 UCHAR *v_k_master, /*!< Master frequency table from which all other table 506 are derived.*/ 507 INT numMaster, /*!< Number of elements in the master table. */ 508 INT fs, /*!< Sampling frequency. */ 509 INT noChannels) /*!< Number of QMF-channels. */ 510 { 511 INT patch, k, i; 512 INT targetStopBand; 513 514 PATCH_PARAM *patchParam = hTonCorr->patchParam; 515 516 INT sbGuard = hTonCorr->guard; 517 INT sourceStartBand; 518 INT patchDistance; 519 INT numBandsInPatch; 520 521 INT lsb = 522 v_k_master[0]; /* Lowest subband related to the synthesis filterbank */ 523 INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis 524 filterbank */ 525 INT xoverOffset = 526 highBandStartSb - 527 v_k_master[0]; /* Calculate distance in subbands between k0 and kx */ 528 529 INT goalSb; 530 531 /* 532 * Initialize the patching parameter 533 */ 534 535 if (xposctrl == 1) { 536 lsb += xoverOffset; 537 xoverOffset = 0; 538 } 539 540 goalSb = (INT)((2 * noChannels * 16000 + (fs >> 1)) / fs); /* 16 kHz band */ 541 goalSb = findClosestEntry(goalSb, v_k_master, numMaster, 542 1); /* Adapt region to master-table */ 543 544 /* First patch */ 545 sourceStartBand = hTonCorr->shiftStartSb + xoverOffset; 546 targetStopBand = lsb + xoverOffset; 547 548 /* even (odd) numbered channel must be patched to even (odd) numbered channel 549 */ 550 patch = 0; 551 while (targetStopBand < usb) { 552 /* To many patches */ 553 if (patch >= MAX_NUM_PATCHES) return (1); /*Number of patches to high */ 554 555 patchParam[patch].guardStartBand = targetStopBand; 556 targetStopBand += sbGuard; 557 patchParam[patch].targetStartBand = targetStopBand; 558 559 numBandsInPatch = 560 goalSb - targetStopBand; /* get the desired range of the patch */ 561 562 if (numBandsInPatch >= lsb - sourceStartBand) { 563 /* desired number bands are not available -> patch whole source range */ 564 patchDistance = 565 targetStopBand - sourceStartBand; /* get the targetOffset */ 566 patchDistance = 567 patchDistance & ~1; /* rounding off odd numbers and make all even */ 568 numBandsInPatch = lsb - (targetStopBand - patchDistance); 569 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, 570 v_k_master, numMaster, 0) - 571 targetStopBand; /* Adapt region to master-table */ 572 } 573 574 /* desired number bands are available -> get the minimal even patching 575 * distance */ 576 patchDistance = 577 numBandsInPatch + targetStopBand - lsb; /* get minimal distance */ 578 patchDistance = (patchDistance + 1) & 579 ~1; /* rounding up odd numbers and make all even */ 580 581 if (numBandsInPatch <= 0) { 582 patch--; 583 } else { 584 patchParam[patch].sourceStartBand = targetStopBand - patchDistance; 585 patchParam[patch].targetBandOffs = patchDistance; 586 patchParam[patch].numBandsInPatch = numBandsInPatch; 587 patchParam[patch].sourceStopBand = 588 patchParam[patch].sourceStartBand + numBandsInPatch; 589 590 targetStopBand += patchParam[patch].numBandsInPatch; 591 } 592 593 /* All patches but first */ 594 sourceStartBand = hTonCorr->shiftStartSb; 595 596 /* Check if we are close to goalSb */ 597 if (fixp_abs(targetStopBand - goalSb) < 3) { 598 goalSb = usb; 599 } 600 601 patch++; 602 } 603 604 patch--; 605 606 /* if highest patch contains less than three subband: skip it */ 607 if (patchParam[patch].numBandsInPatch < 3 && patch > 0) { 608 patch--; 609 } 610 611 hTonCorr->noOfPatches = patch + 1; 612 613 /* Assign the index-vector, so we know where to look for the high-band. 614 -1 represents a guard-band. */ 615 for (k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++) 616 hTonCorr->indexVector[k] = k; 617 618 for (i = 0; i < hTonCorr->noOfPatches; i++) { 619 INT sourceStart = hTonCorr->patchParam[i].sourceStartBand; 620 INT targetStart = hTonCorr->patchParam[i].targetStartBand; 621 INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch; 622 INT startGuardBand = hTonCorr->patchParam[i].guardStartBand; 623 624 for (k = 0; k < (targetStart - startGuardBand); k++) 625 hTonCorr->indexVector[startGuardBand + k] = -1; 626 627 for (k = 0; k < numberOfBands; k++) 628 hTonCorr->indexVector[targetStart + k] = sourceStart + k; 629 } 630 631 return (0); 632 } 633 634 /**************************************************************************/ 635 /*! 636 \brief Creates an instance of the tonality correction parameter module. 637 638 The module includes modules for inverse filtering level estimation, 639 missing harmonics detection and noise floor level estimation. 640 641 \return errorCode, noError if successful. 642 */ 643 /**************************************************************************/ 644 INT FDKsbrEnc_CreateTonCorrParamExtr( 645 HANDLE_SBR_TON_CORR_EST 646 hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 647 INT chan) /*!< Channel index, needed for mem allocation */ 648 { 649 INT i; 650 FIXP_DBL *quotaMatrix = GetRam_Sbr_quotaMatrix(chan); 651 INT *signMatrix = GetRam_Sbr_signMatrix(chan); 652 653 if ((NULL == quotaMatrix) || (NULL == signMatrix)) { 654 goto bail; 655 } 656 657 FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST)); 658 659 for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) { 660 hTonCorr->quotaMatrix[i] = quotaMatrix + (i * 64); 661 hTonCorr->signMatrix[i] = signMatrix + (i * 64); 662 } 663 664 if (0 != FDKsbrEnc_CreateSbrMissingHarmonicsDetector( 665 &hTonCorr->sbrMissingHarmonicsDetector, chan)) { 666 goto bail; 667 } 668 669 return 0; 670 671 bail: 672 hTonCorr->quotaMatrix[0] = quotaMatrix; 673 hTonCorr->signMatrix[0] = signMatrix; 674 675 FDKsbrEnc_DeleteTonCorrParamExtr(hTonCorr); 676 677 return -1; 678 } 679 680 /**************************************************************************/ 681 /*! 682 \brief Initialize an instance of the tonality correction parameter module. 683 684 The module includes modules for inverse filtering level estimation, 685 missing harmonics detection and noise floor level estimation. 686 687 \return errorCode, noError if successful. 688 */ 689 /**************************************************************************/ 690 INT FDKsbrEnc_InitTonCorrParamExtr( 691 INT frameSize, /*!< Current SBR frame size. */ 692 HANDLE_SBR_TON_CORR_EST 693 hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ 694 HANDLE_SBR_CONFIG_DATA 695 sbrCfg, /*!< Pointer to SBR configuration parameters. */ 696 INT timeSlots, /*!< Number of time-slots per frame */ 697 INT xposCtrl, /*!< Different patch modes. */ 698 INT ana_max_level, /*!< Maximum level of the adaptive noise. */ 699 INT noiseBands, /*!< Number of noise bands per octave. */ 700 INT noiseFloorOffset, /*!< Noise floor offset. */ 701 UINT useSpeechConfig) /*!< Speech or music tuning. */ 702 { 703 INT nCols = sbrCfg->noQmfSlots; 704 INT fs = sbrCfg->sampleFreq; 705 INT noQmfChannels = sbrCfg->noQmfBands; 706 707 INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0]; 708 UCHAR *v_k_master = sbrCfg->v_k_master; 709 INT numMaster = sbrCfg->num_Master; 710 711 UCHAR **freqBandTable = sbrCfg->freqBandTable; 712 INT *nSfb = sbrCfg->nSfb; 713 714 INT i; 715 716 /* 717 Reset the patching and allocate memory for the quota matrix. 718 Assuming parameters for the LPC analysis. 719 */ 720 if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { 721 switch (timeSlots) { 722 case NUMBER_TIME_SLOTS_1920: 723 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 724 hTonCorr->lpcLength[1] = 7 - LPC_ORDER; 725 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 726 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */ 727 hTonCorr->frameStartIndexInvfEst = 0; 728 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 729 break; 730 case NUMBER_TIME_SLOTS_2048: 731 hTonCorr->lpcLength[0] = 8 - LPC_ORDER; 732 hTonCorr->lpcLength[1] = 8 - LPC_ORDER; 733 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; 734 hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */ 735 hTonCorr->frameStartIndexInvfEst = 0; 736 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; 737 break; 738 } 739 } else 740 switch (timeSlots) { 741 case NUMBER_TIME_SLOTS_2048: 742 hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */ 743 hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */ 744 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 745 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16; 746 hTonCorr->frameStartIndexInvfEst = 0; 747 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048; 748 break; 749 case NUMBER_TIME_SLOTS_1920: 750 hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */ 751 hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */ 752 hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; 753 hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15; 754 hTonCorr->frameStartIndexInvfEst = 0; 755 hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920; 756 break; 757 default: 758 return -1; 759 } 760 761 hTonCorr->bufferLength = nCols; 762 hTonCorr->stepSize = 763 hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */ 764 765 hTonCorr->nextSample = LPC_ORDER; /* firstSample */ 766 hTonCorr->move = hTonCorr->numberOfEstimates - 767 hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates 768 to move when 769 buffering.*/ 770 if (hTonCorr->move < 0) { 771 return -1; 772 } 773 hTonCorr->startIndexMatrix = 774 hTonCorr->numberOfEstimates - 775 hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest 776 estimations in the tonality 777 Matrix.*/ 778 hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current 779 frame (to be sent to the decoder) starts. */ 780 hTonCorr->prevTransientFlag = 0; 781 hTonCorr->transientNextFrame = 0; 782 783 hTonCorr->noQmfChannels = noQmfChannels; 784 785 for (i = 0; i < hTonCorr->numberOfEstimates; i++) { 786 FDKmemclear(hTonCorr->quotaMatrix[i], sizeof(FIXP_DBL) * noQmfChannels); 787 FDKmemclear(hTonCorr->signMatrix[i], sizeof(INT) * noQmfChannels); 788 } 789 790 /* Reset the patch.*/ 791 hTonCorr->guard = 0; 792 hTonCorr->shiftStartSb = 1; 793 794 if (resetPatch(hTonCorr, xposCtrl, highBandStartSb, v_k_master, numMaster, fs, 795 noQmfChannels)) 796 return (1); 797 798 if (FDKsbrEnc_InitSbrNoiseFloorEstimate( 799 &hTonCorr->sbrNoiseFloorEstimate, ana_max_level, freqBandTable[LO], 800 nSfb[LO], noiseBands, noiseFloorOffset, timeSlots, useSpeechConfig)) 801 return (1); 802 803 if (FDKsbrEnc_initInvFiltDetector( 804 &hTonCorr->sbrInvFilt, 805 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 806 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, useSpeechConfig)) 807 return (1); 808 809 if (FDKsbrEnc_InitSbrMissingHarmonicsDetector( 810 &hTonCorr->sbrMissingHarmonicsDetector, fs, frameSize, nSfb[HI], 811 noQmfChannels, hTonCorr->numberOfEstimates, hTonCorr->move, 812 hTonCorr->numberOfEstimatesPerFrame, sbrCfg->sbrSyntaxFlags)) 813 return (1); 814 815 return (0); 816 } 817 818 /**************************************************************************/ 819 /*! 820 \brief resets tonality correction parameter module. 821 822 823 824 \return errorCode, noError if successful. 825 826 */ 827 /**************************************************************************/ 828 INT FDKsbrEnc_ResetTonCorrParamExtr( 829 HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ 830 INT xposctrl, /*!< Different patch modes. */ 831 INT highBandStartSb, /*!< Start band of the SBR range. */ 832 UCHAR *v_k_master, /*!< Master frequency table from which all other table 833 are derived.*/ 834 INT numMaster, /*!< Number of elements in the master table. */ 835 INT fs, /*!< Sampling frequency (of the SBR part). */ 836 UCHAR * 837 *freqBandTable, /*!< Frequency band table for low-res and high-res. */ 838 INT *nSfb, /*!< Number of frequency bands (hig-res and low-res). */ 839 INT noQmfChannels /*!< Number of QMF channels. */ 840 ) { 841 /* Reset the patch.*/ 842 hTonCorr->guard = 0; 843 hTonCorr->shiftStartSb = 1; 844 845 if (resetPatch(hTonCorr, xposctrl, highBandStartSb, v_k_master, numMaster, fs, 846 noQmfChannels)) 847 return (1); 848 849 /* Reset the noise floor estimate.*/ 850 if (FDKsbrEnc_resetSbrNoiseFloorEstimate(&hTonCorr->sbrNoiseFloorEstimate, 851 freqBandTable[LO], nSfb[LO])) 852 return (1); 853 854 /* 855 Reset the inveerse filtereing detector. 856 */ 857 if (FDKsbrEnc_resetInvFiltDetector( 858 &hTonCorr->sbrInvFilt, 859 hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, 860 hTonCorr->sbrNoiseFloorEstimate.noNoiseBands)) 861 return (1); 862 /* Reset the missing harmonics detector. */ 863 if (FDKsbrEnc_ResetSbrMissingHarmonicsDetector( 864 &hTonCorr->sbrMissingHarmonicsDetector, nSfb[HI])) 865 return (1); 866 867 return (0); 868 } 869 870 /**************************************************************************/ 871 /*! 872 \brief Deletes the tonality correction paramtere module. 873 874 875 876 \return none 877 878 */ 879 /**************************************************************************/ 880 void FDKsbrEnc_DeleteTonCorrParamExtr( 881 HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */ 882 { 883 if (hTonCorr) { 884 FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix); 885 886 FreeRam_Sbr_signMatrix(hTonCorr->signMatrix); 887 888 FDKsbrEnc_DeleteSbrMissingHarmonicsDetector( 889 &hTonCorr->sbrMissingHarmonicsDetector); 890 } 891 } 892