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_SCALE (2) 1071 #define PI_FIX FL2FXCONST_DBL(3.1416f/(float)(1<<PI_SCALE)) 1072 1073 #define EULER_SCALE (2) 1074 #define EULER_FIX FL2FXCONST_DBL(2.7183/(float)(1<<EULER_SCALE)) 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_FIX, 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_SCALE); 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_FIX, 1099 EULER_SCALE, 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] = scaleValue(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(autoCorr_0, input[0], &scale)); 1161 predictionGain = (LONG)scaleValue(tmp,scale-21); 1162 1163 return (predictionGain); 1164 } 1165 1166 1167 static INT FDKaacEnc_Search3(FIXP_DBL parcor) 1168 { 1169 INT i, index=0; 1170 1171 for(i=0;i<8;i++){ 1172 if(parcor > FDKaacEnc_tnsCoeff3Borders[i]) 1173 index=i; 1174 } 1175 return(index-4); 1176 } 1177 1178 static INT FDKaacEnc_Search4(FIXP_DBL parcor) 1179 { 1180 INT i, index=0; 1181 1182 for(i=0;i<16;i++){ 1183 if(parcor > FDKaacEnc_tnsCoeff4Borders[i]) 1184 index=i; 1185 } 1186 return(index-8); 1187 } 1188 1189 1190 /***************************************************************************** 1191 1192 functionname: FDKaacEnc_Parcor2Index 1193 1194 *****************************************************************************/ 1195 static void FDKaacEnc_Parcor2Index( 1196 const FIXP_DBL *parcor, 1197 INT *RESTRICT index, 1198 const INT order, 1199 const INT bitsPerCoeff 1200 ) 1201 { 1202 INT i; 1203 for(i=0; i<order; i++) { 1204 if(bitsPerCoeff == 3) 1205 index[i] = FDKaacEnc_Search3(parcor[i]); 1206 else 1207 index[i] = FDKaacEnc_Search4(parcor[i]); 1208 } 1209 } 1210 1211 1212 /***************************************************************************** 1213 1214 functionname: FDKaacEnc_Index2Parcor 1215 description: inverse quantization for reflection coefficients 1216 returns: - 1217 input: quantized values, ptr. to reflection coefficients, 1218 no. of coefficients, resolution 1219 output: reflection coefficients 1220 1221 *****************************************************************************/ 1222 static void FDKaacEnc_Index2Parcor( 1223 const INT *index, 1224 FIXP_DBL *RESTRICT parcor, 1225 const INT order, 1226 const INT bitsPerCoeff 1227 ) 1228 { 1229 INT i; 1230 for(i=0; i<order; i++) 1231 parcor[i] = bitsPerCoeff == 4 ? FDKaacEnc_tnsEncCoeff4[index[i]+8] : FDKaacEnc_tnsEncCoeff3[index[i]+4]; 1232 } 1233 1234 1235 /***************************************************************************** 1236 1237 functionname: FDKaacEnc_ParcorToLpc 1238 description: conversion reflection coefficients to LPC coefficients 1239 returns: Gain factor 1240 input: reflection coefficients, no. of reflection coefficients <order>, 1241 ptr. to work buffer (required size: order) 1242 output: <order> LPC coefficients 1243 1244 *****************************************************************************/ 1245 static INT FDKaacEnc_ParcorToLpc( 1246 const FIXP_DBL *reflCoeff, 1247 FIXP_DBL *RESTRICT LpcCoeff, 1248 const INT numOfCoeff, 1249 FIXP_DBL *RESTRICT workBuffer 1250 ) 1251 { 1252 INT i, j; 1253 INT shiftval, par2LpcShiftVal = 6; /* 6 should be enough, bec. max(numOfCoeff) = 20 */ 1254 FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); 1255 1256 LpcCoeff[0] = reflCoeff[0] >> par2LpcShiftVal; 1257 for(i=1; i<numOfCoeff; i++) { 1258 for(j=0; j<i; j++) { 1259 workBuffer[j] = LpcCoeff[i-1-j]; 1260 } 1261 1262 for(j=0; j<i; j++) { 1263 LpcCoeff[j] += fMult(reflCoeff[i],workBuffer[j]); 1264 } 1265 1266 LpcCoeff[i] = reflCoeff[i] >> par2LpcShiftVal; 1267 } 1268 1269 /* normalize LpcCoeff and calc shiftfactor */ 1270 for(i=0; i<numOfCoeff; i++) { 1271 maxVal = fixMax(maxVal,(FIXP_DBL)fixp_abs(LpcCoeff[i])); 1272 } 1273 1274 shiftval = CountLeadingBits(maxVal); 1275 shiftval = (shiftval>=par2LpcShiftVal) ? par2LpcShiftVal : shiftval; 1276 1277 for(i=0; i<numOfCoeff; i++) 1278 LpcCoeff[i] = LpcCoeff[i]<<shiftval; 1279 1280 return (par2LpcShiftVal - shiftval); 1281 } 1282 1283 /***************************************************************************/ 1284 /*! 1285 \brief FDKaacEnc_AnalysisFilter 1286 1287 TNS analysis filter (all-zero filter) 1288 1289 \param pointer to signal spectrum 1290 \param number of lines 1291 \param pointer to lpc coefficients 1292 \param filter order 1293 \param lpc gain factor 1294 1295 \return void 1296 ****************************************************************************/ 1297 /* Note: in-place computation possible */ 1298 static void FDKaacEnc_AnalysisFilter( 1299 FIXP_DBL *RESTRICT signal, 1300 const INT numOfLines, 1301 const FIXP_DBL *predictorCoeff, 1302 const INT order, 1303 const INT lpcGainFactor 1304 ) 1305 { 1306 FIXP_DBL statusVar[TNS_MAX_ORDER]; 1307 INT i, j; 1308 const INT shift = lpcGainFactor + 1; /* +1, because fMultDiv2 */ 1309 FIXP_DBL tmp; 1310 1311 if (order>0) { 1312 1313 INT idx = 0; 1314 1315 /* keep filter coefficients twice and save memory copy operation in 1316 modulo state buffer */ 1317 #if defined(ARCH_PREFER_MULT_32x16) 1318 FIXP_SGL coeff[2*TNS_MAX_ORDER]; 1319 const FIXP_SGL *pCoeff; 1320 for(i=0;i<order;i++) { 1321 coeff[i] = FX_DBL2FX_SGL(predictorCoeff[i]); 1322 } 1323 FDKmemcpy(&coeff[order], coeff, order*sizeof(FIXP_SGL)); 1324 #else 1325 FIXP_DBL coeff[2*TNS_MAX_ORDER]; 1326 const FIXP_DBL *pCoeff; 1327 FDKmemcpy(&coeff[0], predictorCoeff, order*sizeof(FIXP_DBL)); 1328 FDKmemcpy(&coeff[order], predictorCoeff, order*sizeof(FIXP_DBL)); 1329 #endif 1330 FDKmemclear(statusVar, order*sizeof(FIXP_DBL)); 1331 1332 for(j=0; j<numOfLines; j++) { 1333 pCoeff = &coeff[(order-idx)]; 1334 tmp = FL2FXCONST_DBL(0); 1335 for(i=0; i<order; i++) { 1336 tmp = fMultAddDiv2(tmp, pCoeff[i], statusVar[i]) ; 1337 } 1338 1339 if(--idx<0) { idx = order-1; } 1340 statusVar[idx] = signal[j]; 1341 1342 FDK_ASSERT(lpcGainFactor>=0); 1343 signal[j] = (tmp<<shift) + signal[j]; 1344 } 1345 } 1346 } 1347 1348 1349