1 2/* ----------------------------------------------------------------------------------------------------------- 3Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5� Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16of the MPEG specifications. 17 18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20individually for the purpose of encoding or decoding bit streams in products that are compliant with 21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27applications information and documentation. 28 292. COPYRIGHT LICENSE 30 31Redistribution and use in source and binary forms, with or without modification, are permitted without 32payment of copyright license fees provided that you satisfy the following conditions: 33 34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35your modifications thereto in source code form. 36 37You must retain the complete text of this software license in the documentation and/or other materials 38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40modifications thereto to recipients of copies in binary form. 41 42The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43prior written permission. 44 45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46software or your modifications thereto. 47 48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49and 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 533. NO PATENT LICENSE 54 55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57respect to this software. 58 59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60by appropriate patent licenses. 61 624. DISCLAIMER 63 64This 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 66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69or business interruption, however caused and on any theory of liability, whether in contract, strict 70liability, or tort (including negligence), arising in any way out of the use of this software, even if 71advised of the possibility of such damage. 72 735. CONTACT INFORMATION 74 75Fraunhofer Institute for Integrated Circuits IIS 76Attention: Audio and Multimedia Departments - FDK AAC LL 77Am Wolfsmantel 33 7891058 Erlangen, Germany 79 80www.iis.fraunhofer.de/amm 81amm-info@iis.fraunhofer.de 82----------------------------------------------------------------------------------------------------------- */ 83 84/*! 85 \file 86 \brief Low Power Profile Transposer, 87 This module provides the transposer. The main entry point is lppTransposer(). The function generates 88 high frequency content by copying data from the low band (provided by core codec) into the high band. 89 This process is also referred to as "patching". The function also implements spectral whitening by means of 90 inverse filtering based on LPC coefficients. 91 92 Together with the QMF filterbank the transposer can be tested using a supplied test program. See main_audio.cpp for details. 93 This module does use fractional arithmetic and the accuracy of the computations has an impact on the overall sound quality. 94 The module also needs to take into account the different scaling of spectral data. 95 96 \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview 97*/ 98 99#include "lpp_tran.h" 100 101#include "sbr_ram.h" 102#include "sbr_rom.h" 103 104#include "genericStds.h" 105#include "autocorr2nd.h" 106 107 108 109#if defined(__arm__) 110#include "arm/lpp_tran_arm.cpp" 111#endif 112 113 114 115#define LPC_SCALE_FACTOR 2 116 117 118/*! 119 * 120 * \brief Get bandwidth expansion factor from filtering level 121 * 122 * Returns a filter parameter (bandwidth expansion factor) depending on 123 * the desired filtering level signalled in the bitstream. 124 * When switching the filtering level from LOW to OFF, an additional 125 * level is being inserted to achieve a smooth transition. 126 */ 127 128#ifndef FUNCTION_mapInvfMode 129static FIXP_DBL 130mapInvfMode (INVF_MODE mode, 131 INVF_MODE prevMode, 132 WHITENING_FACTORS whFactors) 133{ 134 switch (mode) { 135 case INVF_LOW_LEVEL: 136 if(prevMode == INVF_OFF) 137 return whFactors.transitionLevel; 138 else 139 return whFactors.lowLevel; 140 141 case INVF_MID_LEVEL: 142 return whFactors.midLevel; 143 144 case INVF_HIGH_LEVEL: 145 return whFactors.highLevel; 146 147 default: 148 if(prevMode == INVF_LOW_LEVEL) 149 return whFactors.transitionLevel; 150 else 151 return whFactors.off; 152 } 153} 154#endif /* #ifndef FUNCTION_mapInvfMode */ 155 156/*! 157 * 158 * \brief Perform inverse filtering level emphasis 159 * 160 * Retrieve bandwidth expansion factor and apply smoothing for each filter band 161 * 162 */ 163 164#ifndef FUNCTION_inverseFilteringLevelEmphasis 165static void 166inverseFilteringLevelEmphasis(HANDLE_SBR_LPP_TRANS hLppTrans,/*!< Handle of lpp transposer */ 167 UCHAR nInvfBands, /*!< Number of bands for inverse filtering */ 168 INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ 169 INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */ 170 FIXP_DBL * bwVector /*!< Resulting filtering levels */ 171 ) 172{ 173 for(int i = 0; i < nInvfBands; i++) { 174 FIXP_DBL accu; 175 FIXP_DBL bwTmp = mapInvfMode (sbr_invf_mode[i], 176 sbr_invf_mode_prev[i], 177 hLppTrans->pSettings->whFactors); 178 179 if(bwTmp < hLppTrans->bwVectorOld[i]) { 180 accu = fMultDiv2(FL2FXCONST_DBL(0.75f),bwTmp) + 181 fMultDiv2(FL2FXCONST_DBL(0.25f),hLppTrans->bwVectorOld[i]); 182 } 183 else { 184 accu = fMultDiv2(FL2FXCONST_DBL(0.90625f),bwTmp) + 185 fMultDiv2(FL2FXCONST_DBL(0.09375f),hLppTrans->bwVectorOld[i]); 186 } 187 188 if (accu < FL2FXCONST_DBL(0.015625f)>>1) 189 bwVector[i] = FL2FXCONST_DBL(0.0f); 190 else 191 bwVector[i] = fixMin(accu<<1,FL2FXCONST_DBL(0.99609375f)); 192 } 193} 194#endif /* #ifndef FUNCTION_inverseFilteringLevelEmphasis */ 195 196/* Resulting autocorrelation determinant exponent */ 197#define ACDET_EXP (2*(DFRACT_BITS+sbrScaleFactor->lb_scale+10-ac.det_scale)) 198#define AC_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR) 199#define ALPHA_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR+1) 200/* Resulting transposed QMF values exponent 16 bit normalized samplebits assumed. */ 201#define QMFOUT_EXP ((SAMPLE_BITS-15)-sbrScaleFactor->lb_scale) 202 203/*! 204 * 205 * \brief Perform transposition by patching of subband samples. 206 * This function serves as the main entry point into the module. The function determines the areas for the 207 * patching process (these are the source range as well as the target range) and implements spectral whitening 208 * by means of inverse filtering. The function autoCorrelation2nd() is an auxiliary function for calculating the 209 * LPC coefficients for the filtering. The actual calculation of the LPC coefficients and the implementation 210 * of the filtering are done as part of lppTransposer(). 211 * 212 * Note that the filtering is done on all available QMF subsamples, whereas the patching is only done on those QMF 213 * subsamples that will be used in the next QMF synthesis. The filtering is also implemented before the patching 214 * includes further dependencies on parameters from the SBR data. 215 * 216 */ 217 218void lppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ 219 QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ 220 FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband samples (source) */ 221 222 FIXP_DBL *degreeAlias, /*!< Vector for results of aliasing estimation */ 223 FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of subband samples (source) */ 224 const int useLP, 225 const int timeStep, /*!< Time step of envelope */ 226 const int firstSlotOffs, /*!< Start position in time */ 227 const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ 228 const int nInvfBands, /*!< Number of bands for inverse filtering */ 229 INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ 230 INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ 231 ) 232{ 233 INT bwIndex[MAX_NUM_PATCHES]; 234 FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */ 235 236 int i; 237 int loBand, start, stop; 238 TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; 239 PATCH_PARAM *patchParam = pSettings->patchParam; 240 int patch; 241 242 FIXP_SGL alphar[LPC_ORDER], a0r, a1r; 243 FIXP_SGL alphai[LPC_ORDER], a0i=0, a1i=0; 244 FIXP_SGL bw = FL2FXCONST_SGL(0.0f); 245 246 int autoCorrLength; 247 248 FIXP_DBL k1, k1_below=0, k1_below2=0; 249 250 ACORR_COEFS ac; 251 int startSample; 252 int stopSample; 253 int stopSampleClear; 254 255 int comLowBandScale; 256 int ovLowBandShift; 257 int lowBandShift; 258/* int ovHighBandShift;*/ 259 int targetStopBand; 260 261 262 alphai[0] = FL2FXCONST_SGL(0.0f); 263 alphai[1] = FL2FXCONST_SGL(0.0f); 264 265 266 startSample = firstSlotOffs * timeStep; 267 stopSample = pSettings->nCols + lastSlotOffs * timeStep; 268 269 270 inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, sbr_invf_mode_prev, bwVector); 271 272 stopSampleClear = stopSample; 273 274 autoCorrLength = pSettings->nCols + pSettings->overlap; 275 276 /* Set upper subbands to zero: 277 This is required in case that the patches do not cover the complete highband 278 (because the last patch would be too short). 279 Possible optimization: Clearing bands up to usb would be sufficient here. */ 280 targetStopBand = patchParam[pSettings->noOfPatches-1].targetStartBand 281 + patchParam[pSettings->noOfPatches-1].numBandsInPatch; 282 283 int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL); 284 285 if (!useLP) { 286 for (i = startSample; i < stopSampleClear; i++) { 287 FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); 288 FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize); 289 } 290 } else 291 for (i = startSample; i < stopSampleClear; i++) { 292 FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); 293 } 294 295 /* init bwIndex for each patch */ 296 FDKmemclear(bwIndex, pSettings->noOfPatches*sizeof(INT)); 297 298 /* 299 Calc common low band scale factor 300 */ 301 comLowBandScale = fixMin(sbrScaleFactor->ov_lb_scale,sbrScaleFactor->lb_scale); 302 303 ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale; 304 lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale; 305 /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/ 306 307 /* outer loop over bands to do analysis only once for each band */ 308 309 if (!useLP) { 310 start = pSettings->lbStartPatching; 311 stop = pSettings->lbStopPatching; 312 } else 313 { 314 start = fixMax(1, pSettings->lbStartPatching - 2); 315 stop = patchParam[0].targetStartBand; 316 } 317 318 319 for ( loBand = start; loBand < stop; loBand++ ) { 320 321 FIXP_DBL lowBandReal[(((1024)/(32))+(6))+LPC_ORDER]; 322 FIXP_DBL *plowBandReal = lowBandReal; 323 FIXP_DBL **pqmfBufferReal = qmfBufferReal; 324 FIXP_DBL lowBandImag[(((1024)/(32))+(6))+LPC_ORDER]; 325 FIXP_DBL *plowBandImag = lowBandImag; 326 FIXP_DBL **pqmfBufferImag = qmfBufferImag; 327 int resetLPCCoeffs=0; 328 int dynamicScale = DFRACT_BITS-1-LPC_SCALE_FACTOR; 329 int acDetScale = 0; /* scaling of autocorrelation determinant */ 330 331 for(i=0;i<LPC_ORDER;i++){ 332 *plowBandReal++ = hLppTrans->lpcFilterStatesReal[i][loBand]; 333 if (!useLP) 334 *plowBandImag++ = hLppTrans->lpcFilterStatesImag[i][loBand]; 335 } 336 337 /* 338 Take old slope length qmf slot source values out of (overlap)qmf buffer 339 */ 340 if (!useLP) { 341 for(i=0;i<pSettings->nCols+pSettings->overlap;i++){ 342 *plowBandReal++ = (*pqmfBufferReal++)[loBand]; 343 *plowBandImag++ = (*pqmfBufferImag++)[loBand]; 344 } 345 } else 346 { 347 /* pSettings->overlap is always even */ 348 FDK_ASSERT((pSettings->overlap & 1) == 0); 349 350 for(i=0;i<((pSettings->overlap+pSettings->nCols)>>1);i++) { 351 *plowBandReal++ = (*pqmfBufferReal++)[loBand]; 352 *plowBandReal++ = (*pqmfBufferReal++)[loBand]; 353 } 354 if (pSettings->nCols & 1) { 355 *plowBandReal++ = (*pqmfBufferReal++)[loBand]; 356 } 357 } 358 359 /* 360 Determine dynamic scaling value. 361 */ 362 dynamicScale = fixMin(dynamicScale, getScalefactor(lowBandReal, LPC_ORDER+pSettings->overlap) + ovLowBandShift); 363 dynamicScale = fixMin(dynamicScale, getScalefactor(&lowBandReal[LPC_ORDER+pSettings->overlap], pSettings->nCols) + lowBandShift); 364 if (!useLP) { 365 dynamicScale = fixMin(dynamicScale, getScalefactor(lowBandImag, LPC_ORDER+pSettings->overlap) + ovLowBandShift); 366 dynamicScale = fixMin(dynamicScale, getScalefactor(&lowBandImag[LPC_ORDER+pSettings->overlap], pSettings->nCols) + lowBandShift); 367 } 368 dynamicScale = fixMax(0, dynamicScale-1); /* one additional bit headroom to prevent -1.0 */ 369 370 /* 371 Scale temporal QMF buffer. 372 */ 373 scaleValues(&lowBandReal[0], LPC_ORDER+pSettings->overlap, dynamicScale-ovLowBandShift); 374 scaleValues(&lowBandReal[LPC_ORDER+pSettings->overlap], pSettings->nCols, dynamicScale-lowBandShift); 375 376 if (!useLP) { 377 scaleValues(&lowBandImag[0], LPC_ORDER+pSettings->overlap, dynamicScale-ovLowBandShift); 378 scaleValues(&lowBandImag[LPC_ORDER+pSettings->overlap], pSettings->nCols, dynamicScale-lowBandShift); 379 } 380 381 382 if (!useLP) { 383 acDetScale += autoCorr2nd_cplx(&ac, lowBandReal+LPC_ORDER, lowBandImag+LPC_ORDER, autoCorrLength); 384 } 385 else 386 { 387 acDetScale += autoCorr2nd_real(&ac, lowBandReal+LPC_ORDER, autoCorrLength); 388 } 389 390 /* Examine dynamic of determinant in autocorrelation. */ 391 acDetScale += 2*(comLowBandScale + dynamicScale); 392 acDetScale *= 2; /* two times reflection coefficent scaling */ 393 acDetScale += ac.det_scale; /* ac scaling of determinant */ 394 395 /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */ 396 if (acDetScale>126 ) { 397 resetLPCCoeffs = 1; 398 } 399 400 401 alphar[1] = FL2FXCONST_SGL(0.0f); 402 if (!useLP) 403 alphai[1] = FL2FXCONST_SGL(0.0f); 404 405 if (ac.det != FL2FXCONST_DBL(0.0f)) { 406 FIXP_DBL tmp,absTmp,absDet; 407 408 absDet = fixp_abs(ac.det); 409 410 if (!useLP) { 411 tmp = ( fMultDiv2(ac.r01r,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) - 412 ( (fMultDiv2(ac.r01i,ac.r12i) + fMultDiv2(ac.r02r,ac.r11r)) >> (LPC_SCALE_FACTOR-1) ); 413 } else 414 { 415 tmp = ( fMultDiv2(ac.r01r,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) - 416 ( fMultDiv2(ac.r02r,ac.r11r) >> (LPC_SCALE_FACTOR-1) ); 417 } 418 absTmp = fixp_abs(tmp); 419 420 /* 421 Quick check: is first filter coeff >= 1(4) 422 */ 423 { 424 INT scale; 425 FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); 426 scale = scale+ac.det_scale; 427 428 if ( (scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL>>scale) ) { 429 resetLPCCoeffs = 1; 430 } 431 else { 432 alphar[1] = FX_DBL2FX_SGL(scaleValue(result,scale)); 433 if((tmp<FL2FX_DBL(0.0f)) ^ (ac.det<FL2FX_DBL(0.0f))) { 434 alphar[1] = -alphar[1]; 435 } 436 } 437 } 438 439 if (!useLP) 440 { 441 tmp = ( fMultDiv2(ac.r01i,ac.r12r) >> (LPC_SCALE_FACTOR-1) ) + 442 ( (fMultDiv2(ac.r01r,ac.r12i) - (FIXP_DBL)fMultDiv2(ac.r02i,ac.r11r)) >> (LPC_SCALE_FACTOR-1) ) ; 443 444 absTmp = fixp_abs(tmp); 445 446 /* 447 Quick check: is second filter coeff >= 1(4) 448 */ 449 { 450 INT scale; 451 FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); 452 scale = scale+ac.det_scale; 453 454 if ( (scale > 0) && (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL>>scale) ) { 455 resetLPCCoeffs = 1; 456 } 457 else { 458 alphai[1] = FX_DBL2FX_SGL(scaleValue(result,scale)); 459 if((tmp<FL2FX_DBL(0.0f)) ^ (ac.det<FL2FX_DBL(0.0f))) { 460 alphai[1] = -alphai[1]; 461 } 462 } 463 } 464 } 465 } 466 467 alphar[0] = FL2FXCONST_SGL(0.0f); 468 if (!useLP) 469 alphai[0] = FL2FXCONST_SGL(0.0f); 470 471 if ( ac.r11r != FL2FXCONST_DBL(0.0f) ) { 472 473 /* ac.r11r is always >=0 */ 474 FIXP_DBL tmp,absTmp; 475 476 if (!useLP) { 477 tmp = (ac.r01r>>(LPC_SCALE_FACTOR+1)) + 478 (fMultDiv2(alphar[1],ac.r12r) + fMultDiv2(alphai[1],ac.r12i)); 479 } else 480 { 481 if(ac.r01r>=FL2FXCONST_DBL(0.0f)) 482 tmp = (ac.r01r>>(LPC_SCALE_FACTOR+1)) + fMultDiv2(alphar[1],ac.r12r); 483 else 484 tmp = -((-ac.r01r)>>(LPC_SCALE_FACTOR+1)) + fMultDiv2(alphar[1],ac.r12r); 485 } 486 487 absTmp = fixp_abs(tmp); 488 489 /* 490 Quick check: is first filter coeff >= 1(4) 491 */ 492 493 if (absTmp >= (ac.r11r>>1)) { 494 resetLPCCoeffs=1; 495 } 496 else { 497 INT scale; 498 FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); 499 alphar[0] = FX_DBL2FX_SGL(scaleValue(result,scale+1)); 500 501 if((tmp>FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f))) 502 alphar[0] = -alphar[0]; 503 } 504 505 if (!useLP) 506 { 507 tmp = (ac.r01i>>(LPC_SCALE_FACTOR+1)) + 508 (fMultDiv2(alphai[1],ac.r12r) - fMultDiv2(alphar[1],ac.r12i)); 509 510 absTmp = fixp_abs(tmp); 511 512 /* 513 Quick check: is second filter coeff >= 1(4) 514 */ 515 if (absTmp >= (ac.r11r>>1)) { 516 resetLPCCoeffs=1; 517 } 518 else { 519 INT scale; 520 FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); 521 alphai[0] = FX_DBL2FX_SGL(scaleValue(result,scale+1)); 522 if((tmp>FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f))) 523 alphai[0] = -alphai[0]; 524 } 525 } 526 } 527 528 529 if (!useLP) 530 { 531 /* Now check the quadratic criteria */ 532 if( (fMultDiv2(alphar[0],alphar[0]) + fMultDiv2(alphai[0],alphai[0])) >= FL2FXCONST_DBL(0.5f) ) 533 resetLPCCoeffs=1; 534 if( (fMultDiv2(alphar[1],alphar[1]) + fMultDiv2(alphai[1],alphai[1])) >= FL2FXCONST_DBL(0.5f) ) 535 resetLPCCoeffs=1; 536 } 537 538 if(resetLPCCoeffs){ 539 alphar[0] = FL2FXCONST_SGL(0.0f); 540 alphar[1] = FL2FXCONST_SGL(0.0f); 541 if (!useLP) 542 { 543 alphai[0] = FL2FXCONST_SGL(0.0f); 544 alphai[1] = FL2FXCONST_SGL(0.0f); 545 } 546 } 547 548 if (useLP) 549 { 550 551 /* Aliasing detection */ 552 if(ac.r11r==FL2FXCONST_DBL(0.0f)) { 553 k1 = FL2FXCONST_DBL(0.0f); 554 } 555 else { 556 if ( fixp_abs(ac.r01r) >= fixp_abs(ac.r11r) ) { 557 if ( fMultDiv2(ac.r01r,ac.r11r) < FL2FX_DBL(0.0f)) { 558 k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/; 559 }else { 560 /* Since this value is squared later, it must not ever become -1.0f. */ 561 k1 = (FIXP_DBL)(MINVAL_DBL+1) /*FL2FXCONST_SGL(-1.0f)*/; 562 } 563 } 564 else { 565 INT scale; 566 FIXP_DBL result = fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale); 567 k1 = scaleValue(result,scale); 568 569 if(!((ac.r01r<FL2FX_DBL(0.0f)) ^ (ac.r11r<FL2FX_DBL(0.0f)))) { 570 k1 = -k1; 571 } 572 } 573 } 574 if(loBand > 1){ 575 /* Check if the gain should be locked */ 576 FIXP_DBL deg = /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below); 577 degreeAlias[loBand] = FL2FXCONST_DBL(0.0f); 578 if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))){ 579 if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */ 580 degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; 581 if ( k1_below2 > FL2FXCONST_DBL(0.0f) ) { /* 3-Ch Aliasing Detection */ 582 degreeAlias[loBand-1] = deg; 583 } 584 } 585 else if ( k1_below2 > FL2FXCONST_DBL(0.0f) ) { /* 3-Ch Aliasing Detection */ 586 degreeAlias[loBand] = deg; 587 } 588 } 589 if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))){ 590 if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */ 591 degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; 592 if ( k1_below2 < FL2FXCONST_DBL(0.0f) ) { /* 3-CH Aliasing Detection */ 593 degreeAlias[loBand-1] = deg; 594 } 595 } 596 else if ( k1_below2 < FL2FXCONST_DBL(0.0f) ) { /* 3-CH Aliasing Detection */ 597 degreeAlias[loBand] = deg; 598 } 599 } 600 } 601 /* remember k1 values of the 2 QMF channels below the current channel */ 602 k1_below2 = k1_below; 603 k1_below = k1; 604 } 605 606 patch = 0; 607 608 while ( patch < pSettings->noOfPatches ) { /* inner loop over every patch */ 609 610 int hiBand = loBand + patchParam[patch].targetBandOffs; 611 612 if ( loBand < patchParam[patch].sourceStartBand 613 || loBand >= patchParam[patch].sourceStopBand 614 //|| hiBand >= hLppTrans->pSettings->noChannels 615 ) { 616 /* Lowband not in current patch - proceed */ 617 patch++; 618 continue; 619 } 620 621 FDK_ASSERT( hiBand < (64) ); 622 623 /* bwIndex[patch] is already initialized with value from previous band inside this patch */ 624 while (hiBand >= pSettings->bwBorders[bwIndex[patch]]) 625 bwIndex[patch]++; 626 627 628 /* 629 Filter Step 2: add the left slope with the current filter to the buffer 630 pure source values are already in there 631 */ 632 bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]); 633 634 a0r = FX_DBL2FX_SGL(fMult(bw,alphar[0])); /* Apply current bandwidth expansion factor */ 635 636 637 if (!useLP) 638 a0i = FX_DBL2FX_SGL(fMult(bw,alphai[0])); 639 bw = FX_DBL2FX_SGL(fPow2(bw)); 640 a1r = FX_DBL2FX_SGL(fMult(bw,alphar[1])); 641 if (!useLP) 642 a1i = FX_DBL2FX_SGL(fMult(bw,alphai[1])); 643 644 645 646 /* 647 Filter Step 3: insert the middle part which won't be windowed 648 */ 649 650 if ( bw <= FL2FXCONST_SGL(0.0f) ) { 651 if (!useLP) { 652 int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale)); 653 for(i = startSample; i < stopSample; i++ ) { 654 qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER+i]>>descale; 655 qmfBufferImag[i][hiBand] = lowBandImag[LPC_ORDER+i]>>descale; 656 } 657 } else 658 { 659 int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale)); 660 for(i = startSample; i < stopSample; i++ ) { 661 qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER+i]>>descale; 662 } 663 } 664 } 665 else { /* bw <= 0 */ 666 667 if (!useLP) { 668 int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale)); 669#ifdef FUNCTION_LPPTRANSPOSER_func1 670 lppTransposer_func1(lowBandReal+LPC_ORDER+startSample,lowBandImag+LPC_ORDER+startSample, 671 qmfBufferReal+startSample,qmfBufferImag+startSample, 672 stopSample-startSample, (int) hiBand, 673 dynamicScale,descale, 674 a0r, a0i, a1r, a1i); 675#else 676 for(i = startSample; i < stopSample; i++ ) { 677 FIXP_DBL accu1, accu2; 678 679 accu1 = (fMultDiv2(a0r,lowBandReal[LPC_ORDER+i-1]) - fMultDiv2(a0i,lowBandImag[LPC_ORDER+i-1]) + 680 fMultDiv2(a1r,lowBandReal[LPC_ORDER+i-2]) - fMultDiv2(a1i,lowBandImag[LPC_ORDER+i-2]))>>dynamicScale; 681 accu2 = (fMultDiv2(a0i,lowBandReal[LPC_ORDER+i-1]) + fMultDiv2(a0r,lowBandImag[LPC_ORDER+i-1]) + 682 fMultDiv2(a1i,lowBandReal[LPC_ORDER+i-2]) + fMultDiv2(a1r,lowBandImag[LPC_ORDER+i-2]))>>dynamicScale; 683 684 qmfBufferReal[i][hiBand] = (lowBandReal[LPC_ORDER+i]>>descale) + (accu1<<1); 685 qmfBufferImag[i][hiBand] = (lowBandImag[LPC_ORDER+i]>>descale) + (accu2<<1); 686 } 687#endif 688 } else 689 { 690 int descale = fixMin(DFRACT_BITS-1, (LPC_SCALE_FACTOR+dynamicScale)); 691 692 FDK_ASSERT(dynamicScale >= 0); 693 for(i = startSample; i < stopSample; i++ ) { 694 FIXP_DBL accu1; 695 696 accu1 = (fMultDiv2(a0r,lowBandReal[LPC_ORDER+i-1]) + fMultDiv2(a1r,lowBandReal[LPC_ORDER+i-2]))>>dynamicScale; 697 698 qmfBufferReal[i][hiBand] = (lowBandReal[LPC_ORDER+i]>>descale) + (accu1<<1); 699 } 700 } 701 } /* bw <= 0 */ 702 703 patch++; 704 705 } /* inner loop over patches */ 706 707 /* 708 * store the unmodified filter coefficients if there is 709 * an overlapping envelope 710 *****************************************************************/ 711 712 713 } /* outer loop over bands (loBand) */ 714 715 if (useLP) 716 { 717 for ( loBand = pSettings->lbStartPatching; loBand < pSettings->lbStopPatching; loBand++ ) { 718 patch = 0; 719 while ( patch < pSettings->noOfPatches ) { 720 721 UCHAR hiBand = loBand + patchParam[patch].targetBandOffs; 722 723 if ( loBand < patchParam[patch].sourceStartBand 724 || loBand >= patchParam[patch].sourceStopBand 725 || hiBand >= (64) /* Highband out of range (biterror) */ 726 ) { 727 /* Lowband not in current patch or highband out of range (might be caused by biterrors)- proceed */ 728 patch++; 729 continue; 730 } 731 732 if(hiBand != patchParam[patch].targetStartBand) 733 degreeAlias[hiBand] = degreeAlias[loBand]; 734 735 patch++; 736 } 737 }/* end for loop */ 738 } 739 740 for (i = 0; i < nInvfBands; i++ ) { 741 hLppTrans->bwVectorOld[i] = bwVector[i]; 742 } 743 744 /* 745 set high band scale factor 746 */ 747 sbrScaleFactor->hb_scale = comLowBandScale-(LPC_SCALE_FACTOR); 748 749} 750 751/*! 752 * 753 * \brief Initialize one low power transposer instance 754 * 755 * 756 */ 757SBR_ERROR 758createLppTransposer (HANDLE_SBR_LPP_TRANS hs, /*!< Handle of low power transposer */ 759 TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */ 760 const int highBandStartSb, /*!< ? */ 761 UCHAR *v_k_master, /*!< Master table */ 762 const int numMaster, /*!< Valid entries in master table */ 763 const int usb, /*!< Highband area stop subband */ 764 const int timeSlots, /*!< Number of time slots */ 765 const int nCols, /*!< Number of colums (codec qmf bank) */ 766 UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ 767 const int noNoiseBands, /*!< Number of noise bands */ 768 UINT fs, /*!< Sample Frequency */ 769 const int chan, /*!< Channel number */ 770 const int overlap 771 ) 772{ 773 /* FB inverse filtering settings */ 774 hs->pSettings = pSettings; 775 776 pSettings->nCols = nCols; 777 pSettings->overlap = overlap; 778 779 switch (timeSlots) { 780 781 case 15: 782 case 16: 783 break; 784 785 default: 786 return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */ 787 } 788 789 if (chan==0) { 790 /* Init common data only once */ 791 hs->pSettings->nCols = nCols; 792 793 return resetLppTransposer (hs, 794 highBandStartSb, 795 v_k_master, 796 numMaster, 797 noiseBandTable, 798 noNoiseBands, 799 usb, 800 fs); 801 } 802 return SBRDEC_OK; 803} 804 805 806static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster, UCHAR direction) 807{ 808 int index; 809 810 if( goalSb <= v_k_master[0] ) 811 return v_k_master[0]; 812 813 if( goalSb >= v_k_master[numMaster] ) 814 return v_k_master[numMaster]; 815 816 if(direction) { 817 index = 0; 818 while( v_k_master[index] < goalSb ) { 819 index++; 820 } 821 } else { 822 index = numMaster; 823 while( v_k_master[index] > goalSb ) { 824 index--; 825 } 826 } 827 828 return v_k_master[index]; 829} 830 831 832/*! 833 * 834 * \brief Reset memory for one lpp transposer instance 835 * 836 * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error 837 */ 838SBR_ERROR 839resetLppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ 840 UCHAR highBandStartSb, /*!< High band area: start subband */ 841 UCHAR *v_k_master, /*!< Master table */ 842 UCHAR numMaster, /*!< Valid entries in master table */ 843 UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ 844 UCHAR noNoiseBands, /*!< Number of noise bands */ 845 UCHAR usb, /*!< High band area: stop subband */ 846 UINT fs /*!< SBR output sampling frequency */ 847 ) 848{ 849 TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; 850 PATCH_PARAM *patchParam = pSettings->patchParam; 851 852 int i, patch; 853 int targetStopBand; 854 int sourceStartBand; 855 int patchDistance; 856 int numBandsInPatch; 857 858 int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling terms*/ 859 int xoverOffset = highBandStartSb - lsb; /* Calculate distance in QMF bands between k0 and kx */ 860 int startFreqHz; 861 862 int desiredBorder; 863 864 usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with float code). */ 865 866 /* 867 * Plausibility check 868 */ 869 870 if ( lsb - SHIFT_START_SB < 4 ) { 871 return SBRDEC_UNSUPPORTED_CONFIG; 872 } 873 874 875 /* 876 * Initialize the patching parameter 877 */ 878 /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */ 879 desiredBorder = (((2048000*2) / fs) + 1) >> 1; 880 881 desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster, 1); /* Adapt region to master-table */ 882 883 /* First patch */ 884 sourceStartBand = SHIFT_START_SB + xoverOffset; 885 targetStopBand = lsb + xoverOffset; /* upperBand */ 886 887 /* Even (odd) numbered channel must be patched to even (odd) numbered channel */ 888 patch = 0; 889 while(targetStopBand < usb) { 890 891 /* Too many patches? 892 Allow MAX_NUM_PATCHES+1 patches here. 893 we need to check later again, since patch might be the highest patch 894 AND contain less than 3 bands => actual number of patches will be reduced by 1. 895 */ 896 if (patch > MAX_NUM_PATCHES) { 897 return SBRDEC_UNSUPPORTED_CONFIG; 898 } 899 900 patchParam[patch].guardStartBand = targetStopBand; 901 patchParam[patch].targetStartBand = targetStopBand; 902 903 numBandsInPatch = desiredBorder - targetStopBand; /* Get the desired range of the patch */ 904 905 if ( numBandsInPatch >= lsb - sourceStartBand ) { 906 /* Desired number bands are not available -> patch whole source range */ 907 patchDistance = targetStopBand - sourceStartBand; /* Get the targetOffset */ 908 patchDistance = patchDistance & ~1; /* Rounding off odd numbers and make all even */ 909 numBandsInPatch = lsb - (targetStopBand - patchDistance); /* Update number of bands to be patched */ 910 numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, v_k_master, numMaster, 0) - 911 targetStopBand; /* Adapt region to master-table */ 912 } 913 914 /* Desired number bands are available -> get the minimal even patching distance */ 915 patchDistance = numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */ 916 patchDistance = (patchDistance + 1) & ~1; /* Rounding up odd numbers and make all even */ 917 918 if (numBandsInPatch > 0) { 919 patchParam[patch].sourceStartBand = targetStopBand - patchDistance; 920 patchParam[patch].targetBandOffs = patchDistance; 921 patchParam[patch].numBandsInPatch = numBandsInPatch; 922 patchParam[patch].sourceStopBand = patchParam[patch].sourceStartBand + numBandsInPatch; 923 924 targetStopBand += patchParam[patch].numBandsInPatch; 925 patch++; 926 } 927 928 /* All patches but first */ 929 sourceStartBand = SHIFT_START_SB; 930 931 /* Check if we are close to desiredBorder */ 932 if( desiredBorder - targetStopBand < 3) /* MPEG doc */ 933 { 934 desiredBorder = usb; 935 } 936 937 } 938 939 patch--; 940 941 /* If highest patch contains less than three subband: skip it */ 942 if ( (patch>0) && (patchParam[patch].numBandsInPatch < 3) ) { 943 patch--; 944 targetStopBand = patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch; 945 } 946 947 /* now check if we don't have one too many */ 948 if (patch >= MAX_NUM_PATCHES) { 949 return SBRDEC_UNSUPPORTED_CONFIG; 950 } 951 952 pSettings->noOfPatches = patch + 1; 953 954 /* Check lowest and highest source subband */ 955 pSettings->lbStartPatching = targetStopBand; 956 pSettings->lbStopPatching = 0; 957 for ( patch = 0; patch < pSettings->noOfPatches; patch++ ) { 958 pSettings->lbStartPatching = fixMin( pSettings->lbStartPatching, patchParam[patch].sourceStartBand ); 959 pSettings->lbStopPatching = fixMax( pSettings->lbStopPatching, patchParam[patch].sourceStopBand ); 960 } 961 962 for(i = 0 ; i < noNoiseBands; i++){ 963 pSettings->bwBorders[i] = noiseBandTable[i+1]; 964 } 965 966 /* 967 * Choose whitening factors 968 */ 969 970 startFreqHz = ( (lsb + xoverOffset)*fs ) >> 7; /* Shift does a division by 2*(64) */ 971 972 for( i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++ ) 973 { 974 if( startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) 975 break; 976 } 977 i--; 978 979 pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0]; 980 pSettings->whFactors.transitionLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][1]; 981 pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2]; 982 pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3]; 983 pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4]; 984 985 return SBRDEC_OK; 986} 987