1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten 5 Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10 scheme for digital audio. This FDK AAC Codec software is intended to be used on 11 a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14 general perceptual audio codecs. AAC-ELD is considered the best-performing 15 full-bandwidth communications codec by independent studies and is widely 16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17 specifications. 18 19 Patent licenses for necessary patent claims for the FDK AAC Codec (including 20 those of Fraunhofer) may be obtained through Via Licensing 21 (www.vialicensing.com) or through the respective patent owners individually for 22 the purpose of encoding or decoding bit streams in products that are compliant 23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24 Android devices already license these patent claims through Via Licensing or 25 directly from the patent owners, and therefore FDK AAC Codec software may 26 already be covered under those patent licenses when it is used for those 27 licensed purposes only. 28 29 Commercially-licensed AAC software libraries, including floating-point versions 30 with enhanced sound quality, are also available from Fraunhofer. Users are 31 encouraged to check the Fraunhofer website for additional applications 32 information and documentation. 33 34 2. COPYRIGHT LICENSE 35 36 Redistribution and use in source and binary forms, with or without modification, 37 are permitted without payment of copyright license fees provided that you 38 satisfy the following conditions: 39 40 You must retain the complete text of this software license in redistributions of 41 the FDK AAC Codec or your modifications thereto in source code form. 42 43 You must retain the complete text of this software license in the documentation 44 and/or other materials provided with redistributions of the FDK AAC Codec or 45 your modifications thereto in binary form. You must make available free of 46 charge copies of the complete source code of the FDK AAC Codec and your 47 modifications thereto to recipients of copies in binary form. 48 49 The name of Fraunhofer may not be used to endorse or promote products derived 50 from this library without prior written permission. 51 52 You may not charge copyright license fees for anyone to use, copy or distribute 53 the FDK AAC Codec software or your modifications thereto. 54 55 Your modified versions of the FDK AAC Codec must carry prominent notices stating 56 that you changed the software and the date of any change. For modified versions 57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59 AAC Codec Library for Android." 60 61 3. NO PATENT LICENSE 62 63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65 Fraunhofer provides no warranty of patent non-infringement with respect to this 66 software. 67 68 You may use this FDK AAC Codec software or modifications thereto only for 69 purposes that are authorized by appropriate patent licenses. 70 71 4. DISCLAIMER 72 73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75 including but not limited to the implied warranties of merchantability and 76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78 or consequential damages, including but not limited to procurement of substitute 79 goods or services; loss of use, data, or profits, or business interruption, 80 however caused and on any theory of liability, whether in contract, strict 81 liability, or tort (including negligence), arising in any way out of the use of 82 this software, even if advised of the possibility of such damage. 83 84 5. CONTACT INFORMATION 85 86 Fraunhofer Institute for Integrated Circuits IIS 87 Attention: Audio and Multimedia Departments - FDK AAC LL 88 Am Wolfsmantel 33 89 91058 Erlangen, Germany 90 91 www.iis.fraunhofer.de/amm 92 amm-info (at) iis.fraunhofer.de 93 ----------------------------------------------------------------------------- */ 94 95 /*********************** MPEG surround decoder library ************************* 96 97 Author(s): 98 99 Description: SAC Dec guided envelope shaping 100 101 *******************************************************************************/ 102 103 #include "sac_reshapeBBEnv.h" 104 105 #include "sac_dec.h" 106 #include "sac_bitdec.h" 107 #include "sac_calcM1andM2.h" 108 #include "sac_reshapeBBEnv.h" 109 #include "sac_rom.h" 110 111 #define INP_DRY_WET 0 112 #define INP_DMX 1 113 114 #define SF_SHAPE 1 115 #define SF_DIV32 6 116 #define SF_FACTOR_SLOT 5 117 118 #define START_BB_ENV 0 /* 10 */ 119 #define END_BB_ENV 9 /* 18 */ 120 121 #define SF_ALPHA1 8 122 #define SF_BETA1 4 123 124 void initBBEnv(spatialDec *self, int initStatesFlag) { 125 INT ch, k; 126 127 for (ch = 0; ch < self->numOutputChannels; ch++) { 128 k = row2channelGES[self->treeConfig][ch]; 129 self->row2channelDmxGES[ch] = k; 130 if (k == -1) continue; 131 132 switch (self->treeConfig) { 133 case TREE_212: 134 self->row2channelDmxGES[ch] = 0; 135 break; 136 default:; 137 } 138 } 139 140 if (initStatesFlag) { 141 for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS + MAX_INPUT_CHANNELS; k++) { 142 self->reshapeBBEnvState->normNrgPrev__FDK[k] = 143 FL2FXCONST_DBL(0.5f); /* 32768.f*32768.f */ 144 self->reshapeBBEnvState->normNrgPrevSF[k] = DFRACT_BITS - 1; 145 self->reshapeBBEnvState->partNrgPrevSF[k] = 0; 146 self->reshapeBBEnvState->partNrgPrev2SF[k] = 0; 147 self->reshapeBBEnvState->frameNrgPrevSF[k] = 0; 148 } 149 } 150 151 self->reshapeBBEnvState->alpha__FDK = 152 FL2FXCONST_DBL(0.99637845575f); /* FDKexp(-64 / (0.4f * 44100)) */ 153 self->reshapeBBEnvState->beta__FDK = 154 FL2FXCONST_DBL(0.96436909488f); /* FDKexp(-64 / (0.04f * 44100)) */ 155 } 156 157 static inline void getSlotNrgHQ(FIXP_DBL *RESTRICT pReal, 158 FIXP_DBL *RESTRICT pImag, 159 FIXP_DBL *RESTRICT slotNrg, INT maxValSF, 160 INT hybBands) { 161 INT qs; 162 FIXP_DBL nrg; 163 164 /* qs = 12, 13, 14 */ 165 slotNrg[0] = ((fPow2Div2((*pReal++) << maxValSF) + 166 fPow2Div2((*pImag++) << maxValSF)) >> 167 (SF_FACTOR_SLOT - 1)); 168 slotNrg[1] = ((fPow2Div2((*pReal++) << maxValSF) + 169 fPow2Div2((*pImag++) << maxValSF)) >> 170 (SF_FACTOR_SLOT - 1)); 171 slotNrg[2] = ((fPow2Div2((*pReal++) << maxValSF) + 172 fPow2Div2((*pImag++) << maxValSF)) >> 173 (SF_FACTOR_SLOT - 1)); 174 /* qs = 15 */ 175 slotNrg[3] = ((fPow2Div2((*pReal++) << maxValSF) + 176 fPow2Div2((*pImag++) << maxValSF)) >> 177 (SF_FACTOR_SLOT - 1)); 178 /* qs = 16, 17 */ 179 nrg = ((fPow2Div2((*pReal++) << maxValSF) + 180 fPow2Div2((*pImag++) << maxValSF)) >> 181 (SF_FACTOR_SLOT - 1)); 182 slotNrg[4] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + 183 fPow2Div2((*pImag++) << maxValSF)) >> 184 (SF_FACTOR_SLOT - 1)); 185 /* qs = 18, 19, 20 */ 186 nrg = ((fPow2Div2((*pReal++) << maxValSF) + 187 fPow2Div2((*pImag++) << maxValSF)) >> 188 (SF_FACTOR_SLOT - 1)); 189 nrg += ((fPow2Div2((*pReal++) << maxValSF) + 190 fPow2Div2((*pImag++) << maxValSF)) >> 191 (SF_FACTOR_SLOT - 1)); 192 slotNrg[5] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + 193 fPow2Div2((*pImag++) << maxValSF)) >> 194 (SF_FACTOR_SLOT - 1)); 195 /* qs = 21, 22 */ 196 nrg = ((fPow2Div2((*pReal++) << maxValSF) + 197 fPow2Div2((*pImag++) << maxValSF)) >> 198 (SF_FACTOR_SLOT - 1)); 199 slotNrg[6] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + 200 fPow2Div2((*pImag++) << maxValSF)) >> 201 (SF_FACTOR_SLOT - 1)); 202 /* qs = 23, 24 */ 203 if (hybBands > 23) { 204 slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) + 205 fPow2Div2((*pImag++) << maxValSF)) >> 206 (SF_FACTOR_SLOT - 1)); 207 slotNrg[6] += ((fPow2Div2((*pReal++) << maxValSF) + 208 fPow2Div2((*pImag++) << maxValSF)) >> 209 (SF_FACTOR_SLOT - 1)); 210 /* qs = 25, 26, 29, 28, 29 */ 211 nrg = ((fPow2Div2((*pReal++) << maxValSF) + 212 fPow2Div2((*pImag++) << maxValSF)) >> 213 (SF_FACTOR_SLOT - 1)); 214 nrg += ((fPow2Div2((*pReal++) << maxValSF) + 215 fPow2Div2((*pImag++) << maxValSF)) >> 216 (SF_FACTOR_SLOT - 1)); 217 nrg += ((fPow2Div2((*pReal++) << maxValSF) + 218 fPow2Div2((*pImag++) << maxValSF)) >> 219 (SF_FACTOR_SLOT - 1)); 220 nrg += ((fPow2Div2((*pReal++) << maxValSF) + 221 fPow2Div2((*pImag++) << maxValSF)) >> 222 (SF_FACTOR_SLOT - 1)); 223 slotNrg[7] = nrg + ((fPow2Div2((*pReal++) << maxValSF) + 224 fPow2Div2((*pImag++) << maxValSF)) >> 225 (SF_FACTOR_SLOT - 1)); 226 /* qs = 30 ... min(41,hybBands-1) */ 227 nrg = ((fPow2Div2((*pReal++) << maxValSF) + 228 fPow2Div2((*pImag++) << maxValSF)) >> 229 (SF_FACTOR_SLOT - 1)); 230 for (qs = 31; qs < hybBands; qs++) { 231 nrg += ((fPow2Div2((*pReal++) << maxValSF) + 232 fPow2Div2((*pImag++) << maxValSF)) >> 233 (SF_FACTOR_SLOT - 1)); 234 } 235 slotNrg[8] = nrg; 236 } else { 237 slotNrg[7] = (FIXP_DBL)0; 238 slotNrg[8] = (FIXP_DBL)0; 239 } 240 } 241 242 static inline INT getMaxValDmx(FIXP_DBL *RESTRICT pReal, 243 FIXP_DBL *RESTRICT pImag, INT cplxBands, 244 INT hybBands) { 245 INT qs, clz; 246 FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); 247 248 for (qs = 12; qs < cplxBands; qs++) { 249 maxVal |= fAbs(pReal[qs]); 250 maxVal |= fAbs(pImag[qs]); 251 } 252 for (; qs < hybBands; qs++) { 253 maxVal |= fAbs(pReal[qs]); 254 } 255 256 clz = fixMax(0, CntLeadingZeros(maxVal) - 1); 257 258 return (clz); 259 } 260 261 static inline INT getMaxValDryWet(FIXP_DBL *RESTRICT pReal, 262 FIXP_DBL *RESTRICT pImag, 263 FIXP_DBL *RESTRICT pHybOutputRealDry, 264 FIXP_DBL *RESTRICT pHybOutputImagDry, 265 FIXP_DBL *RESTRICT pHybOutputRealWet, 266 FIXP_DBL *RESTRICT pHybOutputImagWet, 267 INT cplxBands, INT hybBands) { 268 INT qs, clz; 269 FIXP_DBL maxVal = FL2FXCONST_DBL(0.0f); 270 271 for (qs = 12; qs < cplxBands; qs++) { 272 pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs]; 273 maxVal |= fAbs(pReal[qs]); 274 pImag[qs] = pHybOutputImagDry[qs] + pHybOutputImagWet[qs]; 275 maxVal |= fAbs(pImag[qs]); 276 } 277 for (; qs < hybBands; qs++) { 278 pReal[qs] = pHybOutputRealDry[qs] + pHybOutputRealWet[qs]; 279 maxVal |= fAbs(pReal[qs]); 280 } 281 282 clz = fixMax(0, CntLeadingZeros(maxVal) - 1); 283 284 return (clz); 285 } 286 287 static inline void slotAmp(FIXP_DBL *RESTRICT slotAmp_dry, 288 FIXP_DBL *RESTRICT slotAmp_wet, 289 FIXP_DBL *RESTRICT pHybOutputRealDry, 290 FIXP_DBL *RESTRICT pHybOutputImagDry, 291 FIXP_DBL *RESTRICT pHybOutputRealWet, 292 FIXP_DBL *RESTRICT pHybOutputImagWet, INT cplxBands, 293 INT hybBands) { 294 INT qs; 295 FIXP_DBL dry, wet; 296 297 dry = wet = FL2FXCONST_DBL(0.0f); 298 for (qs = 0; qs < cplxBands; qs++) { 299 dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs]) + 300 fPow2Div2(pHybOutputImagDry[qs])); 301 wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs]) + 302 fPow2Div2(pHybOutputImagWet[qs])); 303 } 304 for (; qs < hybBands; qs++) { 305 dry = fAddSaturate(dry, fPow2Div2(pHybOutputRealDry[qs])); 306 wet = fAddSaturate(wet, fPow2Div2(pHybOutputRealWet[qs])); 307 } 308 *slotAmp_dry = dry; 309 *slotAmp_wet = wet; 310 } 311 312 #if defined(__aarch64__) 313 __attribute__((noinline)) 314 #endif 315 static void 316 shapeBBEnv(FIXP_DBL *pHybOutputRealDry, FIXP_DBL *pHybOutputImagDry, 317 FIXP_DBL dryFac, INT scale, INT cplxBands, INT hybBands) { 318 INT qs; 319 320 if (scale == 0) { 321 for (qs = 0; qs < cplxBands; qs++) { 322 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac); 323 pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac); 324 } 325 for (; qs < hybBands; qs++) { 326 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac); 327 } 328 } else { 329 for (qs = 0; qs < cplxBands; qs++) { 330 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale; 331 pHybOutputImagDry[qs] = fMultDiv2(pHybOutputImagDry[qs], dryFac) << scale; 332 } 333 for (; qs < hybBands; qs++) { 334 pHybOutputRealDry[qs] = fMultDiv2(pHybOutputRealDry[qs], dryFac) << scale; 335 } 336 } 337 } 338 339 static void extractBBEnv(spatialDec *self, INT inp, INT start, INT channels, 340 FIXP_DBL *pEnv, const SPATIAL_BS_FRAME *frame) { 341 INT ch, pb, prevChOffs; 342 INT clz, scale, scale_min, envSF; 343 INT scaleCur, scalePrev, commonScale; 344 INT slotNrgSF, partNrgSF, frameNrgSF; 345 INT *pPartNrgPrevSF, *pFrameNrgPrevSF; 346 INT *pNormNrgPrevSF, *pPartNrgPrev2SF; 347 348 FIXP_DBL maxVal, env, frameNrg, normNrg; 349 FIXP_DBL *pReal, *pImag; 350 FIXP_DBL *partNrg, *partNrgPrev; 351 352 C_ALLOC_SCRATCH_START(pScratchBuffer, FIXP_DBL, 353 (2 * 42 + MAX_PARAMETER_BANDS)); 354 C_ALLOC_SCRATCH_START(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV)); 355 C_ALLOC_SCRATCH_START(resPbSF, INT, (END_BB_ENV - START_BB_ENV)); 356 357 FIXP_DBL *slotNrg = pScratchBuffer + (2 * 42); 358 359 RESHAPE_BBENV_STATE *pBBEnvState = self->reshapeBBEnvState; 360 361 FIXP_DBL alpha = pBBEnvState->alpha__FDK; 362 /*FIXP_DBL alpha1 = (FL2FXCONST_DBL(1.0f) - alpha) << SF_ALPHA1;*/ 363 FIXP_DBL alpha1 = ((FIXP_DBL)MAXVAL_DBL - alpha) << SF_ALPHA1; 364 FIXP_DBL beta = pBBEnvState->beta__FDK; 365 /*FIXP_DBL beta1 = (FL2FXCONST_DBL(1.0f) - beta) << SF_BETA1;*/ 366 FIXP_DBL beta1 = ((FIXP_DBL)MAXVAL_DBL - beta) << SF_BETA1; 367 368 INT shapeActiv = 1; 369 INT hybBands = fixMin(42, self->hybridBands); 370 INT staticScale = self->staticDecScale; 371 INT cplxBands; 372 cplxBands = fixMin(42, self->hybridBands); 373 374 for (ch = start; ch < channels; ch++) { 375 if (inp == INP_DRY_WET) { 376 INT ch2 = row2channelGES[self->treeConfig][ch]; 377 if (ch2 == -1) { 378 continue; 379 } else { 380 if (frame->tempShapeEnableChannelGES[ch2]) { 381 shapeActiv = 1; 382 } else { 383 shapeActiv = 0; 384 } 385 } 386 prevChOffs = ch; 387 pReal = pScratchBuffer; 388 pImag = pScratchBuffer + 42; 389 clz = getMaxValDryWet( 390 pReal, pImag, self->hybOutputRealDry__FDK[ch], 391 self->hybOutputImagDry__FDK[ch], self->hybOutputRealWet__FDK[ch], 392 self->hybOutputImagWet__FDK[ch], cplxBands, hybBands); 393 } else { 394 prevChOffs = ch + self->numOutputChannels; 395 pReal = self->hybInputReal__FDK[ch]; 396 pImag = self->hybInputImag__FDK[ch]; 397 clz = getMaxValDmx(pReal, pImag, cplxBands, hybBands); 398 } 399 400 partNrg = partNrgPrev = pBBEnvState->partNrgPrev__FDK[prevChOffs]; 401 pPartNrgPrevSF = &pBBEnvState->partNrgPrevSF[prevChOffs]; 402 pFrameNrgPrevSF = &pBBEnvState->frameNrgPrevSF[prevChOffs]; 403 pNormNrgPrevSF = &pBBEnvState->normNrgPrevSF[prevChOffs]; 404 pPartNrgPrev2SF = &pBBEnvState->partNrgPrev2SF[prevChOffs]; 405 406 /* calculate slot energy */ 407 { 408 getSlotNrgHQ(&pReal[12], &pImag[12], slotNrg, clz, 409 fixMin(42, self->hybridBands)); /* scale slotNrg: 410 2*(staticScale-clz) + 411 SF_FACTOR_SLOT */ 412 } 413 414 slotNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT; 415 frameNrgSF = 2 * (staticScale - clz) + SF_FACTOR_SLOT; 416 417 partNrgSF = fixMax(slotNrgSF - SF_ALPHA1 + 1, 418 pPartNrgPrevSF[0] - pPartNrgPrev2SF[0] + 1); 419 scalePrev = fixMax(fixMin(partNrgSF - pPartNrgPrevSF[0], DFRACT_BITS - 1), 420 -(DFRACT_BITS - 1)); 421 scaleCur = 422 fixMax(fixMin(partNrgSF - slotNrgSF + SF_ALPHA1, DFRACT_BITS - 1), 423 -(DFRACT_BITS - 1)); 424 425 maxVal = FL2FXCONST_DBL(0.0f); 426 frameNrg = FL2FXCONST_DBL(0.0f); 427 if ((scaleCur < 0) && (scalePrev < 0)) { 428 scaleCur = -scaleCur; 429 scalePrev = -scalePrev; 430 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 431 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) + 432 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev)) 433 << 1; 434 maxVal |= partNrg[pb]; 435 frameNrg += slotNrg[pb] >> 3; 436 } 437 } else if ((scaleCur >= 0) && (scalePrev >= 0)) { 438 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 439 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) + 440 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev)) 441 << 1; 442 maxVal |= partNrg[pb]; 443 frameNrg += slotNrg[pb] >> 3; 444 } 445 } else if ((scaleCur < 0) && (scalePrev >= 0)) { 446 scaleCur = -scaleCur; 447 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 448 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) << scaleCur) + 449 (fMultDiv2(alpha, partNrgPrev[pb]) >> scalePrev)) 450 << 1; 451 maxVal |= partNrg[pb]; 452 frameNrg += slotNrg[pb] >> 3; 453 } 454 } else { /* if ( (scaleCur >= 0) && (scalePrev < 0) ) */ 455 scalePrev = -scalePrev; 456 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 457 partNrg[pb] = ((fMultDiv2(alpha1, slotNrg[pb]) >> scaleCur) + 458 (fMultDiv2(alpha, partNrgPrev[pb]) << scalePrev)) 459 << 1; 460 maxVal |= partNrg[pb]; 461 frameNrg += slotNrg[pb] >> 3; 462 } 463 } 464 465 /* frameNrg /= (END_BB_ENV - START_BB_ENV); 0.88888888888f = 466 * (1/(END_BB_ENV-START_BB_ENV)<<3; shift with 3 is compensated in loop 467 * above */ 468 frameNrg = fMult(frameNrg, FL2FXCONST_DBL(0.88888888888f)); 469 470 /* store scalefactor and headroom for part nrg prev */ 471 pPartNrgPrevSF[0] = partNrgSF; 472 pPartNrgPrev2SF[0] = fixMax(0, CntLeadingZeros(maxVal) - 1); 473 474 commonScale = fixMax(frameNrgSF - SF_ALPHA1 + 1, pFrameNrgPrevSF[0] + 1); 475 scalePrev = fixMin(commonScale - pFrameNrgPrevSF[0], DFRACT_BITS - 1); 476 scaleCur = fixMin(commonScale - frameNrgSF + SF_ALPHA1, DFRACT_BITS - 1); 477 frameNrgSF = commonScale; 478 479 frameNrg = ((fMultDiv2(alpha1, frameNrg) >> scaleCur) + 480 (fMultDiv2(alpha, pBBEnvState->frameNrgPrev__FDK[prevChOffs]) >> 481 scalePrev)) 482 << 1; 483 484 clz = fixMax(0, CntLeadingZeros(frameNrg) - 1); 485 pBBEnvState->frameNrgPrev__FDK[prevChOffs] = frameNrg << clz; 486 pFrameNrgPrevSF[0] = frameNrgSF - clz; 487 488 env = FL2FXCONST_DBL(0.0f); 489 scale = clz + partNrgSF - frameNrgSF; 490 scale_min = DFRACT_BITS - 1; 491 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 492 if ((partNrg[pb] | slotNrg[pb]) != FL2FXCONST_DBL(0.0f)) { 493 INT s; 494 INT sc = 0; 495 INT sn = fixMax(0, CntLeadingZeros(slotNrg[pb]) - 1); 496 FIXP_DBL inv_sqrt = invSqrtNorm2(partNrg[pb], &sc); 497 FIXP_DBL res = fMult(slotNrg[pb] << sn, fPow2(inv_sqrt)); 498 499 s = fixMax(0, CntLeadingZeros(res) - 1); 500 res = res << s; 501 502 sc = scale - (2 * sc - sn - s); 503 scale_min = fixMin(scale_min, sc); 504 505 resPb[pb] = res; 506 resPbSF[pb] = sc; 507 } else { 508 resPb[pb] = (FIXP_DBL)0; 509 resPbSF[pb] = 0; 510 } 511 } 512 513 scale_min = 4 - scale_min; 514 515 for (pb = START_BB_ENV; pb < END_BB_ENV; pb++) { 516 INT sc = fixMax(fixMin(resPbSF[pb] + scale_min, DFRACT_BITS - 1), 517 -(DFRACT_BITS - 1)); 518 519 if (sc < 0) { 520 env += resPb[pb] << (-sc); 521 } else { 522 env += resPb[pb] >> (sc); 523 } 524 } 525 526 env = fMultDiv2(env, pBBEnvState->frameNrgPrev__FDK[prevChOffs]); 527 envSF = slotNrgSF + scale_min + 1; 528 529 commonScale = fixMax(envSF - SF_BETA1 + 1, pNormNrgPrevSF[0] + 1); 530 scalePrev = fixMin(commonScale - pNormNrgPrevSF[0], DFRACT_BITS - 1); 531 scaleCur = fixMin(commonScale - envSF + SF_BETA1, DFRACT_BITS - 1); 532 533 normNrg = ((fMultDiv2(beta1, env) >> scaleCur) + 534 (fMultDiv2(beta, pBBEnvState->normNrgPrev__FDK[prevChOffs]) >> 535 scalePrev)) 536 << 1; 537 538 clz = fixMax(0, CntLeadingZeros(normNrg) - 1); 539 pBBEnvState->normNrgPrev__FDK[prevChOffs] = normNrg << clz; 540 pNormNrgPrevSF[0] = commonScale - clz; 541 542 if (shapeActiv) { 543 if ((env | normNrg) != FL2FXCONST_DBL(0.0f)) { 544 INT sc, se, sn; 545 se = fixMax(0, CntLeadingZeros(env) - 1); 546 sc = commonScale + SF_DIV32 - envSF + se; 547 env = fMult(sqrtFixp((env << se) >> (sc & 0x1)), 548 invSqrtNorm2(normNrg, &sn)); 549 550 sc = fixMin((sc >> 1) - sn, DFRACT_BITS - 1); 551 if (sc < 0) { 552 env <<= (-sc); 553 } else { 554 env >>= (sc); 555 } 556 } 557 /* env is scaled by SF_DIV32/2 bits */ 558 } 559 pEnv[ch] = env; 560 } 561 562 C_ALLOC_SCRATCH_END(resPbSF, INT, (END_BB_ENV - START_BB_ENV)); 563 C_ALLOC_SCRATCH_END(resPb, FIXP_DBL, (END_BB_ENV - START_BB_ENV)); 564 C_ALLOC_SCRATCH_END(pScratchBuffer, FIXP_DBL, (2 * 42 + MAX_PARAMETER_BANDS)); 565 } 566 567 void SpatialDecReshapeBBEnv(spatialDec *self, const SPATIAL_BS_FRAME *frame, 568 INT ts) { 569 INT ch, scale; 570 INT dryFacSF, slotAmpSF; 571 FIXP_DBL tmp, dryFac, envShape; 572 FIXP_DBL slotAmp_dry, slotAmp_wet, slotAmp_ratio; 573 FIXP_DBL envDry[MAX_OUTPUT_CHANNELS], envDmx[2]; 574 575 INT cplxBands; 576 INT hybBands = self->hybridBands - 6; 577 578 cplxBands = self->hybridBands - 6; 579 580 /* extract downmix envelope(s) */ 581 switch (self->treeConfig) { 582 default: 583 extractBBEnv(self, INP_DMX, 0, fMin(self->numInputChannels, 2), envDmx, 584 frame); 585 } 586 587 /* extract dry and wet envelopes */ 588 extractBBEnv(self, INP_DRY_WET, 0, self->numOutputChannels, envDry, frame); 589 590 for (ch = 0; ch < self->numOutputChannels; ch++) { 591 INT ch2; 592 593 ch2 = row2channelGES[self->treeConfig][ch]; 594 595 if (ch2 == -1) continue; 596 597 if (frame->tempShapeEnableChannelGES[ch2]) { 598 INT sc; 599 600 /* reshape dry and wet signals according to transmitted envelope */ 601 602 /* De-quantize GES data */ 603 FDK_ASSERT((frame->bsEnvShapeData[ch2][ts] >= 0) && 604 (frame->bsEnvShapeData[ch2][ts] <= 4)); 605 FDK_ASSERT((self->envQuantMode == 0) || (self->envQuantMode == 1)); 606 envShape = 607 FX_CFG2FX_DBL(envShapeDataTable__FDK[frame->bsEnvShapeData[ch2][ts]] 608 [self->envQuantMode]); 609 610 /* get downmix channel */ 611 ch2 = self->row2channelDmxGES[ch]; 612 613 /* multiply ratio with dmx envelope; tmp is scaled by SF_DIV32/2+SF_SHAPE 614 * bits */ 615 if (ch2 == 2) { 616 tmp = fMultDiv2(envShape, envDmx[0]) + fMultDiv2(envShape, envDmx[1]); 617 } else { 618 tmp = fMult(envShape, envDmx[ch2]); 619 } 620 621 /* weighting factors */ 622 dryFacSF = slotAmpSF = 0; 623 dryFac = slotAmp_ratio = FL2FXCONST_DBL(0.0f); 624 625 /* dryFac will be scaled by dryFacSF bits */ 626 if (envDry[ch] != FL2FXCONST_DBL(0.0f)) { 627 envDry[ch] = invSqrtNorm2(envDry[ch], &dryFacSF); 628 dryFac = fMultDiv2(tmp, fPow2Div2(envDry[ch])) << 2; 629 dryFacSF = SF_SHAPE + 2 * dryFacSF; 630 } 631 632 /* calculate slotAmp_dry and slotAmp_wet */ 633 slotAmp(&slotAmp_dry, &slotAmp_wet, &self->hybOutputRealDry__FDK[ch][6], 634 &self->hybOutputImagDry__FDK[ch][6], 635 &self->hybOutputRealWet__FDK[ch][6], 636 &self->hybOutputImagWet__FDK[ch][6], cplxBands, hybBands); 637 638 /* slotAmp_ratio will be scaled by slotAmpSF bits */ 639 if (slotAmp_dry != FL2FXCONST_DBL(0.0f)) { 640 sc = fixMax(0, CntLeadingZeros(slotAmp_wet) - 1); 641 sc = sc - (sc & 1); 642 643 slotAmp_wet = sqrtFixp(slotAmp_wet << sc); 644 slotAmp_dry = invSqrtNorm2(slotAmp_dry, &slotAmpSF); 645 646 slotAmp_ratio = fMult(slotAmp_wet, slotAmp_dry); 647 slotAmpSF = slotAmpSF - (sc >> 1); 648 } 649 650 /* calculate common scale factor */ 651 scale = 652 fixMax(3, fixMax(dryFacSF, slotAmpSF)); /* scale is at least with 3 653 bits to avoid overflows 654 when calculating dryFac */ 655 dryFac = dryFac >> (scale - dryFacSF); 656 slotAmp_ratio = slotAmp_ratio >> (scale - slotAmpSF); 657 658 /* limit dryFac */ 659 dryFac = fixMax( 660 FL2FXCONST_DBL(0.25f) >> (INT)fixMin(2 * scale, DFRACT_BITS - 1), 661 fMult(dryFac, slotAmp_ratio) - (slotAmp_ratio >> scale) + 662 (dryFac >> scale)); 663 dryFac = fixMin( 664 FL2FXCONST_DBL(0.50f) >> (INT)fixMin(2 * scale - 3, DFRACT_BITS - 1), 665 dryFac); /* reduce shift bits by 3, because upper 666 limit 4.0 is scaled with 3 bits */ 667 scale = 2 * scale + 1; 668 669 /* improve precision for dryFac */ 670 sc = fixMax(0, CntLeadingZeros(dryFac) - 1); 671 dryFac = dryFac << (INT)fixMin(scale, sc); 672 scale = scale - fixMin(scale, sc); 673 674 /* shaping */ 675 shapeBBEnv(&self->hybOutputRealDry__FDK[ch][6], 676 &self->hybOutputImagDry__FDK[ch][6], dryFac, scale, cplxBands, 677 hybBands); 678 } 679 } 680 } 681