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