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