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: M.Werner 87 contents/description: Psychoaccoustic major function block 88 89 ******************************************************************************/ 90 91 #include "psy_const.h" 92 93 #include "block_switch.h" 94 #include "transform.h" 95 #include "spreading.h" 96 #include "pre_echo_control.h" 97 #include "band_nrg.h" 98 #include "psy_configuration.h" 99 #include "psy_data.h" 100 #include "ms_stereo.h" 101 #include "interface.h" 102 #include "psy_main.h" 103 #include "grp_data.h" 104 #include "tns_func.h" 105 #include "pns_func.h" 106 #include "tonality.h" 107 #include "aacEnc_ram.h" 108 #include "intensity.h" 109 110 111 112 /* blending to reduce gibbs artifacts */ 113 #define FADE_OUT_LEN 6 114 static const FIXP_DBL fadeOutFactor[FADE_OUT_LEN] = {1840644096, 1533870080, 1227096064, 920322048, 613548032, 306774016}; 115 116 /* forward definitions */ 117 118 119 static inline int isLowDelay( AUDIO_OBJECT_TYPE aot ) 120 { 121 return (aot==AOT_ER_AAC_LD || aot==AOT_ER_AAC_ELD); 122 } 123 124 /***************************************************************************** 125 126 functionname: FDKaacEnc_PsyNew 127 description: allocates memory for psychoacoustic 128 returns: an error code 129 input: pointer to a psych handle 130 131 *****************************************************************************/ 132 AAC_ENCODER_ERROR FDKaacEnc_PsyNew(PSY_INTERNAL **phpsy, 133 const INT nElements, 134 const INT nChannels 135 ,UCHAR *dynamic_RAM 136 ) 137 { 138 AAC_ENCODER_ERROR ErrorStatus; 139 PSY_INTERNAL *hPsy; 140 INT i; 141 142 hPsy = GetRam_aacEnc_PsyInternal(); 143 *phpsy = hPsy; 144 if (hPsy == NULL) { 145 ErrorStatus = AAC_ENC_NO_MEMORY; 146 goto bail; 147 } 148 149 for (i=0; i<nElements; i++) { 150 /* PSY_ELEMENT */ 151 hPsy->psyElement[i] = GetRam_aacEnc_PsyElement(i); 152 if (hPsy->psyElement[i] == NULL) { 153 ErrorStatus = AAC_ENC_NO_MEMORY; 154 goto bail; 155 } 156 } 157 158 for (i=0; i<nChannels; i++) { 159 /* PSY_STATIC */ 160 hPsy->pStaticChannels[i] = GetRam_aacEnc_PsyStatic(i); 161 if (hPsy->pStaticChannels[i]==NULL) { 162 ErrorStatus = AAC_ENC_NO_MEMORY; 163 goto bail; 164 } 165 /* AUDIO INPUT BUFFER */ 166 hPsy->pStaticChannels[i]->psyInputBuffer = GetRam_aacEnc_PsyInputBuffer(i); 167 if (hPsy->pStaticChannels[i]->psyInputBuffer==NULL) { 168 ErrorStatus = AAC_ENC_NO_MEMORY; 169 goto bail; 170 } 171 } 172 173 /* reusable psych memory */ 174 hPsy->psyDynamic = GetRam_aacEnc_PsyDynamic(0, dynamic_RAM); 175 176 return AAC_ENC_OK; 177 178 bail: 179 FDKaacEnc_PsyClose(phpsy, NULL); 180 181 return ErrorStatus; 182 } 183 184 /***************************************************************************** 185 186 functionname: FDKaacEnc_PsyOutNew 187 description: allocates memory for psyOut struc 188 returns: an error code 189 input: pointer to a psych handle 190 191 *****************************************************************************/ 192 AAC_ENCODER_ERROR FDKaacEnc_PsyOutNew(PSY_OUT **phpsyOut, 193 const INT nElements, 194 const INT nChannels, 195 const INT nSubFrames 196 ,UCHAR *dynamic_RAM 197 ) 198 { 199 AAC_ENCODER_ERROR ErrorStatus; 200 int n, i; 201 int elInc = 0, chInc = 0; 202 203 for (n=0; n<nSubFrames; n++) { 204 phpsyOut[n] = GetRam_aacEnc_PsyOut(n); 205 206 if (phpsyOut[n] == NULL) { 207 ErrorStatus = AAC_ENC_NO_MEMORY; 208 goto bail; 209 } 210 211 for (i=0; i<nChannels; i++) { 212 phpsyOut[n]->pPsyOutChannels[i] = GetRam_aacEnc_PsyOutChannel(chInc++); 213 } 214 215 for (i=0; i<nElements; i++) { 216 phpsyOut[n]->psyOutElement[i] = GetRam_aacEnc_PsyOutElements(elInc++); 217 if (phpsyOut[n]->psyOutElement[i] == NULL) { 218 ErrorStatus = AAC_ENC_NO_MEMORY; 219 goto bail; 220 } 221 } 222 } /* nSubFrames */ 223 224 return AAC_ENC_OK; 225 226 bail: 227 FDKaacEnc_PsyClose(NULL, phpsyOut); 228 return ErrorStatus; 229 } 230 231 232 AAC_ENCODER_ERROR FDKaacEnc_psyInitStates(PSY_INTERNAL *hPsy, 233 PSY_STATIC* psyStatic, 234 AUDIO_OBJECT_TYPE audioObjectType) 235 { 236 /* init input buffer */ 237 FDKmemclear(psyStatic->psyInputBuffer, MAX_INPUT_BUFFER_SIZE*sizeof(INT_PCM)); 238 239 FDKaacEnc_InitBlockSwitching(&psyStatic->blockSwitchingControl, 240 isLowDelay(audioObjectType) 241 ); 242 243 return AAC_ENC_OK; 244 } 245 246 247 AAC_ENCODER_ERROR FDKaacEnc_psyInit(PSY_INTERNAL *hPsy, 248 PSY_OUT **phpsyOut, 249 const INT nSubFrames, 250 const INT nMaxChannels, 251 const AUDIO_OBJECT_TYPE audioObjectType, 252 CHANNEL_MAPPING *cm) 253 { 254 AAC_ENCODER_ERROR ErrorStatus = AAC_ENC_OK; 255 int i, ch, n, chInc = 0, resetChannels = 3; 256 257 if ( (nMaxChannels>2) && (cm->nChannels==2) ) { 258 chInc = 1; 259 FDKaacEnc_psyInitStates(hPsy, hPsy->pStaticChannels[0], audioObjectType); 260 } 261 262 if ( (nMaxChannels==2) ) { 263 resetChannels = 0; 264 } 265 266 for (i=0; i<cm->nElements; i++) { 267 for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { 268 if (cm->elInfo[i].elType!=ID_LFE) { 269 hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[chInc]; 270 if (chInc>=resetChannels) { 271 FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); 272 } 273 hPsy->psyElement[i]->psyStatic[ch]->isLFE = 0; 274 } 275 else { 276 hPsy->psyElement[i]->psyStatic[ch] = hPsy->pStaticChannels[nMaxChannels-1]; 277 hPsy->psyElement[i]->psyStatic[ch]->isLFE = 1; 278 } 279 chInc++; 280 } 281 } 282 283 for (n=0; n<nSubFrames; n++) { 284 chInc = 0; 285 for (i=0; i<cm->nElements; i++) { 286 for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { 287 phpsyOut[n]->psyOutElement[i]->psyOutChannel[ch] = phpsyOut[n]->pPsyOutChannels[chInc++]; 288 } 289 } 290 } 291 292 return ErrorStatus; 293 } 294 295 296 /***************************************************************************** 297 298 functionname: FDKaacEnc_psyMainInit 299 description: initializes psychoacoustic 300 returns: an error code 301 302 *****************************************************************************/ 303 304 AAC_ENCODER_ERROR FDKaacEnc_psyMainInit(PSY_INTERNAL *hPsy, 305 AUDIO_OBJECT_TYPE audioObjectType, 306 CHANNEL_MAPPING *cm, 307 INT sampleRate, 308 INT granuleLength, 309 INT bitRate, 310 INT tnsMask, 311 INT bandwidth, 312 INT usePns, 313 INT useIS, 314 UINT syntaxFlags, 315 ULONG initFlags) 316 { 317 AAC_ENCODER_ERROR ErrorStatus; 318 int i, ch; 319 int channelsEff = cm->nChannelsEff; 320 int tnsChannels = 0; 321 FB_TYPE filterBank; 322 323 324 switch(FDKaacEnc_GetMonoStereoMode(cm->encMode)) { 325 /* ... and map to tnsChannels */ 326 case EL_MODE_MONO: tnsChannels = 1; break; 327 case EL_MODE_STEREO: tnsChannels = 2; break; 328 default: tnsChannels = 0; 329 } 330 331 switch (audioObjectType) 332 { 333 default: filterBank = FB_LC; break; 334 case AOT_ER_AAC_LD: filterBank = FB_LD; break; 335 case AOT_ER_AAC_ELD: filterBank = FB_ELD; break; 336 } 337 338 hPsy->granuleLength = granuleLength; 339 340 ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, LONG_WINDOW, hPsy->granuleLength, useIS, &(hPsy->psyConf[0]), filterBank); 341 if (ErrorStatus != AAC_ENC_OK) 342 return ErrorStatus; 343 344 ErrorStatus = FDKaacEnc_InitTnsConfiguration( 345 (bitRate*tnsChannels)/channelsEff, 346 sampleRate, 347 tnsChannels, 348 LONG_WINDOW, 349 hPsy->granuleLength, 350 (syntaxFlags&AC_SBR_PRESENT)?1:0, 351 &(hPsy->psyConf[0].tnsConf), 352 &hPsy->psyConf[0], 353 (INT)(tnsMask&2), 354 (INT)(tnsMask&8) ); 355 356 if (ErrorStatus != AAC_ENC_OK) 357 return ErrorStatus; 358 359 if (granuleLength > 512) { 360 ErrorStatus = FDKaacEnc_InitPsyConfiguration(bitRate/channelsEff, sampleRate, bandwidth, SHORT_WINDOW, hPsy->granuleLength, useIS, &hPsy->psyConf[1], filterBank); 361 if (ErrorStatus != AAC_ENC_OK) 362 return ErrorStatus; 363 364 ErrorStatus = FDKaacEnc_InitTnsConfiguration( 365 (bitRate*tnsChannels)/channelsEff, 366 sampleRate, 367 tnsChannels, 368 SHORT_WINDOW, 369 hPsy->granuleLength, 370 (syntaxFlags&AC_SBR_PRESENT)?1:0, 371 &hPsy->psyConf[1].tnsConf, 372 &hPsy->psyConf[1], 373 (INT)(tnsMask&1), 374 (INT)(tnsMask&4) ); 375 376 if (ErrorStatus != AAC_ENC_OK) 377 return ErrorStatus; 378 379 } 380 381 382 for (i=0; i<cm->nElements; i++) { 383 for (ch=0; ch<cm->elInfo[i].nChannelsInEl; ch++) { 384 if (initFlags) { 385 /* reset states */ 386 FDKaacEnc_psyInitStates(hPsy, hPsy->psyElement[i]->psyStatic[ch], audioObjectType); 387 } 388 389 FDKaacEnc_InitPreEchoControl(hPsy->psyElement[i]->psyStatic[ch]->sfbThresholdnm1, 390 &hPsy->psyElement[i]->psyStatic[ch]->calcPreEcho, 391 hPsy->psyConf[0].sfbCnt, 392 hPsy->psyConf[0].sfbPcmQuantThreshold, 393 &hPsy->psyElement[i]->psyStatic[ch]->mdctScalenm1); 394 } 395 } 396 397 ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[0].pnsConf, 398 bitRate/channelsEff, 399 sampleRate, 400 usePns, 401 hPsy->psyConf[0].sfbCnt, 402 hPsy->psyConf[0].sfbOffset, 403 cm->elInfo[0].nChannelsInEl, 404 (hPsy->psyConf[0].filterbank == FB_LC)); 405 if (ErrorStatus != AAC_ENC_OK) 406 return ErrorStatus; 407 408 ErrorStatus = FDKaacEnc_InitPnsConfiguration(&hPsy->psyConf[1].pnsConf, 409 bitRate/channelsEff, 410 sampleRate, 411 usePns, 412 hPsy->psyConf[1].sfbCnt, 413 hPsy->psyConf[1].sfbOffset, 414 cm->elInfo[1].nChannelsInEl, 415 (hPsy->psyConf[1].filterbank == FB_LC)); 416 return ErrorStatus; 417 } 418 419 420 static 421 void FDKaacEnc_deinterleaveInputBuffer(INT_PCM *pOutputSamples, 422 INT_PCM *pInputSamples, 423 INT nSamples, 424 INT nChannels) 425 { 426 INT k; 427 /* deinterlave input samples and write to output buffer */ 428 for (k=0; k<nSamples; k++) { 429 pOutputSamples[k] = pInputSamples[k*nChannels]; 430 } 431 } 432 433 434 435 /***************************************************************************** 436 437 functionname: FDKaacEnc_psyMain 438 description: psychoacoustic 439 returns: an error code 440 441 This function assumes that enough input data is in the modulo buffer. 442 443 *****************************************************************************/ 444 445 AAC_ENCODER_ERROR FDKaacEnc_psyMain(INT channels, 446 PSY_ELEMENT *psyElement, 447 PSY_DYNAMIC *psyDynamic, 448 PSY_CONFIGURATION *psyConf, 449 PSY_OUT_ELEMENT *RESTRICT psyOutElement, 450 INT_PCM *pInput, 451 INT *chIdx, 452 INT totalChannels 453 ) 454 { 455 INT commonWindow = 1; 456 INT maxSfbPerGroup[(2)]; 457 INT mdctSpectrum_e; 458 INT ch; /* counts through channels */ 459 INT w; /* counts through windows */ 460 INT sfb; /* counts through scalefactor bands */ 461 INT line; /* counts through lines */ 462 463 PSY_CONFIGURATION *RESTRICT hPsyConfLong = &psyConf[0]; 464 PSY_CONFIGURATION *RESTRICT hPsyConfShort = &psyConf[1]; 465 PSY_OUT_CHANNEL **RESTRICT psyOutChannel = psyOutElement->psyOutChannel; 466 FIXP_SGL sfbTonality[(2)][MAX_SFB_LONG]; 467 468 PSY_STATIC **RESTRICT psyStatic = psyElement->psyStatic; 469 470 PSY_DATA *RESTRICT psyData[(2)]; 471 TNS_DATA *RESTRICT tnsData[(2)]; 472 PNS_DATA *RESTRICT pnsData[(2)]; 473 474 INT zeroSpec = TRUE; /* means all spectral lines are zero */ 475 476 INT blockSwitchingOffset; 477 478 PSY_CONFIGURATION *RESTRICT hThisPsyConf[(2)]; 479 INT windowLength[(2)]; 480 INT nWindows[(2)]; 481 INT wOffset; 482 483 INT maxSfb[(2)]; 484 INT *pSfbMaxScaleSpec[(2)]; 485 FIXP_DBL *pSfbEnergy[(2)]; 486 FIXP_DBL *pSfbSpreadEnergy[(2)]; 487 FIXP_DBL *pSfbEnergyLdData[(2)]; 488 FIXP_DBL *pSfbEnergyMS[(2)]; 489 FIXP_DBL *pSfbThreshold[(2)]; 490 491 INT isShortWindow[(2)]; 492 493 494 if (hPsyConfLong->filterbank == FB_LC) { 495 blockSwitchingOffset = psyConf->granuleLength + (9*psyConf->granuleLength/(2*TRANS_FAC)); 496 } else { 497 blockSwitchingOffset = psyConf->granuleLength; 498 } 499 500 for(ch = 0; ch < channels; ch++) 501 { 502 psyData[ch] = &psyDynamic->psyData[ch]; 503 tnsData[ch] = &psyDynamic->tnsData[ch]; 504 pnsData[ch] = &psyDynamic->pnsData[ch]; 505 506 psyData[ch]->mdctSpectrum = psyOutChannel[ch]->mdctSpectrum; 507 } 508 509 /* block switching */ 510 if (hPsyConfLong->filterbank != FB_ELD) 511 { 512 int err; 513 514 for(ch = 0; ch < channels; ch++) 515 { 516 C_ALLOC_SCRATCH_START(timeSignal, INT_PCM, (1024)); 517 psyStatic[ch]->blockSwitchingControl.timeSignal = timeSignal; 518 519 /* deinterleave input data and use for block switching */ 520 FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->blockSwitchingControl.timeSignal, 521 &pInput[chIdx[ch]], 522 psyConf->granuleLength, 523 totalChannels); 524 525 526 FDKaacEnc_BlockSwitching (&psyStatic[ch]->blockSwitchingControl, 527 psyConf->granuleLength 528 ,psyStatic[ch]->isLFE 529 ); 530 531 532 /* fill up internal input buffer, to 2xframelength samples */ 533 FDKmemcpy(psyStatic[ch]->psyInputBuffer+blockSwitchingOffset, 534 psyStatic[ch]->blockSwitchingControl.timeSignal, 535 (2*psyConf->granuleLength-blockSwitchingOffset)*sizeof(INT_PCM)); 536 537 C_ALLOC_SCRATCH_END(timeSignal, INT_PCM, (1024)); 538 } 539 540 /* synch left and right block type */ 541 err = FDKaacEnc_SyncBlockSwitching(&psyStatic[0]->blockSwitchingControl, 542 &psyStatic[1]->blockSwitchingControl, 543 channels, 544 commonWindow); 545 546 if (err) { 547 return AAC_ENC_UNSUPPORTED_AOT; /* mixed up LC and LD */ 548 } 549 550 } 551 else { 552 for(ch = 0; ch < channels; ch++) 553 { 554 /* deinterleave input data and use for block switching */ 555 FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer + blockSwitchingOffset, 556 &pInput[chIdx[ch]], 557 psyConf->granuleLength, 558 totalChannels); 559 } 560 } 561 562 for(ch = 0; ch < channels; ch++) 563 isShortWindow[ch]=(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == SHORT_WINDOW); 564 565 /* set parameters according to window length */ 566 for(ch = 0; ch < channels; ch++) 567 { 568 if(isShortWindow[ch]) { 569 hThisPsyConf[ch] = hPsyConfShort; 570 windowLength[ch] = psyConf->granuleLength/TRANS_FAC; 571 nWindows[ch] = TRANS_FAC; 572 maxSfb[ch] = MAX_SFB_SHORT; 573 574 pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Short[0]; 575 pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Short[0]; 576 pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Short[0]; 577 pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Short[0]; 578 pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Short[0]; 579 pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Short[0]; 580 581 } else 582 { 583 hThisPsyConf[ch] = hPsyConfLong; 584 windowLength[ch] = psyConf->granuleLength; 585 nWindows[ch] = 1; 586 maxSfb[ch] = MAX_GROUPED_SFB; 587 588 pSfbMaxScaleSpec[ch] = psyData[ch]->sfbMaxScaleSpec.Long; 589 pSfbEnergy[ch] = psyData[ch]->sfbEnergy.Long; 590 pSfbSpreadEnergy[ch] = psyData[ch]->sfbSpreadEnergy.Long; 591 pSfbEnergyLdData[ch] = psyData[ch]->sfbEnergyLdData.Long; 592 pSfbEnergyMS[ch] = psyData[ch]->sfbEnergyMS.Long; 593 pSfbThreshold[ch] = psyData[ch]->sfbThreshold.Long; 594 } 595 } 596 597 /* Transform and get mdctScaling for all channels and windows. */ 598 for(ch = 0; ch < channels; ch++) 599 { 600 /* update number of active bands */ 601 if (psyStatic[ch]->isLFE) { 602 psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActiveLFE; 603 psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLineLFE; 604 } else 605 { 606 psyData[ch]->sfbActive = hThisPsyConf[ch]->sfbActive; 607 psyData[ch]->lowpassLine = hThisPsyConf[ch]->lowpassLine; 608 } 609 610 for(w = 0; w < nWindows[ch]; w++) { 611 612 wOffset = w*windowLength[ch]; 613 614 FDKaacEnc_Transform_Real( psyStatic[ch]->psyInputBuffer + wOffset, 615 psyData[ch]->mdctSpectrum+wOffset, 616 psyStatic[ch]->blockSwitchingControl.lastWindowSequence, 617 psyStatic[ch]->blockSwitchingControl.windowShape, 618 &psyStatic[ch]->blockSwitchingControl.lastWindowShape, 619 psyConf->granuleLength, 620 &mdctSpectrum_e, 621 hThisPsyConf[ch]->filterbank 622 ,psyStatic[ch]->overlapAddBuffer 623 ); 624 625 /* Low pass / highest sfb */ 626 FDKmemclear(&psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset], 627 (windowLength[ch]-psyData[ch]->lowpassLine)*sizeof(FIXP_DBL)); 628 629 if (hPsyConfLong->filterbank != FB_LC) { 630 /* Do blending to reduce gibbs artifacts */ 631 for (int i=0; i<FADE_OUT_LEN; i++) { 632 psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i] = fMult(psyData[ch]->mdctSpectrum[psyData[ch]->lowpassLine+wOffset - FADE_OUT_LEN + i], fadeOutFactor[i]); 633 } 634 } 635 636 637 /* Check for zero spectrum. These loops will usually terminate very, very early. */ 638 for(line=0; (line<psyData[ch]->lowpassLine) && (zeroSpec==TRUE); line++) { 639 if (psyData[ch]->mdctSpectrum[line+wOffset] != (FIXP_DBL)0) { 640 zeroSpec = FALSE; 641 break; 642 } 643 } 644 645 } /* w loop */ 646 647 psyData[ch]->mdctScale = mdctSpectrum_e; 648 649 /* rotate internal time samples */ 650 FDKmemmove(psyStatic[ch]->psyInputBuffer, 651 psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, 652 psyConf->granuleLength*sizeof(INT_PCM)); 653 654 655 /* ... and get remaining samples from input buffer */ 656 FDKaacEnc_deinterleaveInputBuffer( psyStatic[ch]->psyInputBuffer+psyConf->granuleLength, 657 &pInput[ (2*psyConf->granuleLength-blockSwitchingOffset)*totalChannels + chIdx[ch] ], 658 blockSwitchingOffset-psyConf->granuleLength, 659 totalChannels); 660 661 } /* ch */ 662 663 /* Do some rescaling to get maximum possible accuracy for energies */ 664 if ( zeroSpec == FALSE) { 665 666 /* Calc possible spectrum leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ 667 INT minSpecShift = MAX_SHIFT_DBL; 668 INT nrgShift = MAX_SHIFT_DBL; 669 INT finalShift = MAX_SHIFT_DBL; 670 FIXP_DBL currNrg = 0; 671 FIXP_DBL maxNrg = 0; 672 673 for(ch = 0; ch < channels; ch++) { 674 for(w = 0; w < nWindows[ch]; w++) { 675 wOffset = w*windowLength[ch]; 676 FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, 677 hThisPsyConf[ch]->sfbOffset, 678 pSfbMaxScaleSpec[ch]+w*maxSfb[ch], 679 psyData[ch]->sfbActive); 680 681 for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) 682 minSpecShift = fixMin(minSpecShift, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]); 683 } 684 685 } 686 687 /* Calc possible energy leftshift for each sfb (1 means: 1 bit left shift is possible without overflow) */ 688 for(ch = 0; ch < channels; ch++) { 689 for(w = 0; w < nWindows[ch]; w++) { 690 wOffset = w*windowLength[ch]; 691 currNrg = FDKaacEnc_CheckBandEnergyOptim(psyData[ch]->mdctSpectrum+wOffset, 692 pSfbMaxScaleSpec[ch]+w*maxSfb[ch], 693 hThisPsyConf[ch]->sfbOffset, 694 psyData[ch]->sfbActive, 695 pSfbEnergy[ch]+w*maxSfb[ch], 696 pSfbEnergyLdData[ch]+w*maxSfb[ch], 697 minSpecShift-4); 698 699 maxNrg = fixMax(maxNrg, currNrg); 700 } 701 } 702 703 if ( maxNrg != (FIXP_DBL)0 ) { 704 nrgShift = (CountLeadingBits(maxNrg)>>1) + (minSpecShift-4); 705 } 706 707 /* 2check: Hasn't this decision to be made for both channels? */ 708 /* For short windows 1 additional bit headroom is necessary to prevent overflows when summing up energies in FDKaacEnc_groupShortData() */ 709 if(isShortWindow[0]) nrgShift--; 710 711 /* both spectrum and energies mustn't overflow */ 712 finalShift = fixMin(minSpecShift, nrgShift); 713 714 /* do not shift more than 3 bits more to the left than signal without blockfloating point 715 * would be to avoid overflow of scaled PCM quantization thresholds */ 716 if (finalShift > psyData[0]->mdctScale + 3 ) 717 finalShift = psyData[0]->mdctScale + 3; 718 719 FDK_ASSERT(finalShift >= 0); /* right shift is not allowed */ 720 721 /* correct sfbEnergy and sfbEnergyLdData with new finalShift */ 722 FIXP_DBL ldShift = finalShift * FL2FXCONST_DBL(2.0/64); 723 for(ch = 0; ch < channels; ch++) { 724 for(w = 0; w < nWindows[ch]; w++) { 725 for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { 726 INT scale = fixMax(0, (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb]-4); 727 scale = fixMin((scale-finalShift)<<1, DFRACT_BITS-1); 728 if (scale >= 0) (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] >>= (scale); 729 else (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] <<= (-scale); 730 (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = fMult((pSfbEnergy[ch]+w*maxSfb[ch])[sfb], C_RATIO); 731 (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] += ldShift; 732 } 733 } 734 } 735 736 if ( finalShift != 0 ) { 737 for (ch = 0; ch < channels; ch++) { 738 for(w = 0; w < nWindows[ch]; w++) { 739 wOffset = w*windowLength[ch]; 740 for(line=0; line<psyData[ch]->lowpassLine; line++) { 741 psyData[ch]->mdctSpectrum[line+wOffset] <<= finalShift; 742 } 743 /* update sfbMaxScaleSpec */ 744 for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) 745 (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] -= finalShift; 746 } 747 /* update mdctScale */ 748 psyData[ch]->mdctScale -= finalShift; 749 } 750 } 751 752 } else { 753 /* all spectral lines are zero */ 754 for (ch = 0; ch < channels; ch++) { 755 psyData[ch]->mdctScale = 0; /* otherwise mdctScale would be for example 7 and PCM quantization thresholds would be shifted 756 * 14 bits to the right causing some of them to become 0 (which causes problems later) */ 757 /* clear sfbMaxScaleSpec */ 758 for(w = 0; w < nWindows[ch]; w++) { 759 for (sfb = 0; sfb<psyData[ch]->sfbActive; sfb++) { 760 (pSfbMaxScaleSpec[ch]+w*maxSfb[ch])[sfb] = 0; 761 (pSfbEnergy[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; 762 (pSfbEnergyLdData[ch]+w*maxSfb[ch])[sfb] = FL2FXCONST_DBL(-1.0f); 763 (pSfbThreshold[ch]+w*maxSfb[ch])[sfb] = (FIXP_DBL)0; 764 } 765 } 766 } 767 } 768 769 /* Advance psychoacoustics: Tonality and TNS */ 770 if (psyStatic[0]->isLFE) { 771 tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive = 0; 772 } 773 else 774 { 775 776 for(ch = 0; ch < channels; ch++) { 777 if (!isShortWindow[ch]) { 778 /* tonality */ 779 FDKaacEnc_CalculateFullTonality( psyData[ch]->mdctSpectrum, 780 pSfbMaxScaleSpec[ch], 781 pSfbEnergyLdData[ch], 782 sfbTonality[ch], 783 psyData[ch]->sfbActive, 784 hThisPsyConf[ch]->sfbOffset, 785 hThisPsyConf[ch]->pnsConf.usePns); 786 } 787 } 788 789 if (hPsyConfLong->tnsConf.tnsActive || hPsyConfShort->tnsConf.tnsActive) { 790 INT tnsActive[TRANS_FAC]; 791 INT nrgScaling[2] = {0,0}; 792 INT tnsSpecShift = 0; 793 794 for(ch = 0; ch < channels; ch++) { 795 for(w = 0; w < nWindows[ch]; w++) { 796 797 wOffset = w*windowLength[ch]; 798 /* TNS */ 799 FDKaacEnc_TnsDetect( 800 tnsData[ch], 801 &hThisPsyConf[ch]->tnsConf, 802 &psyOutChannel[ch]->tnsInfo, 803 hThisPsyConf[ch]->sfbCnt, 804 psyData[ch]->mdctSpectrum+wOffset, 805 w, 806 psyStatic[ch]->blockSwitchingControl.lastWindowSequence 807 ); 808 } 809 } 810 811 if (channels == 2) { 812 FDKaacEnc_TnsSync( 813 tnsData[1], 814 tnsData[0], 815 &psyOutChannel[1]->tnsInfo, 816 &psyOutChannel[0]->tnsInfo, 817 818 psyStatic[1]->blockSwitchingControl.lastWindowSequence, 819 psyStatic[0]->blockSwitchingControl.lastWindowSequence, 820 &hThisPsyConf[1]->tnsConf); 821 } 822 823 FDK_ASSERT(commonWindow=1); /* all checks for TNS do only work for common windows (which is always set)*/ 824 for(w = 0; w < nWindows[0]; w++) 825 { 826 if (isShortWindow[0]) 827 tnsActive[w] = tnsData[0]->dataRaw.Short.subBlockInfo[w].tnsActive || 828 ((channels == 2) ? tnsData[1]->dataRaw.Short.subBlockInfo[w].tnsActive : 0); 829 else 830 tnsActive[w] = tnsData[0]->dataRaw.Long.subBlockInfo.tnsActive || 831 ((channels == 2) ? tnsData[1]->dataRaw.Long.subBlockInfo.tnsActive : 0); 832 } 833 834 for(ch = 0; ch < channels; ch++) { 835 if (tnsActive[0] && !isShortWindow[ch]) { 836 /* Scale down spectrum if tns is active in one of the two channels with same lastWindowSequence */ 837 /* first part of threshold calculation; it's not necessary to update sfbMaxScaleSpec */ 838 INT shift = 1; 839 for(sfb=0; sfb<hThisPsyConf[ch]->lowpassLine; sfb++) { 840 psyData[ch]->mdctSpectrum[sfb] = psyData[ch]->mdctSpectrum[sfb] >> shift; 841 } 842 843 /* update thresholds */ 844 for (sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { 845 pSfbThreshold[ch][sfb] >>= (2*shift); 846 } 847 848 psyData[ch]->mdctScale += shift; /* update mdctScale */ 849 850 /* calc sfbEnergies after tnsEncode again ! */ 851 852 } 853 } 854 855 for(ch = 0; ch < channels; ch++) { 856 for(w = 0; w < nWindows[ch]; w++) 857 { 858 wOffset = w*windowLength[ch]; 859 FDKaacEnc_TnsEncode( 860 &psyOutChannel[ch]->tnsInfo, 861 tnsData[ch], 862 hThisPsyConf[ch]->sfbCnt, 863 &hThisPsyConf[ch]->tnsConf, 864 hThisPsyConf[ch]->sfbOffset[psyData[ch]->sfbActive],/*hThisPsyConf[ch]->lowpassLine*/ /* filter stops before that line ! */ 865 psyData[ch]->mdctSpectrum+wOffset, 866 w, 867 psyStatic[ch]->blockSwitchingControl.lastWindowSequence); 868 869 if(tnsActive[w]) { 870 /* Calc sfb-bandwise mdct-energies for left and right channel again, */ 871 /* if tns active in current channel or in one channel with same lastWindowSequence left and right */ 872 FDKaacEnc_CalcSfbMaxScaleSpec(psyData[ch]->mdctSpectrum+wOffset, 873 hThisPsyConf[ch]->sfbOffset, 874 pSfbMaxScaleSpec[ch]+w*maxSfb[ch], 875 psyData[ch]->sfbActive); 876 } 877 } 878 } 879 880 for(ch = 0; ch < channels; ch++) { 881 for(w = 0; w < nWindows[ch]; w++) { 882 883 if (tnsActive[w]) { 884 885 if (isShortWindow[ch]) { 886 FDKaacEnc_CalcBandEnergyOptimShort(psyData[ch]->mdctSpectrum+w*windowLength[ch], 887 pSfbMaxScaleSpec[ch]+w*maxSfb[ch], 888 hThisPsyConf[ch]->sfbOffset, 889 psyData[ch]->sfbActive, 890 pSfbEnergy[ch]+w*maxSfb[ch]); 891 } 892 else { 893 nrgScaling[ch] = /* with tns, energy calculation can overflow; -> scaling */ 894 FDKaacEnc_CalcBandEnergyOptimLong(psyData[ch]->mdctSpectrum, 895 pSfbMaxScaleSpec[ch], 896 hThisPsyConf[ch]->sfbOffset, 897 psyData[ch]->sfbActive, 898 pSfbEnergy[ch], 899 pSfbEnergyLdData[ch]); 900 tnsSpecShift = fixMax(tnsSpecShift, nrgScaling[ch]); /* nrgScaling is set only if nrg would have an overflow */ 901 } 902 } /* if tnsActive */ 903 } 904 } /* end channel loop */ 905 906 /* adapt scaling to prevent nrg overflow, only for long blocks */ 907 for(ch = 0; ch < channels; ch++) { 908 if ( (tnsSpecShift!=0) && !isShortWindow[ch] ) { 909 /* scale down spectrum, nrg's and thresholds, if there was an overflow in sfbNrg calculation after tns */ 910 for(line=0; line<hThisPsyConf[ch]->lowpassLine; line++) { 911 psyData[ch]->mdctSpectrum[line] >>= tnsSpecShift; 912 } 913 INT scale = (tnsSpecShift-nrgScaling[ch])<<1; 914 for(sfb=0; sfb<psyData[ch]->sfbActive; sfb++) { 915 pSfbEnergyLdData[ch][sfb] -= scale*FL2FXCONST_DBL(1.0/LD_DATA_SCALING); 916 pSfbEnergy[ch][sfb] >>= scale; 917 pSfbThreshold[ch][sfb] >>= (tnsSpecShift<<1); 918 } 919 psyData[ch]->mdctScale += tnsSpecShift; /* update mdctScale; not necessary to update sfbMaxScaleSpec */ 920 921 } 922 } /* end channel loop */ 923 924 } /* TNS active */ 925 } /* !isLFE */ 926 927 928 929 930 931 932 /* Advance thresholds */ 933 for(ch = 0; ch < channels; ch++) { 934 INT headroom; 935 936 FIXP_DBL clipEnergy; 937 INT energyShift = psyData[ch]->mdctScale*2 ; 938 INT clipNrgShift = energyShift - THR_SHIFTBITS ; 939 940 if(isShortWindow[ch]) 941 headroom = 6; 942 else 943 headroom = 0; 944 945 if (clipNrgShift >= 0) 946 clipEnergy = hThisPsyConf[ch]->clipEnergy >> clipNrgShift ; 947 else if (clipNrgShift>=-headroom) 948 clipEnergy = hThisPsyConf[ch]->clipEnergy << -clipNrgShift ; 949 else 950 clipEnergy = (FIXP_DBL)MAXVAL_DBL ; 951 952 for(w = 0; w < nWindows[ch]; w++) 953 { 954 INT i; 955 /* limit threshold to avoid clipping */ 956 for (i=0; i<psyData[ch]->sfbActive; i++) { 957 *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMin(*(pSfbThreshold[ch]+w*maxSfb[ch]+i), clipEnergy); 958 } 959 960 /* spreading */ 961 FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, 962 hThisPsyConf[ch]->sfbMaskLowFactor, 963 hThisPsyConf[ch]->sfbMaskHighFactor, 964 pSfbThreshold[ch]+w*maxSfb[ch]); 965 966 967 /* PCM quantization threshold */ 968 energyShift += PCM_QUANT_THR_SCALE; 969 if (energyShift>=0) { 970 energyShift = fixMin(DFRACT_BITS-1,energyShift); 971 for (i=0; i<psyData[ch]->sfbActive;i++) { 972 *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, 973 (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] >> energyShift)); 974 } 975 } else { 976 energyShift = fixMin(DFRACT_BITS-1,-energyShift); 977 for (i=0; i<psyData[ch]->sfbActive;i++) { 978 *(pSfbThreshold[ch]+w*maxSfb[ch]+i) = fixMax(*(pSfbThreshold[ch]+w*maxSfb[ch]+i) >> THR_SHIFTBITS, 979 (hThisPsyConf[ch]->sfbPcmQuantThreshold[i] << energyShift)); 980 } 981 } 982 983 if (!psyStatic[ch]->isLFE) 984 { 985 /* preecho control */ 986 if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == STOP_WINDOW) { 987 /* prevent FDKaacEnc_PreEchoControl from comparing stop 988 thresholds with short thresholds */ 989 for (i=0; i<psyData[ch]->sfbActive;i++) { 990 psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; 991 } 992 993 psyStatic[ch]->mdctScalenm1 = 0; 994 psyStatic[ch]->calcPreEcho = 0; 995 } 996 997 FDKaacEnc_PreEchoControl( psyStatic[ch]->sfbThresholdnm1, 998 psyStatic[ch]->calcPreEcho, 999 psyData[ch]->sfbActive, 1000 hThisPsyConf[ch]->maxAllowedIncreaseFactor, 1001 hThisPsyConf[ch]->minRemainingThresholdFactor, 1002 pSfbThreshold[ch]+w*maxSfb[ch], 1003 psyData[ch]->mdctScale, 1004 &psyStatic[ch]->mdctScalenm1); 1005 1006 psyStatic[ch]->calcPreEcho = 1; 1007 1008 if(psyStatic[ch]->blockSwitchingControl.lastWindowSequence == START_WINDOW) 1009 { 1010 /* prevent FDKaacEnc_PreEchoControl in next frame to compare start 1011 thresholds with short thresholds */ 1012 for (i=0; i<psyData[ch]->sfbActive;i++) { 1013 psyStatic[ch]->sfbThresholdnm1[i] = (FIXP_DBL)MAXVAL_DBL; 1014 } 1015 1016 psyStatic[ch]->mdctScalenm1 = 0; 1017 psyStatic[ch]->calcPreEcho = 0; 1018 } 1019 1020 } 1021 1022 /* spread energy to avoid hole detection */ 1023 FDKmemcpy(pSfbSpreadEnergy[ch]+w*maxSfb[ch], pSfbEnergy[ch]+w*maxSfb[ch], psyData[ch]->sfbActive*sizeof(FIXP_DBL)); 1024 1025 FDKaacEnc_SpreadingMax(psyData[ch]->sfbActive, 1026 hThisPsyConf[ch]->sfbMaskLowFactorSprEn, 1027 hThisPsyConf[ch]->sfbMaskHighFactorSprEn, 1028 pSfbSpreadEnergy[ch]+w*maxSfb[ch]); 1029 } 1030 } 1031 1032 /* Calc bandwise energies for mid and side channel. Do it only if 2 channels exist */ 1033 if (channels==2) { 1034 for(w = 0; w < nWindows[1]; w++) { 1035 wOffset = w*windowLength[1]; 1036 FDKaacEnc_CalcBandNrgMSOpt(psyData[0]->mdctSpectrum+wOffset, 1037 psyData[1]->mdctSpectrum+wOffset, 1038 pSfbMaxScaleSpec[0]+w*maxSfb[0], 1039 pSfbMaxScaleSpec[1]+w*maxSfb[1], 1040 hThisPsyConf[1]->sfbOffset, 1041 psyData[0]->sfbActive, 1042 pSfbEnergyMS[0]+w*maxSfb[0], 1043 pSfbEnergyMS[1]+w*maxSfb[1], 1044 (psyStatic[1]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW), 1045 psyData[0]->sfbEnergyMSLdData, 1046 psyData[1]->sfbEnergyMSLdData); 1047 } 1048 } 1049 1050 /* group short data (maxSfb[ch] for short blocks is determined here) */ 1051 for(ch=0;ch<channels;ch++) 1052 { 1053 INT noSfb, i; 1054 if(isShortWindow[ch]) 1055 { 1056 int sfbGrp; 1057 noSfb = psyStatic[ch]->blockSwitchingControl.noOfGroups * hPsyConfShort->sfbCnt; 1058 /* At this point, energies and thresholds are copied/regrouped from the ".Short" to the ".Long" arrays */ 1059 FDKaacEnc_groupShortData( psyData[ch]->mdctSpectrum, 1060 &psyData[ch]->sfbThreshold, 1061 &psyData[ch]->sfbEnergy, 1062 &psyData[ch]->sfbEnergyMS, 1063 &psyData[ch]->sfbSpreadEnergy, 1064 hPsyConfShort->sfbCnt, 1065 psyData[ch]->sfbActive, 1066 hPsyConfShort->sfbOffset, 1067 hPsyConfShort->sfbMinSnrLdData, 1068 psyData[ch]->groupedSfbOffset, 1069 &maxSfbPerGroup[ch], 1070 psyOutChannel[ch]->sfbMinSnrLdData, 1071 psyStatic[ch]->blockSwitchingControl.noOfGroups, 1072 psyStatic[ch]->blockSwitchingControl.groupLen, 1073 psyConf[1].granuleLength); 1074 1075 1076 /* calculate ldData arrays (short values are in .Long-arrays after FDKaacEnc_groupShortData) */ 1077 for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { 1078 LdDataVector(&psyData[ch]->sfbEnergy.Long[sfbGrp], &psyOutChannel[ch]->sfbEnergyLdData[sfbGrp], psyData[ch]->sfbActive); 1079 } 1080 1081 /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ 1082 for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { 1083 LdDataVector(&psyData[ch]->sfbThreshold.Long[sfbGrp], &psyOutChannel[ch]->sfbThresholdLdData[sfbGrp], psyData[ch]->sfbActive); 1084 for (sfb=0;sfb<psyData[ch]->sfbActive;sfb++) { 1085 psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb] = 1086 fixMax(psyOutChannel[ch]->sfbThresholdLdData[sfbGrp+sfb], FL2FXCONST_DBL(-0.515625f)); 1087 } 1088 } 1089 1090 if ( channels==2 ) { 1091 for (sfbGrp = 0; sfbGrp < noSfb; sfbGrp += hPsyConfShort->sfbCnt) { 1092 LdDataVector(&psyData[ch]->sfbEnergyMS.Long[sfbGrp], &psyData[ch]->sfbEnergyMSLdData[sfbGrp], psyData[ch]->sfbActive); 1093 } 1094 } 1095 1096 FDKmemcpy(psyOutChannel[ch]->sfbOffsets, psyData[ch]->groupedSfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); 1097 1098 } else { 1099 /* maxSfb[ch] for long blocks */ 1100 for (sfb = psyData[ch]->sfbActive-1; sfb >= 0; sfb--) { 1101 for (line = hPsyConfLong->sfbOffset[sfb+1]-1; line >= hPsyConfLong->sfbOffset[sfb]; line--) { 1102 if (psyData[ch]->mdctSpectrum[line] != FL2FXCONST_SGL(0.0f)) break; 1103 } 1104 if (line > hPsyConfLong->sfbOffset[sfb]) break; 1105 } 1106 maxSfbPerGroup[ch] = sfb + 1; 1107 /* ensure at least one section in ICS; workaround for existing decoder crc implementation */ 1108 maxSfbPerGroup[ch] = fixMax(fixMin(5,psyData[ch]->sfbActive),maxSfbPerGroup[ch]); 1109 1110 /* sfbNrgLdData is calculated in FDKaacEnc_advancePsychLong, copy in psyOut structure */ 1111 FDKmemcpy(psyOutChannel[ch]->sfbEnergyLdData, psyData[ch]->sfbEnergyLdData.Long, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); 1112 1113 FDKmemcpy(psyOutChannel[ch]->sfbOffsets, hPsyConfLong->sfbOffset, (MAX_GROUPED_SFB+1)*sizeof(INT)); 1114 1115 /* sfbMinSnrLdData modified in adjust threshold, copy necessary */ 1116 FDKmemcpy(psyOutChannel[ch]->sfbMinSnrLdData, hPsyConfLong->sfbMinSnrLdData, psyData[ch]->sfbActive*sizeof(FIXP_DBL)); 1117 1118 /* sfbEnergyMSLdData ist already calculated in FDKaacEnc_CalcBandNrgMSOpt; only in long case */ 1119 1120 /* calc sfbThrld and set Values smaller 2^-31 to 2^-33*/ 1121 LdDataVector(psyData[ch]->sfbThreshold.Long, psyOutChannel[ch]->sfbThresholdLdData, psyData[ch]->sfbActive); 1122 for (i=0;i<psyData[ch]->sfbActive;i++) { 1123 psyOutChannel[ch]->sfbThresholdLdData[i] = 1124 fixMax(psyOutChannel[ch]->sfbThresholdLdData[i], FL2FXCONST_DBL(-0.515625f)); 1125 } 1126 1127 1128 } 1129 1130 1131 } 1132 1133 1134 /* 1135 Intensity parameter intialization. 1136 */ 1137 for(ch=0;ch<channels;ch++) { 1138 FDKmemclear(psyOutChannel[ch]->isBook, MAX_GROUPED_SFB*sizeof(INT)); 1139 FDKmemclear(psyOutChannel[ch]->isScale, MAX_GROUPED_SFB*sizeof(INT)); 1140 } 1141 1142 for(ch=0;ch<channels;ch++) { 1143 INT win = (isShortWindow[ch]?1:0); 1144 if (!psyStatic[ch]->isLFE) 1145 { 1146 /* PNS Decision */ 1147 FDKaacEnc_PnsDetect( &(psyConf[0].pnsConf), 1148 pnsData[ch], 1149 psyStatic[ch]->blockSwitchingControl.lastWindowSequence, 1150 psyData[ch]->sfbActive, 1151 maxSfbPerGroup[ch], /* count of Sfb which are not zero. */ 1152 psyOutChannel[ch]->sfbThresholdLdData, 1153 psyConf[win].sfbOffset, 1154 psyData[ch]->mdctSpectrum, 1155 psyData[ch]->sfbMaxScaleSpec.Long, 1156 sfbTonality[ch], 1157 psyOutChannel[ch]->tnsInfo.order[0][0], 1158 tnsData[ch]->dataRaw.Long.subBlockInfo.predictionGain, 1159 tnsData[ch]->dataRaw.Long.subBlockInfo.tnsActive, 1160 psyOutChannel[ch]->sfbEnergyLdData, 1161 psyOutChannel[ch]->noiseNrg ); 1162 } /* !isLFE */ 1163 } 1164 1165 /* 1166 stereo Processing 1167 */ 1168 if(channels == 2) 1169 { 1170 psyOutElement->toolsInfo.msDigest = MS_NONE; 1171 psyOutElement->commonWindow = commonWindow; 1172 if (psyOutElement->commonWindow) 1173 maxSfbPerGroup[0] = maxSfbPerGroup[1] = 1174 fixMax(maxSfbPerGroup[0], maxSfbPerGroup[1]); 1175 1176 if(psyStatic[0]->blockSwitchingControl.lastWindowSequence != SHORT_WINDOW) 1177 { 1178 /* PNS preprocessing depending on ms processing: PNS not in Short Window! */ 1179 FDKaacEnc_PreProcessPnsChannelPair( 1180 psyData[0]->sfbActive, 1181 (&psyData[0]->sfbEnergy)->Long, 1182 (&psyData[1]->sfbEnergy)->Long, 1183 psyOutChannel[0]->sfbEnergyLdData, 1184 psyOutChannel[1]->sfbEnergyLdData, 1185 psyData[0]->sfbEnergyMS.Long, 1186 &(psyConf[0].pnsConf), 1187 pnsData[0], 1188 pnsData[1]); 1189 1190 FDKaacEnc_IntensityStereoProcessing( 1191 psyData[0]->sfbEnergy.Long, 1192 psyData[1]->sfbEnergy.Long, 1193 psyData[0]->mdctSpectrum, 1194 psyData[1]->mdctSpectrum, 1195 psyData[0]->sfbThreshold.Long, 1196 psyData[1]->sfbThreshold.Long, 1197 psyOutChannel[1]->sfbThresholdLdData, 1198 psyData[0]->sfbSpreadEnergy.Long, 1199 psyData[1]->sfbSpreadEnergy.Long, 1200 psyOutChannel[0]->sfbEnergyLdData, 1201 psyOutChannel[1]->sfbEnergyLdData, 1202 &psyOutElement->toolsInfo.msDigest, 1203 psyOutElement->toolsInfo.msMask, 1204 psyConf[0].sfbCnt, 1205 psyConf[0].sfbCnt, 1206 maxSfbPerGroup[0], 1207 psyConf[0].sfbOffset, 1208 psyConf[0].allowIS && commonWindow, 1209 psyOutChannel[1]->isBook, 1210 psyOutChannel[1]->isScale, 1211 pnsData); 1212 1213 FDKaacEnc_MsStereoProcessing( 1214 psyData, 1215 psyOutChannel, 1216 psyOutChannel[1]->isBook, 1217 &psyOutElement->toolsInfo.msDigest, 1218 psyOutElement->toolsInfo.msMask, 1219 psyData[0]->sfbActive, 1220 psyData[0]->sfbActive, 1221 maxSfbPerGroup[0], 1222 psyOutChannel[0]->sfbOffsets); 1223 1224 /* PNS postprocessing */ 1225 FDKaacEnc_PostProcessPnsChannelPair(psyData[0]->sfbActive, 1226 &(psyConf[0].pnsConf), 1227 pnsData[0], 1228 pnsData[1], 1229 psyOutElement->toolsInfo.msMask, 1230 &psyOutElement->toolsInfo.msDigest); 1231 1232 } else { 1233 FDKaacEnc_IntensityStereoProcessing( 1234 psyData[0]->sfbEnergy.Long, 1235 psyData[1]->sfbEnergy.Long, 1236 psyData[0]->mdctSpectrum, 1237 psyData[1]->mdctSpectrum, 1238 psyData[0]->sfbThreshold.Long, 1239 psyData[1]->sfbThreshold.Long, 1240 psyOutChannel[1]->sfbThresholdLdData, 1241 psyData[0]->sfbSpreadEnergy.Long, 1242 psyData[1]->sfbSpreadEnergy.Long, 1243 psyOutChannel[0]->sfbEnergyLdData, 1244 psyOutChannel[1]->sfbEnergyLdData, 1245 &psyOutElement->toolsInfo.msDigest, 1246 psyOutElement->toolsInfo.msMask, 1247 psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 1248 psyConf[1].sfbCnt, 1249 maxSfbPerGroup[0], 1250 psyData[0]->groupedSfbOffset, 1251 psyConf[0].allowIS && commonWindow, 1252 psyOutChannel[1]->isBook, 1253 psyOutChannel[1]->isScale, 1254 pnsData); 1255 1256 /* it's OK to pass the ".Long" arrays here. They contain grouped short data since FDKaacEnc_groupShortData() */ 1257 FDKaacEnc_MsStereoProcessing( psyData, 1258 psyOutChannel, 1259 psyOutChannel[1]->isBook, 1260 &psyOutElement->toolsInfo.msDigest, 1261 psyOutElement->toolsInfo.msMask, 1262 psyStatic[0]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt, 1263 hPsyConfShort->sfbCnt, 1264 maxSfbPerGroup[0], 1265 psyOutChannel[0]->sfbOffsets); 1266 } 1267 } 1268 1269 /* 1270 PNS Coding 1271 */ 1272 for(ch=0;ch<channels;ch++) { 1273 if (psyStatic[ch]->isLFE) { 1274 /* no PNS coding */ 1275 for(sfb = 0; sfb < psyData[ch]->sfbActive; sfb++) { 1276 psyOutChannel[ch]->noiseNrg[sfb] = NO_NOISE_PNS; 1277 } 1278 } else 1279 { 1280 FDKaacEnc_CodePnsChannel(psyData[ch]->sfbActive, 1281 &(psyConf[ch].pnsConf), 1282 pnsData[ch]->pnsFlag, 1283 psyData[ch]->sfbEnergyLdData.Long, 1284 psyOutChannel[ch]->noiseNrg, /* this is the energy that will be written to the bitstream */ 1285 psyOutChannel[ch]->sfbThresholdLdData); 1286 } 1287 } 1288 1289 /* 1290 build output 1291 */ 1292 for(ch=0;ch<channels;ch++) 1293 { 1294 INT j, grp, mask; 1295 1296 psyOutChannel[ch]->maxSfbPerGroup = maxSfbPerGroup[ch]; 1297 psyOutChannel[ch]->mdctScale = psyData[ch]->mdctScale; 1298 1299 if(isShortWindow[ch]==0) { 1300 1301 psyOutChannel[ch]->sfbCnt = hPsyConfLong->sfbActive; 1302 psyOutChannel[ch]->sfbPerGroup = hPsyConfLong->sfbActive; 1303 psyOutChannel[ch]->lastWindowSequence = psyStatic[ch]->blockSwitchingControl.lastWindowSequence; 1304 psyOutChannel[ch]->windowShape = psyStatic[ch]->blockSwitchingControl.windowShape; 1305 } 1306 else { 1307 INT sfbCnt = psyStatic[ch]->blockSwitchingControl.noOfGroups*hPsyConfShort->sfbCnt; 1308 1309 psyOutChannel[ch]->sfbCnt = sfbCnt; 1310 psyOutChannel[ch]->sfbPerGroup = hPsyConfShort->sfbCnt; 1311 psyOutChannel[ch]->lastWindowSequence = SHORT_WINDOW; 1312 psyOutChannel[ch]->windowShape = SINE_WINDOW; 1313 } 1314 1315 /* generate grouping mask */ 1316 mask = 0; 1317 for (grp = 0; grp < psyStatic[ch]->blockSwitchingControl.noOfGroups; grp++) 1318 { 1319 mask <<= 1; 1320 for (j=1; j<psyStatic[ch]->blockSwitchingControl.groupLen[grp]; j++) { 1321 mask = (mask<<1) | 1 ; 1322 } 1323 } 1324 psyOutChannel[ch]->groupingMask = mask; 1325 1326 /* build interface */ 1327 FDKmemcpy(psyOutChannel[ch]->groupLen,psyStatic[ch]->blockSwitchingControl.groupLen,MAX_NO_OF_GROUPS*sizeof(INT)); 1328 FDKmemcpy(psyOutChannel[ch]->sfbEnergy,(&psyData[ch]->sfbEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 1329 FDKmemcpy(psyOutChannel[ch]->sfbSpreadEnergy,(&psyData[ch]->sfbSpreadEnergy)->Long, MAX_GROUPED_SFB*sizeof(FIXP_DBL)); 1330 // FDKmemcpy(psyOutChannel[ch]->mdctSpectrum, psyData[ch]->mdctSpectrum, (1024)*sizeof(FIXP_DBL)); 1331 } 1332 1333 return AAC_ENC_OK; 1334 } 1335 1336 1337 void FDKaacEnc_PsyClose(PSY_INTERNAL **phPsyInternal, 1338 PSY_OUT **phPsyOut) 1339 { 1340 int n, i; 1341 1342 1343 if(phPsyInternal!=NULL) { 1344 PSY_INTERNAL *hPsyInternal = *phPsyInternal; 1345 1346 if (hPsyInternal) 1347 { 1348 for (i=0; i<(6); i++) { 1349 if (hPsyInternal->pStaticChannels[i]) { 1350 if (hPsyInternal->pStaticChannels[i]->psyInputBuffer) 1351 FreeRam_aacEnc_PsyInputBuffer(&hPsyInternal->pStaticChannels[i]->psyInputBuffer); /* AUDIO INPUT BUFFER */ 1352 1353 FreeRam_aacEnc_PsyStatic(&hPsyInternal->pStaticChannels[i]); /* PSY_STATIC */ 1354 } 1355 } 1356 1357 for (i=0; i<(6); i++) { 1358 if (hPsyInternal->psyElement[i]) 1359 FreeRam_aacEnc_PsyElement(&hPsyInternal->psyElement[i]); /* PSY_ELEMENT */ 1360 } 1361 1362 1363 FreeRam_aacEnc_PsyInternal(phPsyInternal); 1364 } 1365 } 1366 1367 if (phPsyOut!=NULL) { 1368 for (n=0; n<(1); n++) { 1369 if (phPsyOut[n]) 1370 { 1371 for (i=0; i<(6); i++) { 1372 if (phPsyOut[n]->pPsyOutChannels[i]) 1373 FreeRam_aacEnc_PsyOutChannel(&phPsyOut[n]->pPsyOutChannels[i]); /* PSY_OUT_CHANNEL */ 1374 } 1375 1376 for (i=0; i<(6); i++) { 1377 if (phPsyOut[n]->psyOutElement[i]) 1378 FreeRam_aacEnc_PsyOutElements(&phPsyOut[n]->psyOutElement[i]); /* PSY_OUT_ELEMENTS */ 1379 } 1380 1381 FreeRam_aacEnc_PsyOut(&phPsyOut[n]); 1382 } 1383 } 1384 } 1385 } 1386