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