1 2/* ----------------------------------------------------------------------------------------------------------- 3Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5� Copyright 1995 - 2015 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/******************************** MPEG Audio Encoder ************************** 85 86 Initial author: Alex Groeschel, Tobias Chalupka 87 contents/description: Temporal noise shaping 88 89******************************************************************************/ 90 91#include "aacenc_tns.h" 92#include "psy_const.h" 93#include "psy_configuration.h" 94#include "tns_func.h" 95#include "aacEnc_rom.h" 96#include "aacenc_tns.h" 97 98#define FILTER_DIRECTION 0 /* 0 = up, 1 = down */ 99 100static const FIXP_DBL acfWindowLong[12+3+1] = { 101 0x7fffffff,0x7fb80000,0x7ee00000,0x7d780000,0x7b800000,0x78f80000,0x75e00000,0x72380000, 102 0x6e000000,0x69380000,0x63e00000,0x5df80000,0x57800000,0x50780000,0x48e00000,0x40b80000 103}; 104 105static const FIXP_DBL acfWindowShort[4+3+1] = { 106 0x7fffffff,0x7e000000,0x78000000,0x6e000000,0x60000000,0x4e000000,0x38000000,0x1e000000 107}; 108 109typedef struct{ 110 INT bitRateFrom[2]; /* noneSbr=0, useSbr=1 */ 111 INT bitRateTo[2]; /* noneSbr=0, useSbr=1 */ 112 TNS_PARAMETER_TABULATED paramTab[2]; /* mono=0, stereo=1 */ 113 114} TNS_INFO_TAB; 115 116#define TNS_TIMERES_SCALE (1) 117#define FL2_TIMERES_FIX(a) ( FL2FXCONST_DBL(a/(float)(1<<TNS_TIMERES_SCALE)) ) 118 119static const TNS_INFO_TAB tnsInfoTab[] = 120{ 121 { 122 { 16000, 13500}, 123 { 32000, 28000}, 124 { 125 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 12}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, 1 }, 126 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 12}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.2f)}, 1 } 127 } 128 }, 129 { 130 { 32001, 28001}, 131 { 60000, 52000}, 132 { 133 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 10}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 }, 134 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 10}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 } 135 } 136 }, 137 { 138 { 60001, 52001}, 139 { 384000, 384000}, 140 { 141 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 8}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 }, 142 { {1, 1}, {1437, 1500}, {1400, 600}, {12, 8}, {FILTER_DIRECTION, FILTER_DIRECTION}, {3, 1}, {FL2_TIMERES_FIX(0.4f), FL2_TIMERES_FIX(1.0f)}, 1 } 143 } 144 } 145}; 146 147typedef struct { 148 INT samplingRate; 149 SCHAR maxBands[2]; /* long=0; short=1 */ 150 151} TNS_MAX_TAB_ENTRY; 152 153static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab1024[] = 154{ 155 { 96000, { 31, 9}}, 156 { 88200, { 31, 9}}, 157 { 64000, { 34, 10}}, 158 { 48000, { 40, 14}}, 159 { 44100, { 42, 14}}, 160 { 32000, { 51, 14}}, 161 { 24000, { 46, 14}}, 162 { 22050, { 46, 14}}, 163 { 16000, { 42, 14}}, 164 { 12000, { 42, 14}}, 165 { 11025, { 42, 14}}, 166 { 8000, { 39, 14}} 167}; 168 169static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab480[] = 170{ 171 { 48000, { 31, -1}}, 172 { 44100, { 32, -1}}, 173 { 32000, { 37, -1}}, 174 { 24000, { 30, -1}}, 175 { 22050, { 30, -1}} 176}; 177 178static const TNS_MAX_TAB_ENTRY tnsMaxBandsTab512[] = 179{ 180 { 48000, { 31, -1}}, 181 { 44100, { 32, -1}}, 182 { 32000, { 37, -1}}, 183 { 24000, { 31, -1}}, 184 { 22050, { 31, -1}} 185}; 186 187static INT FDKaacEnc_AutoToParcor( 188 FIXP_DBL *RESTRICT input, 189 FIXP_DBL *RESTRICT reflCoeff, 190 const INT numOfCoeff 191 ); 192 193static void FDKaacEnc_Parcor2Index( 194 const FIXP_DBL *parcor, 195 INT *RESTRICT index, 196 const INT order, 197 const INT bitsPerCoeff 198 ); 199 200static void FDKaacEnc_Index2Parcor( 201 const INT *index, 202 FIXP_DBL *RESTRICT parcor, 203 const INT order, 204 const INT bitsPerCoeff 205 ); 206 207static INT FDKaacEnc_ParcorToLpc( 208 const FIXP_DBL *reflCoeff, 209 FIXP_DBL *RESTRICT LpcCoeff, 210 const INT numOfCoeff, 211 FIXP_DBL *RESTRICT workBuffer 212 ); 213 214static void FDKaacEnc_AnalysisFilter( 215 FIXP_DBL *RESTRICT signal, 216 const INT numOfLines, 217 const FIXP_DBL *predictorCoeff, 218 const INT order, 219 const INT lpcGainFactor 220 ); 221 222static void FDKaacEnc_CalcGaussWindow( 223 FIXP_DBL *win, 224 const int winSize, 225 const INT samplingRate, 226 const INT transformResolution, 227 const FIXP_DBL timeResolution, 228 const INT timeResolution_e 229 ); 230 231static const TNS_PARAMETER_TABULATED* FDKaacEnc_GetTnsParam( 232 const INT bitRate, 233 const INT channels, 234 const INT sbrLd 235 ) 236{ 237 int i; 238 const TNS_PARAMETER_TABULATED *tnsConfigTab = NULL; 239 240 for (i = 0; i < (int) (sizeof(tnsInfoTab)/sizeof(TNS_INFO_TAB)); i++) { 241 if ((bitRate >= tnsInfoTab[i].bitRateFrom[sbrLd?1:0]) && 242 bitRate <= tnsInfoTab[i].bitRateTo[sbrLd?1:0]) 243 { 244 tnsConfigTab = &tnsInfoTab[i].paramTab[(channels==1)?0:1]; 245 } 246 } 247 248 return tnsConfigTab; 249} 250 251 252static INT getTnsMaxBands( 253 const INT sampleRate, 254 const INT granuleLength, 255 const INT isShortBlock 256 ) 257{ 258 int i; 259 INT numBands = -1; 260 const TNS_MAX_TAB_ENTRY *pMaxBandsTab = NULL; 261 int maxBandsTabSize = 0; 262 263 switch (granuleLength) { 264 case 1024: 265 pMaxBandsTab = tnsMaxBandsTab1024; 266 maxBandsTabSize = sizeof(tnsMaxBandsTab1024)/sizeof(TNS_MAX_TAB_ENTRY); 267 break; 268 case 480: 269 pMaxBandsTab = tnsMaxBandsTab480; 270 maxBandsTabSize = sizeof(tnsMaxBandsTab480)/sizeof(TNS_MAX_TAB_ENTRY); 271 break; 272 case 512: 273 pMaxBandsTab = tnsMaxBandsTab512; 274 maxBandsTabSize = sizeof(tnsMaxBandsTab512)/sizeof(TNS_MAX_TAB_ENTRY); 275 break; 276 default: 277 numBands = -1; 278 } 279 280 if (pMaxBandsTab!=NULL) { 281 for (i=0; i<maxBandsTabSize; i++) { 282 numBands = pMaxBandsTab[i].maxBands[(!isShortBlock)?0:1]; 283 if (sampleRate >= pMaxBandsTab[i].samplingRate) { 284 break; 285 } 286 } 287 } 288 289 return numBands; 290} 291 292/***************************************************************************/ 293/*! 294 \brief FDKaacEnc_FreqToBandWithRounding 295 296 Returns index of nearest band border 297 298 \param frequency 299 \param sampling frequency 300 \param total number of bands 301 \param pointer to table of band borders 302 303 \return band border 304****************************************************************************/ 305 306INT FDKaacEnc_FreqToBandWithRounding( 307 const INT freq, 308 const INT fs, 309 const INT numOfBands, 310 const INT *bandStartOffset 311 ) 312{ 313 INT lineNumber, band; 314 315 /* assert(freq >= 0); */ 316 lineNumber = (freq*bandStartOffset[numOfBands]*4/fs+1)/2; 317 318 /* freq > fs/2 */ 319 if (lineNumber >= bandStartOffset[numOfBands]) 320 return numOfBands; 321 322 /* find band the line number lies in */ 323 for (band=0; band<numOfBands; band++) { 324 if (bandStartOffset[band+1]>lineNumber) break; 325 } 326 327 /* round to nearest band border */ 328 if (lineNumber - bandStartOffset[band] > 329 bandStartOffset[band+1] - lineNumber ) 330 { 331 band++; 332 } 333 334 return(band); 335} 336 337 338/***************************************************************************** 339 340 functionname: FDKaacEnc_InitTnsConfiguration 341 description: fill TNS_CONFIG structure with sensible content 342 returns: 343 input: bitrate, samplerate, number of channels, 344 blocktype (long or short), 345 TNS Config struct (modified), 346 psy config struct, 347 tns active flag 348 output: 349 350*****************************************************************************/ 351AAC_ENCODER_ERROR FDKaacEnc_InitTnsConfiguration(INT bitRate, 352 INT sampleRate, 353 INT channels, 354 INT blockType, 355 INT granuleLength, 356 INT isLowDelay, 357 INT ldSbrPresent, 358 TNS_CONFIG *tC, 359 PSY_CONFIGURATION *pC, 360 INT active, 361 INT useTnsPeak) 362{ 363 int i; 364 //float acfTimeRes = (blockType == SHORT_WINDOW) ? 0.125f : 0.046875f; 365 366 if (channels <= 0) 367 return (AAC_ENCODER_ERROR)1; 368 369 tC->isLowDelay = isLowDelay; 370 371 /* initialize TNS filter flag, order, and coefficient resolution (in bits per coeff) */ 372 tC->tnsActive = (active) ? TRUE : FALSE; 373 tC->maxOrder = (blockType == SHORT_WINDOW) ? 5 : 12; /* maximum: 7, 20 */ 374 if (bitRate < 16000) 375 tC->maxOrder -= 2; 376 tC->coefRes = (blockType == SHORT_WINDOW) ? 3 : 4; 377 378 /* LPC stop line: highest MDCT line to be coded, but do not go beyond TNS_MAX_BANDS! */ 379 tC->lpcStopBand = getTnsMaxBands(sampleRate, granuleLength, (blockType == SHORT_WINDOW) ? 1 : 0); 380 381 if (tC->lpcStopBand < 0) { 382 return (AAC_ENCODER_ERROR)1; 383 } 384 385 tC->lpcStopBand = FDKmin(tC->lpcStopBand, pC->sfbActive); 386 tC->lpcStopLine = pC->sfbOffset[tC->lpcStopBand]; 387 388 switch (granuleLength) { 389 case 1024: 390 /* TNS start line: skip lower MDCT lines to prevent artifacts due to filter mismatch */ 391 tC->lpcStartBand[LOFILT] = (blockType == SHORT_WINDOW) ? 0 : ((sampleRate < 18783) ? 4 : 8); 392 tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; 393 394 i = tC->lpcStopBand; 395 while (pC->sfbOffset[i] > (tC->lpcStartLine[LOFILT] + (tC->lpcStopLine - tC->lpcStartLine[LOFILT]) / 4)) i--; 396 tC->lpcStartBand[HIFILT] = i; 397 tC->lpcStartLine[HIFILT] = pC->sfbOffset[i]; 398 399 tC->confTab.threshOn[HIFILT] = 1437; 400 tC->confTab.threshOn[LOFILT] = 1500; 401 402 tC->confTab.tnsLimitOrder[HIFILT] = tC->maxOrder; 403 tC->confTab.tnsLimitOrder[LOFILT] = tC->maxOrder - 7; 404 405 tC->confTab.tnsFilterDirection[HIFILT] = FILTER_DIRECTION; 406 tC->confTab.tnsFilterDirection[LOFILT] = FILTER_DIRECTION; 407 408 tC->confTab.acfSplit[HIFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation*/ 409 tC->confTab.acfSplit[LOFILT] = -1; /* signal Merged4to2QuartersAutoCorrelation in FDKaacEnc_MergedAutoCorrelation */ 410 411 tC->confTab.filterEnabled[HIFILT] = 1; 412 tC->confTab.filterEnabled[LOFILT] = 1; 413 tC->confTab.seperateFiltersAllowed = 1; 414 415 /* compute autocorrelation window based on maximum filter order for given block type */ 416 /* for (i = 0; i <= tC->maxOrder + 3; i++) { 417 float acfWinTemp = acfTimeRes * i; 418 acfWindow[i] = FL2FXCONST_DBL(1.0f - acfWinTemp * acfWinTemp); 419 } 420 */ 421 if (blockType == SHORT_WINDOW) { 422 FDKmemcpy(tC->acfWindow[HIFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); 423 FDKmemcpy(tC->acfWindow[LOFILT], acfWindowShort, FDKmin(sizeof(acfWindowShort), sizeof(tC->acfWindow[HIFILT]))); 424 } 425 else { 426 FDKmemcpy(tC->acfWindow[HIFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); 427 FDKmemcpy(tC->acfWindow[LOFILT], acfWindowLong, FDKmin(sizeof(acfWindowLong), sizeof(tC->acfWindow[HIFILT]))); 428 } 429 break; 430 case 480: 431 case 512: 432 { 433 const TNS_PARAMETER_TABULATED* pCfg = FDKaacEnc_GetTnsParam(bitRate, channels, ldSbrPresent); 434 435 if ( pCfg != NULL ) { 436 437 FDKmemcpy(&(tC->confTab), pCfg, sizeof(tC->confTab)); 438 439 tC->lpcStartBand[HIFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[HIFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); 440 tC->lpcStartLine[HIFILT] = pC->sfbOffset[tC->lpcStartBand[HIFILT]]; 441 tC->lpcStartBand[LOFILT] = FDKaacEnc_FreqToBandWithRounding(pCfg->filterStartFreq[LOFILT], sampleRate, pC->sfbCnt, pC->sfbOffset); 442 tC->lpcStartLine[LOFILT] = pC->sfbOffset[tC->lpcStartBand[LOFILT]]; 443 444 FDKaacEnc_CalcGaussWindow(tC->acfWindow[HIFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[HIFILT], TNS_TIMERES_SCALE); 445 FDKaacEnc_CalcGaussWindow(tC->acfWindow[LOFILT], tC->maxOrder+1, sampleRate, granuleLength, pCfg->tnsTimeResolution[LOFILT], TNS_TIMERES_SCALE); 446 } 447 else { 448 tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ 449 } 450 } 451 break; 452 default: 453 tC->tnsActive = FALSE; /* no configuration available, disable tns tool */ 454 } 455 456 return AAC_ENC_OK; 457 458} 459 460/***************************************************************************/ 461/*! 462 \brief FDKaacEnc_ScaleUpSpectrum 463 464 Scales up spectrum lines in a given frequency section 465 466 \param scaled spectrum 467 \param original spectrum 468 \param frequency line to start scaling 469 \param frequency line to enc scaling 470 471 \return scale factor 472 473****************************************************************************/ 474static inline INT FDKaacEnc_ScaleUpSpectrum( 475 FIXP_DBL *dest, 476 const FIXP_DBL *src, 477 const INT startLine, 478 const INT stopLine 479 ) 480{ 481 INT i, scale; 482 483 FIXP_DBL maxVal = FL2FXCONST_DBL(0.f); 484 485 /* Get highest value in given spectrum */ 486 for (i=startLine; i<stopLine; i++) { 487 maxVal = fixMax(maxVal,fixp_abs(src[i])); 488 } 489 scale = CountLeadingBits(maxVal); 490 491 /* Scale spectrum according to highest value */ 492 for (i=startLine; i<stopLine; i++) { 493 dest[i] = src[i]<<scale; 494 } 495 496 return scale; 497} 498 499/***************************************************************************/ 500/*! 501 \brief FDKaacEnc_CalcAutoCorrValue 502 503 Calculate autocorellation value for one lag 504 505 \param pointer to spectrum 506 \param start line 507 \param stop line 508 \param lag to be calculated 509 \param scaling of the lag 510 511****************************************************************************/ 512static inline FIXP_DBL FDKaacEnc_CalcAutoCorrValue( 513 const FIXP_DBL *spectrum, 514 const INT startLine, 515 const INT stopLine, 516 const INT lag, 517 const INT scale 518 ) 519{ 520 int i; 521 FIXP_DBL result = FL2FXCONST_DBL(0.f); 522 523 if (lag==0) { 524 for (i=startLine; i<stopLine; i++) { 525 result += (fPow2(spectrum[i])>>scale); 526 } 527 } 528 else { 529 for (i=startLine; i<(stopLine-lag); i++) { 530 result += (fMult(spectrum[i], spectrum[i+lag])>>scale); 531 } 532 } 533 534 return result; 535} 536 537/***************************************************************************/ 538/*! 539 \brief FDKaacEnc_AutoCorrNormFac 540 541 Autocorrelation function for 1st and 2nd half of the spectrum 542 543 \param pointer to spectrum 544 \param pointer to autocorrelation window 545 \param filter start line 546 547****************************************************************************/ 548static inline FIXP_DBL FDKaacEnc_AutoCorrNormFac( 549 const FIXP_DBL value, 550 const INT scale, 551 INT *sc 552 ) 553{ 554 #define HLM_MIN_NRG 0.0000000037252902984619140625f /* 2^-28 */ 555 #define MAX_INV_NRGFAC (1.f/HLM_MIN_NRG) 556 557 FIXP_DBL retValue; 558 FIXP_DBL A, B; 559 560 if (scale>=0) { 561 A = value; 562 B = FL2FXCONST_DBL(HLM_MIN_NRG)>>fixMin(DFRACT_BITS-1,scale); 563 } 564 else { 565 A = value>>fixMin(DFRACT_BITS-1,(-scale)); 566 B = FL2FXCONST_DBL(HLM_MIN_NRG); 567 } 568 569 if (A > B) { 570 int shift = 0; 571 FIXP_DBL tmp = invSqrtNorm2(value,&shift); 572 573 retValue = fMult(tmp,tmp); 574 *sc += (2*shift); 575 } 576 else { 577 /* MAX_INV_NRGFAC*FDKpow(2,-28) = 1/2^-28 * 2^-28 = 1.0 */ 578 retValue = /*FL2FXCONST_DBL(MAX_INV_NRGFAC*FDKpow(2,-28))*/ (FIXP_DBL)MAXVAL_DBL; 579 *sc += scale+28; 580 } 581 582 return retValue; 583} 584 585static void FDKaacEnc_MergedAutoCorrelation( 586 const FIXP_DBL *spectrum, 587 const INT isLowDelay, 588 const FIXP_DBL acfWindow[MAX_NUM_OF_FILTERS][TNS_MAX_ORDER+3+1], 589 const INT lpcStartLine[MAX_NUM_OF_FILTERS], 590 const INT lpcStopLine, 591 const INT maxOrder, 592 const INT acfSplit[MAX_NUM_OF_FILTERS], 593 FIXP_DBL *_rxx1, 594 FIXP_DBL *_rxx2 595 ) 596{ 597 int i, idx0, idx1, idx2, idx3, idx4, lag; 598 FIXP_DBL rxx1_0, rxx2_0, rxx3_0, rxx4_0; 599 600 /* buffer for temporal spectrum */ 601 C_ALLOC_SCRATCH_START(pSpectrum, FIXP_DBL, (1024)); 602 603 /* pre-initialization output */ 604 FDKmemclear(&_rxx1[0], sizeof(FIXP_DBL)*(maxOrder+1)); 605 FDKmemclear(&_rxx2[0], sizeof(FIXP_DBL)*(maxOrder+1)); 606 607 idx0 = idx1 = idx2 = idx3 = idx4 = 0; 608 609 /* MDCT line indices separating the 1st, 2nd, 3rd, and 4th analysis quarters */ 610 if ( (acfSplit[LOFILT]==-1) || (acfSplit[HIFILT]==-1) ) { 611 /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum */ 612 idx0 = lpcStartLine[LOFILT]; 613 i = lpcStopLine - lpcStartLine[LOFILT]; 614 idx1 = idx0 + i / 4; 615 idx2 = idx0 + i / 2; 616 idx3 = idx0 + i * 3 / 4; 617 idx4 = lpcStopLine; 618 } 619 else { 620 FDK_ASSERT(acfSplit[LOFILT]==1); 621 FDK_ASSERT(acfSplit[HIFILT]==3); 622 i = (lpcStopLine - lpcStartLine[HIFILT]) / 3; 623 idx0 = lpcStartLine[LOFILT]; 624 idx1 = lpcStartLine[HIFILT]; 625 idx2 = idx1 + i; 626 idx3 = idx2 + i; 627 idx4 = lpcStopLine; 628 } 629 630 /* copy spectrum to temporal buffer and scale up as much as possible */ 631 INT sc1 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx0, idx1); 632 INT sc2 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx1, idx2); 633 INT sc3 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx2, idx3); 634 INT sc4 = FDKaacEnc_ScaleUpSpectrum(pSpectrum, spectrum, idx3, idx4); 635 636 /* get scaling values for summation */ 637 INT nsc1, nsc2, nsc3, nsc4; 638 for (nsc1=1; (1<<nsc1)<(idx1-idx0); nsc1++); 639 for (nsc2=1; (1<<nsc2)<(idx2-idx1); nsc2++); 640 for (nsc3=1; (1<<nsc3)<(idx3-idx2); nsc3++); 641 for (nsc4=1; (1<<nsc4)<(idx4-idx3); nsc4++); 642 643 /* compute autocorrelation value at lag zero, i. e. energy, for each quarter */ 644 rxx1_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, 0, nsc1); 645 rxx2_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, 0, nsc2); 646 rxx3_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, 0, nsc3); 647 rxx4_0 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, 0, nsc4); 648 649 /* compute energy normalization factors, i. e. 1/energy (saves some divisions) */ 650 if (rxx1_0 != FL2FXCONST_DBL(0.f)) 651 { 652 INT sc_fac1 = -1; 653 FIXP_DBL fac1 = FDKaacEnc_AutoCorrNormFac(rxx1_0, ((-2*sc1)+nsc1), &sc_fac1); 654 _rxx1[0] = scaleValue(fMult(rxx1_0,fac1),sc_fac1); 655 656 if (isLowDelay) 657 { 658 for (lag = 1; lag <= maxOrder; lag++) { 659 /* compute energy-normalized and windowed autocorrelation values at this lag */ 660 FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); 661 _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][lag]); 662 } 663 } 664 else 665 { 666 for (lag = 1; lag <= maxOrder; lag++) { 667 if ((3 * lag) <= maxOrder + 3) { 668 FIXP_DBL x1 = FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx0, idx1, lag, nsc1); 669 _rxx1[lag] = fMult(scaleValue(fMult(x1,fac1),sc_fac1), acfWindow[LOFILT][3*lag]); 670 } 671 } 672 } 673 } 674 675 /* auto corr over upper 3/4 of spectrum */ 676 if ( !((rxx2_0 == FL2FXCONST_DBL(0.f)) && (rxx3_0 == FL2FXCONST_DBL(0.f)) && (rxx4_0 == FL2FXCONST_DBL(0.f))) ) 677 { 678 FIXP_DBL fac2, fac3, fac4; 679 fac2 = fac3 = fac4 = FL2FXCONST_DBL(0.f); 680 INT sc_fac2, sc_fac3, sc_fac4; 681 sc_fac2 = sc_fac3 = sc_fac4 = 0; 682 683 if (rxx2_0!=FL2FXCONST_DBL(0.f)) { 684 fac2 = FDKaacEnc_AutoCorrNormFac(rxx2_0, ((-2*sc2)+nsc2), &sc_fac2); 685 sc_fac2 -= 2; 686 } 687 if (rxx3_0!=FL2FXCONST_DBL(0.f)) { 688 fac3 = FDKaacEnc_AutoCorrNormFac(rxx3_0, ((-2*sc3)+nsc3), &sc_fac3); 689 sc_fac3 -= 2; 690 } 691 if (rxx4_0!=FL2FXCONST_DBL(0.f)) { 692 fac4 = FDKaacEnc_AutoCorrNormFac(rxx4_0, ((-2*sc4)+nsc4), &sc_fac4); 693 sc_fac4 -= 2; 694 } 695 696 _rxx2[0] = scaleValue(fMult(rxx2_0,fac2),sc_fac2) + 697 scaleValue(fMult(rxx3_0,fac3),sc_fac3) + 698 scaleValue(fMult(rxx4_0,fac4),sc_fac4); 699 700 for (lag = 1; lag <= maxOrder; lag++) { 701 /* merge quarters 2, 3, 4 into one autocorrelation; quarter 1 stays separate */ 702 FIXP_DBL x2 = scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx1, idx2, lag, nsc2), fac2),sc_fac2) + 703 scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx2, idx3, lag, nsc3), fac3),sc_fac3) + 704 scaleValue(fMult(FDKaacEnc_CalcAutoCorrValue(pSpectrum, idx3, idx4, lag, nsc4), fac4),sc_fac4); 705 706 _rxx2[lag] = fMult(x2, acfWindow[HIFILT][lag]); 707 } 708 } 709 710 C_ALLOC_SCRATCH_END(pSpectrum, FIXP_DBL, (1024)); 711} 712 713 714/***************************************************************************** 715 functionname: FDKaacEnc_TnsDetect 716 description: do decision, if TNS shall be used or not 717 returns: 718 input: tns data structure (modified), 719 tns config structure, 720 scalefactor size and table, 721 spectrum, 722 subblock num, blocktype, 723 sfb-wise energy. 724 725*****************************************************************************/ 726INT FDKaacEnc_TnsDetect( 727 TNS_DATA *tnsData, 728 const TNS_CONFIG *tC, 729 TNS_INFO* tnsInfo, 730 INT sfbCnt, 731 FIXP_DBL *spectrum, 732 INT subBlockNumber, 733 INT blockType 734 ) 735{ 736 /* autocorrelation function for 1st, 2nd, 3rd, and 4th quarter of the spectrum. */ 737 FIXP_DBL rxx1[TNS_MAX_ORDER+1]; /* higher part */ 738 FIXP_DBL rxx2[TNS_MAX_ORDER+1]; /* lower part */ 739 FIXP_DBL parcor_tmp[TNS_MAX_ORDER]; 740 741 int i; 742 743 TNS_SUBBLOCK_INFO *tsbi = (blockType == SHORT_WINDOW) 744 ? &tnsData->dataRaw.Short.subBlockInfo[subBlockNumber] 745 : &tnsData->dataRaw.Long.subBlockInfo; 746 747 tnsData->filtersMerged = FALSE; 748 749 tsbi->tnsActive[HIFILT] = FALSE; 750 tsbi->predictionGain[HIFILT] = 1000; 751 tsbi->tnsActive[LOFILT] = FALSE; 752 tsbi->predictionGain[LOFILT] = 1000; 753 754 tnsInfo->numOfFilters[subBlockNumber] = 0; 755 tnsInfo->coefRes[subBlockNumber] = tC->coefRes; 756 for (i = 0; i < tC->maxOrder; i++) { 757 tnsInfo->coef[subBlockNumber][HIFILT][i] = tnsInfo->coef[subBlockNumber][LOFILT][i] = 0; 758 } 759 760 tnsInfo->length[subBlockNumber][HIFILT] = tnsInfo->length[subBlockNumber][LOFILT] = 0; 761 tnsInfo->order [subBlockNumber][HIFILT] = tnsInfo->order [subBlockNumber][LOFILT] = 0; 762 763 if ( (tC->tnsActive) && (tC->maxOrder>0) ) 764 { 765 int sumSqrCoef; 766 767 FDKaacEnc_MergedAutoCorrelation( 768 spectrum, 769 tC->isLowDelay, 770 tC->acfWindow, 771 tC->lpcStartLine, 772 tC->lpcStopLine, 773 tC->maxOrder, 774 tC->confTab.acfSplit, 775 rxx1, 776 rxx2); 777 778 /* compute higher TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ 779 tsbi->predictionGain[HIFILT] = FDKaacEnc_AutoToParcor(rxx2, parcor_tmp, tC->confTab.tnsLimitOrder[HIFILT]); 780 781 /* non-linear quantization of TNS lattice coefficients with given resolution */ 782 FDKaacEnc_Parcor2Index( 783 parcor_tmp, 784 tnsInfo->coef[subBlockNumber][HIFILT], 785 tC->confTab.tnsLimitOrder[HIFILT], 786 tC->coefRes); 787 788 /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ 789 for (i = tC->confTab.tnsLimitOrder[HIFILT] - 1; i >= 0; i--) { 790 if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { 791 break; 792 } 793 } 794 795 tnsInfo->order[subBlockNumber][HIFILT] = i + 1; 796 797 sumSqrCoef = 0; 798 for (; i >= 0; i--) { 799 sumSqrCoef += tnsInfo->coef[subBlockNumber][HIFILT][i] * tnsInfo->coef[subBlockNumber][HIFILT][i]; 800 } 801 802 tnsInfo->direction[subBlockNumber][HIFILT] = tC->confTab.tnsFilterDirection[HIFILT]; 803 tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[HIFILT]; 804 805 /* disable TNS if predictionGain is less than 3dB or sumSqrCoef is too small */ 806 if ((tsbi->predictionGain[HIFILT] > tC->confTab.threshOn[HIFILT]) || (sumSqrCoef > (tC->confTab.tnsLimitOrder[HIFILT]/2 + 2))) 807 { 808 tsbi->tnsActive[HIFILT] = TRUE; 809 tnsInfo->numOfFilters[subBlockNumber]++; 810 811 /* compute second filter for lower quarter; only allowed for long windows! */ 812 if ( (blockType != SHORT_WINDOW) && 813 (tC->confTab.filterEnabled[LOFILT]) && (tC->confTab.seperateFiltersAllowed) ) 814 { 815 /* compute second filter for lower frequencies */ 816 817 /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ 818 INT predGain = FDKaacEnc_AutoToParcor(rxx1, parcor_tmp, tC->confTab.tnsLimitOrder[LOFILT]); 819 820 /* non-linear quantization of TNS lattice coefficients with given resolution */ 821 FDKaacEnc_Parcor2Index( 822 parcor_tmp, 823 tnsInfo->coef[subBlockNumber][LOFILT], 824 tC->confTab.tnsLimitOrder[LOFILT], 825 tC->coefRes); 826 827 /* reduce filter order by truncating trailing zeros, compute sum(abs(coefs)) */ 828 for (i = tC->confTab.tnsLimitOrder[LOFILT] - 1; i >= 0; i--) { 829 if (tnsInfo->coef[subBlockNumber][LOFILT][i] != 0) { 830 break; 831 } 832 } 833 tnsInfo->order[subBlockNumber][LOFILT] = i + 1; 834 835 sumSqrCoef = 0; 836 for (; i >= 0; i--) { 837 sumSqrCoef += tnsInfo->coef[subBlockNumber][LOFILT][i] * tnsInfo->coef[subBlockNumber][LOFILT][i]; 838 } 839 840 tnsInfo->direction[subBlockNumber][LOFILT] = tC->confTab.tnsFilterDirection[LOFILT]; 841 tnsInfo->length[subBlockNumber][LOFILT] = tC->lpcStartBand[HIFILT] - tC->lpcStartBand[LOFILT]; 842 843 /* filter lower quarter if gain is high enough, but not if it's too high */ 844 if ( ( (predGain > tC->confTab.threshOn[LOFILT]) && (predGain < (16000 * tC->confTab.tnsLimitOrder[LOFILT])) ) 845 || ( (sumSqrCoef > 9) && (sumSqrCoef < 22 * tC->confTab.tnsLimitOrder[LOFILT]) ) ) 846 { 847 /* compare lower to upper filter; if they are very similar, merge them */ 848 tsbi->tnsActive[LOFILT] = TRUE; 849 sumSqrCoef = 0; 850 for (i = 0; i < tC->confTab.tnsLimitOrder[LOFILT]; i++) { 851 sumSqrCoef += FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i] - tnsInfo->coef[subBlockNumber][LOFILT][i]); 852 } 853 if ( (sumSqrCoef < 2) && 854 (tnsInfo->direction[subBlockNumber][LOFILT] == tnsInfo->direction[subBlockNumber][HIFILT]) ) 855 { 856 tnsData->filtersMerged = TRUE; 857 tnsInfo->length[subBlockNumber][HIFILT] = sfbCnt - tC->lpcStartBand[LOFILT]; 858 for (; i < tnsInfo->order[subBlockNumber][HIFILT]; i++) { 859 if (FDKabs(tnsInfo->coef[subBlockNumber][HIFILT][i]) > 1) { 860 break; 861 } 862 } 863 for (i--; i >= 0; i--) { 864 if (tnsInfo->coef[subBlockNumber][HIFILT][i] != 0) { 865 break; 866 } 867 } 868 if (i < tnsInfo->order[subBlockNumber][HIFILT]) { 869 tnsInfo->order[subBlockNumber][HIFILT] = i + 1; 870 } 871 } 872 else { 873 tnsInfo->numOfFilters[subBlockNumber]++; 874 } 875 } /* filter lower part */ 876 tsbi->predictionGain[LOFILT]=predGain; 877 878 } /* second filter allowed */ 879 } /* if predictionGain > 1437 ... */ 880 } /* maxOrder > 0 && tnsActive */ 881 882 return 0; 883 884} 885 886 887/***************************************************************************/ 888/*! 889 \brief FDKaacLdEnc_TnsSync 890 891 synchronize TNS parameters when TNS gain difference small (relative) 892 893 \param pointer to TNS data structure (destination) 894 \param pointer to TNS data structure (source) 895 \param pointer to TNS config structure 896 \param number of sub-block 897 \param block type 898 899 \return void 900****************************************************************************/ 901void FDKaacEnc_TnsSync( 902 TNS_DATA *tnsDataDest, 903 const TNS_DATA *tnsDataSrc, 904 TNS_INFO *tnsInfoDest, 905 TNS_INFO *tnsInfoSrc, 906 const INT blockTypeDest, 907 const INT blockTypeSrc, 908 const TNS_CONFIG *tC 909 ) 910{ 911 int i, w, absDiff, nWindows; 912 TNS_SUBBLOCK_INFO *sbInfoDest; 913 const TNS_SUBBLOCK_INFO *sbInfoSrc; 914 915 /* if one channel contains short blocks and the other not, do not synchronize */ 916 if ( (blockTypeSrc == SHORT_WINDOW && blockTypeDest != SHORT_WINDOW) || 917 (blockTypeDest == SHORT_WINDOW && blockTypeSrc != SHORT_WINDOW) ) 918 { 919 return; 920 } 921 922 if (blockTypeDest != SHORT_WINDOW) { 923 sbInfoDest = &tnsDataDest->dataRaw.Long.subBlockInfo; 924 sbInfoSrc = &tnsDataSrc->dataRaw.Long.subBlockInfo; 925 nWindows = 1; 926 } else { 927 sbInfoDest = &tnsDataDest->dataRaw.Short.subBlockInfo[0]; 928 sbInfoSrc = &tnsDataSrc->dataRaw.Short.subBlockInfo[0]; 929 nWindows = 8; 930 } 931 932 for (w=0; w<nWindows; w++) { 933 const TNS_SUBBLOCK_INFO *pSbInfoSrcW = sbInfoSrc + w; 934 TNS_SUBBLOCK_INFO *pSbInfoDestW = sbInfoDest + w; 935 INT doSync = 1, absDiffSum = 0; 936 937 /* if TNS is active in at least one channel, check if ParCor coefficients of higher filter are similar */ 938 if (pSbInfoDestW->tnsActive[HIFILT] || pSbInfoSrcW->tnsActive[HIFILT]) { 939 for (i = 0; i < tC->maxOrder; i++) { 940 absDiff = FDKabs(tnsInfoDest->coef[w][HIFILT][i] - tnsInfoSrc->coef[w][HIFILT][i]); 941 absDiffSum += absDiff; 942 /* if coefficients diverge too much between channels, do not synchronize */ 943 if ((absDiff > 1) || (absDiffSum > 2)) { 944 doSync = 0; 945 break; 946 } 947 } 948 949 if (doSync) { 950 /* if no significant difference was detected, synchronize coefficient sets */ 951 if (pSbInfoSrcW->tnsActive[HIFILT]) { 952 /* no dest filter, or more dest than source filters: use one dest filter */ 953 if ((!pSbInfoDestW->tnsActive[HIFILT]) || 954 ((pSbInfoDestW->tnsActive[HIFILT]) && (tnsInfoDest->numOfFilters[w] > tnsInfoSrc->numOfFilters[w]))) 955 { 956 pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 1; 957 } 958 tnsDataDest->filtersMerged = tnsDataSrc->filtersMerged; 959 tnsInfoDest->order [w][HIFILT] = tnsInfoSrc->order [w][HIFILT]; 960 tnsInfoDest->length [w][HIFILT] = tnsInfoSrc->length [w][HIFILT]; 961 tnsInfoDest->direction [w][HIFILT] = tnsInfoSrc->direction [w][HIFILT]; 962 tnsInfoDest->coefCompress[w][HIFILT] = tnsInfoSrc->coefCompress[w][HIFILT]; 963 964 for (i = 0; i < tC->maxOrder; i++) { 965 tnsInfoDest->coef[w][HIFILT][i] = tnsInfoSrc->coef[w][HIFILT][i]; 966 } 967 } 968 else 969 pSbInfoDestW->tnsActive[HIFILT] = tnsInfoDest->numOfFilters[w] = 0; 970 } 971 } 972 973 } 974} 975 976/***************************************************************************/ 977/*! 978 \brief FDKaacEnc_TnsEncode 979 980 perform TNS encoding 981 982 \param pointer to TNS info structure 983 \param pointer to TNS data structure 984 \param number of sfbs 985 \param pointer to TNS config structure 986 \param low-pass line 987 \param pointer to spectrum 988 \param number of sub-block 989 \param block type 990 991 \return ERROR STATUS 992****************************************************************************/ 993INT FDKaacEnc_TnsEncode( 994 TNS_INFO* tnsInfo, 995 TNS_DATA* tnsData, 996 const INT numOfSfb, 997 const TNS_CONFIG *tC, 998 const INT lowPassLine, 999 FIXP_DBL* spectrum, 1000 const INT subBlockNumber, 1001 const INT blockType 1002 ) 1003{ 1004 INT i, startLine, stopLine; 1005 1006 if ( ( (blockType == SHORT_WINDOW) && (!tnsData->dataRaw.Short.subBlockInfo[subBlockNumber].tnsActive[HIFILT]) ) 1007 || ( (blockType != SHORT_WINDOW) && (!tnsData->dataRaw.Long.subBlockInfo.tnsActive[HIFILT]) ) ) 1008 { 1009 return 1; 1010 } 1011 1012 startLine = (tnsData->filtersMerged) ? tC->lpcStartLine[LOFILT] : tC->lpcStartLine[HIFILT]; 1013 stopLine = tC->lpcStopLine; 1014 1015 for (i=0; i<tnsInfo->numOfFilters[subBlockNumber]; i++) { 1016 1017 INT lpcGainFactor; 1018 FIXP_DBL LpcCoeff[TNS_MAX_ORDER]; 1019 FIXP_DBL workBuffer[TNS_MAX_ORDER]; 1020 FIXP_DBL parcor_tmp[TNS_MAX_ORDER]; 1021 1022 FDKaacEnc_Index2Parcor( 1023 tnsInfo->coef[subBlockNumber][i], 1024 parcor_tmp, 1025 tnsInfo->order[subBlockNumber][i], 1026 tC->coefRes); 1027 1028 lpcGainFactor = FDKaacEnc_ParcorToLpc( 1029 parcor_tmp, 1030 LpcCoeff, 1031 tnsInfo->order[subBlockNumber][i], 1032 workBuffer); 1033 1034 FDKaacEnc_AnalysisFilter( 1035 &spectrum[startLine], 1036 stopLine - startLine, 1037 LpcCoeff, 1038 tnsInfo->order[subBlockNumber][i], 1039 lpcGainFactor); 1040 1041 /* update for second filter */ 1042 startLine = tC->lpcStartLine[LOFILT]; 1043 stopLine = tC->lpcStartLine[HIFILT]; 1044 } 1045 1046 return(0); 1047 1048} 1049 1050static void FDKaacEnc_CalcGaussWindow( 1051 FIXP_DBL *win, 1052 const int winSize, 1053 const INT samplingRate, 1054 const INT transformResolution, 1055 const FIXP_DBL timeResolution, 1056 const INT timeResolution_e 1057 ) 1058{ 1059 #define PI_E (2) 1060 #define PI_M FL2FXCONST_DBL(3.1416f/(float)(1<<PI_E)) 1061 1062 #define EULER_E (2) 1063 #define EULER_M FL2FXCONST_DBL(2.7183/(float)(1<<EULER_E)) 1064 1065 #define COEFF_LOOP_SCALE (4) 1066 1067 INT i, e1, e2, gaussExp_e; 1068 FIXP_DBL gaussExp_m; 1069 1070 /* calc. window exponent from time resolution: 1071 * 1072 * gaussExp = PI * samplingRate * 0.001f * timeResolution / transformResolution; 1073 * gaussExp = -0.5f * gaussExp * gaussExp; 1074 */ 1075 gaussExp_m = fMultNorm(timeResolution, fMult(PI_M, fDivNorm( (FIXP_DBL)(samplingRate), (FIXP_DBL)(LONG)(transformResolution*1000.f), &e1)), &e2); 1076 gaussExp_m = -fPow2Div2(gaussExp_m); 1077 gaussExp_e = 2*(e1+e2+timeResolution_e+PI_E); 1078 1079 FDK_ASSERT( winSize < (1<<COEFF_LOOP_SCALE) ); 1080 1081 /* calc. window coefficients 1082 * win[i] = (float)exp( gaussExp * (i+0.5) * (i+0.5) ); 1083 */ 1084 for( i=0; i<winSize; i++) { 1085 1086 win[i] = fPow( 1087 EULER_M, 1088 EULER_E, 1089 fMult(gaussExp_m, fPow2((i*FL2FXCONST_DBL(1.f/(float)(1<<COEFF_LOOP_SCALE)) + FL2FXCONST_DBL(.5f/(float)(1<<COEFF_LOOP_SCALE))))), 1090 gaussExp_e + 2*COEFF_LOOP_SCALE, 1091 &e1); 1092 1093 win[i] = scaleValueSaturate(win[i], e1); 1094 } 1095} 1096 1097 1098/***************************************************************************/ 1099/*! 1100 \brief FDKaacEnc_AutoToParcor 1101 1102 conversion autocorrelation to reflection coefficients 1103 1104 \param pointer to input (acf) 1105 \param pointer to output (reflection coefficients) 1106 \param number of coefficients 1107 1108 \return prediction gain 1109****************************************************************************/ 1110static INT FDKaacEnc_AutoToParcor( 1111 FIXP_DBL *RESTRICT input, 1112 FIXP_DBL *RESTRICT reflCoeff, 1113 const INT numOfCoeff 1114 ) 1115{ 1116 INT i, j, scale=0; 1117 FIXP_DBL tmp, parcorWorkBuffer[TNS_MAX_ORDER]; 1118 INT predictionGain = (INT)(TNS_PREDGAIN_SCALE); 1119 1120 FIXP_DBL *RESTRICT workBuffer = parcorWorkBuffer; 1121 const FIXP_DBL autoCorr_0 = input[0]; 1122 1123 FDKmemclear(reflCoeff,numOfCoeff*sizeof(FIXP_DBL)); 1124 1125 if((FIXP_DBL)input[0] == FL2FXCONST_DBL(0.0)) { 1126 return(predictionGain); 1127 } 1128 1129 FDKmemcpy(workBuffer,&input[1],numOfCoeff*sizeof(FIXP_DBL)); 1130 for(i=0; i<numOfCoeff; i++) { 1131 LONG sign = ((LONG)workBuffer[0] >> (DFRACT_BITS-1)); 1132 tmp = (FIXP_DBL)((LONG)workBuffer[0]^sign); 1133 1134 if(input[0]<tmp) 1135 break; 1136 1137 tmp = (FIXP_DBL)((LONG)schur_div(tmp, input[0], FRACT_BITS)^(~sign)); 1138 reflCoeff[i] = tmp; 1139 1140 for(j=numOfCoeff-i-1; j>=0; j--) { 1141 FIXP_DBL accu1 = fMult(tmp, input[j]); 1142 FIXP_DBL accu2 = fMult(tmp, workBuffer[j]); 1143 workBuffer[j] += accu1; 1144 input[j] += accu2; 1145 } 1146 1147 workBuffer++; 1148 } 1149 1150 tmp = fMult((FIXP_DBL)((LONG)TNS_PREDGAIN_SCALE<<21), fDivNorm(fAbs(autoCorr_0), fAbs(input[0]), &scale)); 1151 if ( fMultDiv2(autoCorr_0, input[0])<FL2FXCONST_DBL(0.0f) ) { 1152 tmp = -tmp; 1153 } 1154 predictionGain = (LONG)scaleValue(tmp,scale-21); 1155 1156 return (predictionGain); 1157} 1158 1159 1160static INT FDKaacEnc_Search3(FIXP_DBL parcor) 1161{ 1162 INT i, index=0; 1163 1164 for(i=0;i<8;i++){ 1165 if(parcor > FDKaacEnc_tnsCoeff3Borders[i]) 1166 index=i; 1167 } 1168 return(index-4); 1169} 1170 1171static INT FDKaacEnc_Search4(FIXP_DBL parcor) 1172{ 1173 INT i, index=0; 1174 1175 for(i=0;i<16;i++){ 1176 if(parcor > FDKaacEnc_tnsCoeff4Borders[i]) 1177 index=i; 1178 } 1179 return(index-8); 1180} 1181 1182 1183/***************************************************************************** 1184 1185 functionname: FDKaacEnc_Parcor2Index 1186 1187*****************************************************************************/ 1188static void FDKaacEnc_Parcor2Index( 1189 const FIXP_DBL *parcor, 1190 INT *RESTRICT index, 1191 const INT order, 1192 const INT bitsPerCoeff 1193 ) 1194{ 1195 INT i; 1196 for(i=0; i<order; i++) { 1197 if(bitsPerCoeff == 3) 1198 index[i] = FDKaacEnc_Search3(parcor[i]); 1199 else 1200 index[i] = FDKaacEnc_Search4(parcor[i]); 1201 } 1202} 1203 1204 1205/***************************************************************************** 1206 1207 functionname: FDKaacEnc_Index2Parcor 1208 description: inverse quantization for reflection coefficients 1209 returns: - 1210 input: quantized values, ptr. to reflection coefficients, 1211 no. of coefficients, resolution 1212 output: reflection coefficients 1213 1214*****************************************************************************/ 1215static void FDKaacEnc_Index2Parcor( 1216 const INT *index, 1217 FIXP_DBL *RESTRICT parcor, 1218 const INT order, 1219 const INT bitsPerCoeff 1220 ) 1221{ 1222 INT i; 1223 for(i=0; i<order; i++) 1224 parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i]+8] : FDKaacEnc_tnsEncCoeff3[index[i]+4]; 1225} 1226 1227 1228/***************************************************************************** 1229 1230 functionname: FDKaacEnc_ParcorToLpc 1231 description: conversion reflection coefficients to LPC coefficients 1232 returns: Gain factor 1233 input: reflection coefficients, no. of reflection coefficients <order>, 1234 ptr. to work buffer (required size: order) 1235 output: <order> LPC coefficients 1236 1237*****************************************************************************/ 1238static INT FDKaacEnc_ParcorToLpc( 1239 const FIXP_DBL *reflCoeff, 1240 FIXP_DBL *RESTRICT LpcCoeff, 1241 const INT numOfCoeff, 1242 FIXP_DBL *RESTRICT workBuffer 1243 ) 1244{ 1245 INT i, j; 1246 INT shiftval, par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ 1247 FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); 1248 1249 LpcCoeff[0] = reflCoeff[0] >> par2LpcShiftVal; 1250 for(i=1; i<numOfCoeff; i++) { 1251 for(j=0; j<i; j++) { 1252 workBuffer[j] = LpcCoeff[i-1-j]; 1253 } 1254 1255 for(j=0; j<i; j++) { 1256 LpcCoeff[j] += fMult(reflCoeff[i],workBuffer[j]); 1257 } 1258 1259 LpcCoeff[i] = reflCoeff[i] >> par2LpcShiftVal; 1260 } 1261 1262 /* normalize LpcCoeff and calc shiftfactor */ 1263 for(i=0; i<numOfCoeff; i++) { 1264 maxVal = fixMax(maxVal,(FIXP_DBL)fixp_abs(LpcCoeff[i])); 1265 } 1266 1267 shiftval = CountLeadingBits(maxVal); 1268 shiftval = (shiftval>=par2LpcShiftVal) ? par2LpcShiftVal : shiftval; 1269 1270 for(i=0; i<numOfCoeff; i++) 1271 LpcCoeff[i] = LpcCoeff[i]<<shiftval; 1272 1273 return (par2LpcShiftVal - shiftval); 1274} 1275 1276/***************************************************************************/ 1277/*! 1278 \brief FDKaacEnc_AnalysisFilter 1279 1280 TNS analysis filter (all-zero filter) 1281 1282 \param pointer to signal spectrum 1283 \param number of lines 1284 \param pointer to lpc coefficients 1285 \param filter order 1286 \param lpc gain factor 1287 1288 \return void 1289****************************************************************************/ 1290/* Note: in-place computation possible */ 1291static void FDKaacEnc_AnalysisFilter( 1292 FIXP_DBL *RESTRICT signal, 1293 const INT numOfLines, 1294 const FIXP_DBL *predictorCoeff, 1295 const INT order, 1296 const INT lpcGainFactor 1297 ) 1298{ 1299 FIXP_DBL statusVar[TNS_MAX_ORDER]; 1300 INT i, j; 1301 const INT shift = lpcGainFactor + 1; /* +1, because fMultDiv2 */ 1302 FIXP_DBL tmp; 1303 1304 if (order>0) { 1305 1306 INT idx = 0; 1307 1308 /* keep filter coefficients twice and save memory copy operation in 1309 modulo state buffer */ 1310#if defined(ARCH_PREFER_MULT_32x16) 1311 FIXP_SGL coeff[2*TNS_MAX_ORDER]; 1312 const FIXP_SGL *pCoeff; 1313 for(i=0;i<order;i++) { 1314 coeff[i] = FX_DBL2FX_SGL(predictorCoeff[i]); 1315 } 1316 FDKmemcpy(&coeff[order], coeff, order*sizeof(FIXP_SGL)); 1317#else 1318 FIXP_DBL coeff[2*TNS_MAX_ORDER]; 1319 const FIXP_DBL *pCoeff; 1320 FDKmemcpy(&coeff[0], predictorCoeff, order*sizeof(FIXP_DBL)); 1321 FDKmemcpy(&coeff[order], predictorCoeff, order*sizeof(FIXP_DBL)); 1322#endif 1323 FDKmemclear(statusVar, order*sizeof(FIXP_DBL)); 1324 1325 for(j=0; j<numOfLines; j++) { 1326 pCoeff = &coeff[(order-idx)]; 1327 tmp = FL2FXCONST_DBL(0); 1328 for(i=0; i<order; i++) { 1329 tmp = fMultAddDiv2(tmp, pCoeff[i], statusVar[i]) ; 1330 } 1331 1332 if(--idx<0) { idx = order-1; } 1333 statusVar[idx] = signal[j]; 1334 1335 FDK_ASSERT(lpcGainFactor>=0); 1336 signal[j] = (tmp<<shift) + signal[j]; 1337 } 1338 } 1339} 1340 1341 1342