1/* ----------------------------------------------------------------------------- 2Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten 5Forschung e.V. All rights reserved. 6 7 1. INTRODUCTION 8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software 9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding 10scheme for digital audio. This FDK AAC Codec software is intended to be used on 11a wide variety of Android devices. 12 13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient 14general perceptual audio codecs. AAC-ELD is considered the best-performing 15full-bandwidth communications codec by independent studies and is widely 16deployed. AAC has been standardized by ISO and IEC as part of the MPEG 17specifications. 18 19Patent licenses for necessary patent claims for the FDK AAC Codec (including 20those of Fraunhofer) may be obtained through Via Licensing 21(www.vialicensing.com) or through the respective patent owners individually for 22the purpose of encoding or decoding bit streams in products that are compliant 23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of 24Android devices already license these patent claims through Via Licensing or 25directly from the patent owners, and therefore FDK AAC Codec software may 26already be covered under those patent licenses when it is used for those 27licensed purposes only. 28 29Commercially-licensed AAC software libraries, including floating-point versions 30with enhanced sound quality, are also available from Fraunhofer. Users are 31encouraged to check the Fraunhofer website for additional applications 32information and documentation. 33 342. COPYRIGHT LICENSE 35 36Redistribution and use in source and binary forms, with or without modification, 37are permitted without payment of copyright license fees provided that you 38satisfy the following conditions: 39 40You must retain the complete text of this software license in redistributions of 41the FDK AAC Codec or your modifications thereto in source code form. 42 43You must retain the complete text of this software license in the documentation 44and/or other materials provided with redistributions of the FDK AAC Codec or 45your modifications thereto in binary form. You must make available free of 46charge copies of the complete source code of the FDK AAC Codec and your 47modifications thereto to recipients of copies in binary form. 48 49The name of Fraunhofer may not be used to endorse or promote products derived 50from this library without prior written permission. 51 52You may not charge copyright license fees for anyone to use, copy or distribute 53the FDK AAC Codec software or your modifications thereto. 54 55Your modified versions of the FDK AAC Codec must carry prominent notices stating 56that you changed the software and the date of any change. For modified versions 57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android" 58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK 59AAC Codec Library for Android." 60 613. NO PATENT LICENSE 62 63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without 64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE. 65Fraunhofer provides no warranty of patent non-infringement with respect to this 66software. 67 68You may use this FDK AAC Codec software or modifications thereto only for 69purposes that are authorized by appropriate patent licenses. 70 714. DISCLAIMER 72 73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright 74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 75including but not limited to the implied warranties of merchantability and 76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, 78or consequential damages, including but not limited to procurement of substitute 79goods or services; loss of use, data, or profits, or business interruption, 80however caused and on any theory of liability, whether in contract, strict 81liability, or tort (including negligence), arising in any way out of the use of 82this software, even if advised of the possibility of such damage. 83 845. CONTACT INFORMATION 85 86Fraunhofer Institute for Integrated Circuits IIS 87Attention: Audio and Multimedia Departments - FDK AAC LL 88Am Wolfsmantel 33 8991058 Erlangen, Germany 90 91www.iis.fraunhofer.de/amm 92amm-info@iis.fraunhofer.de 93----------------------------------------------------------------------------- */ 94 95/*********************** MPEG surround decoder library ************************* 96 97 Author(s): 98 99 Description: SAC Dec subband processing 100 101*******************************************************************************/ 102 103#include "sac_stp.h" 104#include "sac_calcM1andM2.h" 105#include "sac_bitdec.h" 106#include "FDK_matrixCalloc.h" 107#include "sac_rom.h" 108 109#define BP_GF_START 6 110#define BP_GF_SIZE 25 111#define HP_SIZE 9 112#define STP_UPDATE_ENERGY_RATE 32 113 114#define SF_WET 5 115#define SF_DRY \ 116 3 /* SF_DRY == 2 would produce good conformance test results as well */ 117#define SF_PRODUCT_BP_GF 13 118#define SF_PRODUCT_BP_GF_GF 26 119#define SF_SCALE 2 120 121#define SF_SCALE_LD64 FL2FXCONST_DBL(0.03125) /* LD64((1<<SF_SCALE))*/ 122#define STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.950f) /* 0.95 */ 123#define ONE_MINUS_STP_LPF_COEFF1__FDK FL2FXCONST_DBL(0.05f) /* 1.0 - 0.95 */ 124#define STP_LPF_COEFF2__FDK FL2FXCONST_DBL(0.450f) /* 0.45 */ 125#define ONE_MINUS_STP_LPF_COEFF2__FDK \ 126 FL2FXCONST_DBL(1.0f - 0.450f) /* 1.0 - 0.45 */ 127#define STP_SCALE_LIMIT__FDK \ 128 FL2FXCONST_DBL(2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE */ 129#define ONE_DIV_STP_SCALE_LIMIT__FDK \ 130 FL2FXCONST_DBL(1.0f / 2.82f / (float)(1 << SF_SCALE)) /* scaled by SF_SCALE \ 131 */ 132#define ABS_THR__FDK \ 133 FL2FXCONST_DBL(ABS_THR / \ 134 ((float)(1 << (22 + 22 - 26)))) /* scaled by 18 bits */ 135#define ABS_THR2__FDK \ 136 FL2FXCONST_DBL(ABS_THR * 32.0f * 32.0f / \ 137 ((float)(1 << (22 + 22 - 26)))) /* scaled by 10 bits */ 138#define STP_SCALE_LIMIT_HI \ 139 FL2FXCONST_DBL(3.02222222222 / (1 << SF_SCALE)) /* see 4. below */ 140#define STP_SCALE_LIMIT_LO \ 141 FL2FXCONST_DBL(0.28289992119 / (1 << SF_SCALE)) /* see 4. below */ 142#define STP_SCALE_LIMIT_HI_LD64 \ 143 FL2FXCONST_DBL(0.04986280452) /* see 4. below \ 144 */ 145#define STP_SCALE_LIMIT_LO_LD64 \ 146 FL2FXCONST_DBL(0.05692613500) /* see 4. below \ 147 */ 148 149/* Scale factor calculation for the diffuse signal needs adapted thresholds 150 for STP_SCALE_LIMIT and 1/STP_SCALE_LIMIT: 151 152 1. scale = sqrt(DryNrg/WetNrg) 153 154 2. Damping of scale factor 155 scale2 = 0.1 + 0.9 * scale 156 157 3. Limiting of scale factor 158 STP_SCALE_LIMIT >= scale2 >= 1/STP_SCALE_LIMIT 159 => STP_SCALE_LIMIT >= (0.1 + 0.9 * scale) >= 1/STP_SCALE_LIMIT 160 => (STP_SCALE_LIMIT-0.1)/0.9 >= scale >= 161 (1/STP_SCALE_LIMIT-0.1)/0.9 162 163 3. Limiting of scale factor before sqrt calculation 164 ((STP_SCALE_LIMIT-0.1)/0.9)^2 >= (scale^2) >= 165 ((1/STP_SCALE_LIMIT-0.1)/0.9)^2 (STP_SCALE_LIMIT_HI)^2 >= (scale^2) >= 166 (STP_SCALE_LIMIT_LO)^2 167 168 4. Thresholds for limiting of scale factor 169 STP_SCALE_LIMIT_HI = ((2.82-0.1)/0.9) 170 STP_SCALE_LIMIT_LO = (((1.0/2.82)-0.1)/0.9) 171 STP_SCALE_LIMIT_HI_LD64 = LD64(STP_SCALE_LIMIT_HI*STP_SCALE_LIMIT_HI) 172 STP_SCALE_LIMIT_LO_LD64 = LD64(STP_SCALE_LIMIT_LO*STP_SCALE_LIMIT_LO) 173*/ 174 175#define DRY_ENER_WEIGHT(DryEner) DryEner = DryEner >> dry_scale_dmx 176 177#define WET_ENER_WEIGHT(WetEner) WetEner = WetEner << wet_scale_dmx 178 179#define DRY_ENER_SUM_REAL(DryEner, dmxReal, n) \ 180 DryEner += \ 181 fMultDiv2(fPow2Div2(dmxReal << SF_DRY), pBP[n]) >> ((2 * SF_DRY) - 2) 182 183#define DRY_ENER_SUM_CPLX(DryEner, dmxReal, dmxImag, n) \ 184 DryEner += fMultDiv2( \ 185 fPow2Div2(dmxReal << SF_DRY) + fPow2Div2(dmxImag << SF_DRY), pBP[n]) 186 187#define CALC_WET_SCALE(dryIdx, wetIdx) \ 188 if ((DryEnerLD64[dryIdx] - STP_SCALE_LIMIT_HI_LD64) > WetEnerLD64[wetIdx]) { \ 189 scale[wetIdx] = STP_SCALE_LIMIT_HI; \ 190 } else if (DryEnerLD64[dryIdx] < \ 191 (WetEnerLD64[wetIdx] - STP_SCALE_LIMIT_LO_LD64)) { \ 192 scale[wetIdx] = STP_SCALE_LIMIT_LO; \ 193 } else { \ 194 tmp = ((DryEnerLD64[dryIdx] - WetEnerLD64[wetIdx]) >> 1) - SF_SCALE_LD64; \ 195 scale[wetIdx] = CalcInvLdData(tmp); \ 196 } 197 198struct STP_DEC { 199 FIXP_DBL runDryEner[MAX_INPUT_CHANNELS]; 200 FIXP_DBL runWetEner[MAX_OUTPUT_CHANNELS]; 201 FIXP_DBL oldDryEnerLD64[MAX_INPUT_CHANNELS]; 202 FIXP_DBL oldWetEnerLD64[MAX_OUTPUT_CHANNELS]; 203 FIXP_DBL prev_tp_scale[MAX_OUTPUT_CHANNELS]; 204 const FIXP_CFG *BP; 205 const FIXP_CFG *BP_GF; 206 int update_old_ener; 207}; 208 209inline void combineSignalReal(FIXP_DBL *hybOutputRealDry, 210 FIXP_DBL *hybOutputRealWet, int bands) { 211 int n; 212 213 for (n = bands - 1; n >= 0; n--) { 214 *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet; 215 hybOutputRealDry++, hybOutputRealWet++; 216 } 217} 218 219inline void combineSignalRealScale1(FIXP_DBL *hybOutputRealDry, 220 FIXP_DBL *hybOutputRealWet, FIXP_DBL scaleX, 221 int bands) { 222 int n; 223 224 for (n = bands - 1; n >= 0; n--) { 225 *hybOutputRealDry = 226 *hybOutputRealDry + 227 (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1)); 228 hybOutputRealDry++, hybOutputRealWet++; 229 } 230} 231 232inline void combineSignalCplx(FIXP_DBL *hybOutputRealDry, 233 FIXP_DBL *hybOutputImagDry, 234 FIXP_DBL *hybOutputRealWet, 235 FIXP_DBL *hybOutputImagWet, int bands) { 236 int n; 237 238 for (n = bands - 1; n >= 0; n--) { 239 *hybOutputRealDry = *hybOutputRealDry + *hybOutputRealWet; 240 *hybOutputImagDry = *hybOutputImagDry + *hybOutputImagWet; 241 hybOutputRealDry++, hybOutputRealWet++; 242 hybOutputImagDry++, hybOutputImagWet++; 243 } 244} 245 246inline void combineSignalCplxScale1(FIXP_DBL *hybOutputRealDry, 247 FIXP_DBL *hybOutputImagDry, 248 FIXP_DBL *hybOutputRealWet, 249 FIXP_DBL *hybOutputImagWet, 250 const FIXP_CFG *pBP, FIXP_DBL scaleX, 251 int bands) { 252 int n; 253 FIXP_DBL scaleY; 254 for (n = bands - 1; n >= 0; n--) { 255 scaleY = fMultDiv2(scaleX, *pBP); 256 *hybOutputRealDry = 257 *hybOutputRealDry + 258 (fMultDiv2(*hybOutputRealWet, scaleY) << (SF_SCALE + 2)); 259 *hybOutputImagDry = 260 *hybOutputImagDry + 261 (fMultDiv2(*hybOutputImagWet, scaleY) << (SF_SCALE + 2)); 262 hybOutputRealDry++, hybOutputRealWet++; 263 hybOutputImagDry++, hybOutputImagWet++; 264 pBP++; 265 } 266} 267 268inline void combineSignalCplxScale2(FIXP_DBL *hybOutputRealDry, 269 FIXP_DBL *hybOutputImagDry, 270 FIXP_DBL *hybOutputRealWet, 271 FIXP_DBL *hybOutputImagWet, FIXP_DBL scaleX, 272 int bands) { 273 int n; 274 275 for (n = bands - 1; n >= 0; n--) { 276 *hybOutputRealDry = 277 *hybOutputRealDry + 278 (fMultDiv2(*hybOutputRealWet, scaleX) << (SF_SCALE + 1)); 279 *hybOutputImagDry = 280 *hybOutputImagDry + 281 (fMultDiv2(*hybOutputImagWet, scaleX) << (SF_SCALE + 1)); 282 hybOutputRealDry++, hybOutputRealWet++; 283 hybOutputImagDry++, hybOutputImagWet++; 284 } 285} 286 287/******************************************************************************* 288 Functionname: subbandTPCreate 289 ******************************************************************************/ 290SACDEC_ERROR subbandTPCreate(HANDLE_STP_DEC *hStpDec) { 291 HANDLE_STP_DEC self = NULL; 292 FDK_ALLOCATE_MEMORY_1D(self, 1, struct STP_DEC) 293 if (hStpDec != NULL) { 294 *hStpDec = self; 295 } 296 297 return MPS_OK; 298bail: 299 return MPS_OUTOFMEMORY; 300} 301 302SACDEC_ERROR subbandTPInit(HANDLE_STP_DEC self) { 303 SACDEC_ERROR err = MPS_OK; 304 int ch; 305 306 for (ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++) { 307 self->prev_tp_scale[ch] = FL2FXCONST_DBL(1.0f / (1 << SF_SCALE)); 308 self->oldWetEnerLD64[ch] = 309 FL2FXCONST_DBL(0.34375f); /* 32768.0*32768.0/2^(44-26-10) */ 310 } 311 for (ch = 0; ch < MAX_INPUT_CHANNELS; ch++) { 312 self->oldDryEnerLD64[ch] = 313 FL2FXCONST_DBL(0.1875f); /* 32768.0*32768.0/2^(44-26) */ 314 } 315 316 self->BP = BP__FDK; 317 self->BP_GF = BP_GF__FDK; 318 319 self->update_old_ener = 0; 320 321 return err; 322} 323 324/******************************************************************************* 325 Functionname: subbandTPDestroy 326 ******************************************************************************/ 327void subbandTPDestroy(HANDLE_STP_DEC *hStpDec) { 328 if (hStpDec != NULL) { 329 FDK_FREE_MEMORY_1D(*hStpDec); 330 } 331} 332 333/******************************************************************************* 334 Functionname: subbandTPApply 335 ******************************************************************************/ 336SACDEC_ERROR subbandTPApply(spatialDec *self, const SPATIAL_BS_FRAME *frame) { 337 FIXP_DBL *qmfOutputRealDry[MAX_OUTPUT_CHANNELS]; 338 FIXP_DBL *qmfOutputImagDry[MAX_OUTPUT_CHANNELS]; 339 FIXP_DBL *qmfOutputRealWet[MAX_OUTPUT_CHANNELS]; 340 FIXP_DBL *qmfOutputImagWet[MAX_OUTPUT_CHANNELS]; 341 342 FIXP_DBL DryEner[MAX_INPUT_CHANNELS]; 343 FIXP_DBL scale[MAX_OUTPUT_CHANNELS]; 344 345 FIXP_DBL DryEnerLD64[MAX_INPUT_CHANNELS]; 346 FIXP_DBL WetEnerLD64[MAX_OUTPUT_CHANNELS]; 347 348 FIXP_DBL DryEner0 = FL2FXCONST_DBL(0.0f); 349 FIXP_DBL WetEnerX, damp, tmp; 350 FIXP_DBL dmxReal0, dmxImag0; 351 int skipChannels[MAX_OUTPUT_CHANNELS]; 352 int n, ch, cplxBands, cplxHybBands; 353 int dry_scale_dmx, wet_scale_dmx; 354 int i_LF, i_RF; 355 HANDLE_STP_DEC hStpDec; 356 const FIXP_CFG *pBP; 357 358 int nrgScale = (2 * self->clipProtectGainSF__FDK); 359 360 hStpDec = self->hStpDec; 361 362 /* set scalefactor and loop counter */ 363 FDK_ASSERT(SF_DRY >= 1); 364 { 365 cplxBands = BP_GF_SIZE; 366 cplxHybBands = self->hybridBands; 367 dry_scale_dmx = (2 * SF_DRY) - 2; 368 wet_scale_dmx = 2; 369 } 370 371 /* setup pointer for forming the direct downmix signal */ 372 for (ch = 0; ch < self->numOutputChannels; ch++) { 373 qmfOutputRealDry[ch] = &self->hybOutputRealDry__FDK[ch][7]; 374 qmfOutputRealWet[ch] = &self->hybOutputRealWet__FDK[ch][7]; 375 qmfOutputImagDry[ch] = &self->hybOutputImagDry__FDK[ch][7]; 376 qmfOutputImagWet[ch] = &self->hybOutputImagWet__FDK[ch][7]; 377 } 378 379 /* clear skipping flag for all output channels */ 380 FDKmemset(skipChannels, 0, self->numOutputChannels * sizeof(int)); 381 382 /* set scale values to zero */ 383 FDKmemset(scale, 0, self->numOutputChannels * sizeof(FIXP_DBL)); 384 385 /* update normalisation energy with latest smoothed energy */ 386 if (hStpDec->update_old_ener == STP_UPDATE_ENERGY_RATE) { 387 hStpDec->update_old_ener = 1; 388 for (ch = 0; ch < self->numInputChannels; ch++) { 389 hStpDec->oldDryEnerLD64[ch] = 390 CalcLdData(hStpDec->runDryEner[ch] + ABS_THR__FDK); 391 } 392 for (ch = 0; ch < self->numOutputChannels; ch++) { 393 hStpDec->oldWetEnerLD64[ch] = 394 CalcLdData(hStpDec->runWetEner[ch] + ABS_THR2__FDK); 395 } 396 } else { 397 hStpDec->update_old_ener++; 398 } 399 400 /* get channel configuration */ 401 switch (self->treeConfig) { 402 case TREE_212: 403 i_LF = 0; 404 i_RF = 1; 405 break; 406 default: 407 return MPS_WRONG_TREECONFIG; 408 } 409 410 /* form the 'direct' downmix signal */ 411 pBP = hStpDec->BP_GF - BP_GF_START; 412 switch (self->treeConfig) { 413 case TREE_212: 414 for (n = BP_GF_START; n < cplxBands; n++) { 415 dmxReal0 = qmfOutputRealDry[i_LF][n] + qmfOutputRealDry[i_RF][n]; 416 dmxImag0 = qmfOutputImagDry[i_LF][n] + qmfOutputImagDry[i_RF][n]; 417 DRY_ENER_SUM_CPLX(DryEner0, dmxReal0, dmxImag0, n); 418 } 419 DRY_ENER_WEIGHT(DryEner0); 420 break; 421 default:; 422 } 423 DryEner[0] = DryEner0; 424 425 /* normalise the 'direct' signals */ 426 for (ch = 0; ch < self->numInputChannels; ch++) { 427 DryEner[ch] = DryEner[ch] << (nrgScale); 428 hStpDec->runDryEner[ch] = 429 fMult(STP_LPF_COEFF1__FDK, hStpDec->runDryEner[ch]) + 430 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, DryEner[ch]); 431 if (DryEner[ch] != FL2FXCONST_DBL(0.0f)) { 432 DryEnerLD64[ch] = 433 fixMax((CalcLdData(DryEner[ch]) - hStpDec->oldDryEnerLD64[ch]), 434 FL2FXCONST_DBL(-0.484375f)); 435 } else { 436 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); 437 } 438 } 439 if (self->treeConfig == TREE_212) { 440 for (; ch < MAX_INPUT_CHANNELS; ch++) { 441 DryEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); 442 } 443 } 444 445 /* normalise the 'diffuse' signals */ 446 pBP = hStpDec->BP_GF - BP_GF_START; 447 for (ch = 0; ch < self->numOutputChannels; ch++) { 448 if (skipChannels[ch]) { 449 continue; 450 } 451 452 WetEnerX = FL2FXCONST_DBL(0.0f); 453 for (n = BP_GF_START; n < cplxBands; n++) { 454 tmp = fPow2Div2(qmfOutputRealWet[ch][n] << SF_WET); 455 tmp += fPow2Div2(qmfOutputImagWet[ch][n] << SF_WET); 456 WetEnerX += fMultDiv2(tmp, pBP[n]); 457 } 458 WET_ENER_WEIGHT(WetEnerX); 459 460 WetEnerX = WetEnerX << (nrgScale); 461 hStpDec->runWetEner[ch] = 462 fMult(STP_LPF_COEFF1__FDK, hStpDec->runWetEner[ch]) + 463 fMult(ONE_MINUS_STP_LPF_COEFF1__FDK, WetEnerX); 464 465 if (WetEnerX == FL2FXCONST_DBL(0.0f)) { 466 WetEnerLD64[ch] = FL2FXCONST_DBL(-0.484375f); 467 } else { 468 WetEnerLD64[ch] = 469 fixMax((CalcLdData(WetEnerX) - hStpDec->oldWetEnerLD64[ch]), 470 FL2FXCONST_DBL(-0.484375f)); 471 } 472 } 473 474 /* compute scale factor for the 'diffuse' signals */ 475 switch (self->treeConfig) { 476 case TREE_212: 477 if (DryEner[0] != FL2FXCONST_DBL(0.0f)) { 478 CALC_WET_SCALE(0, i_LF); 479 CALC_WET_SCALE(0, i_RF); 480 } 481 break; 482 default:; 483 } 484 485 damp = FL2FXCONST_DBL(0.1f / (1 << SF_SCALE)); 486 for (ch = 0; ch < self->numOutputChannels; ch++) { 487 /* damp the scaling factor */ 488 scale[ch] = damp + fMult(FL2FXCONST_DBL(0.9f), scale[ch]); 489 490 /* limiting the scale factor */ 491 if (scale[ch] > STP_SCALE_LIMIT__FDK) { 492 scale[ch] = STP_SCALE_LIMIT__FDK; 493 } 494 if (scale[ch] < ONE_DIV_STP_SCALE_LIMIT__FDK) { 495 scale[ch] = ONE_DIV_STP_SCALE_LIMIT__FDK; 496 } 497 498 /* low pass filter the scaling factor */ 499 scale[ch] = 500 fMult(STP_LPF_COEFF2__FDK, scale[ch]) + 501 fMult(ONE_MINUS_STP_LPF_COEFF2__FDK, hStpDec->prev_tp_scale[ch]); 502 hStpDec->prev_tp_scale[ch] = scale[ch]; 503 } 504 505 /* combine 'direct' and scaled 'diffuse' signal */ 506 FDK_ASSERT((HP_SIZE - 3 + 10 - 1) == PC_NUM_HYB_BANDS); 507 const SCHAR *channlIndex = row2channelSTP[self->treeConfig]; 508 509 for (ch = 0; ch < self->numOutputChannels; ch++) { 510 int no_scaling; 511 512 no_scaling = !frame->tempShapeEnableChannelSTP[channlIndex[ch]]; 513 if (no_scaling) { 514 combineSignalCplx( 515 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder], 516 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder], 517 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder], 518 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder], 519 cplxHybBands - self->tp_hybBandBorder); 520 521 } else { 522 FIXP_DBL scaleX; 523 scaleX = scale[ch]; 524 pBP = hStpDec->BP - self->tp_hybBandBorder; 525 /* Band[HP_SIZE-3+10-1] needs not to be processed in 526 combineSignalCplxScale1(), because pB[HP_SIZE-3+10-1] would be 1.0 */ 527 combineSignalCplxScale1( 528 &self->hybOutputRealDry__FDK[ch][self->tp_hybBandBorder], 529 &self->hybOutputImagDry__FDK[ch][self->tp_hybBandBorder], 530 &self->hybOutputRealWet__FDK[ch][self->tp_hybBandBorder], 531 &self->hybOutputImagWet__FDK[ch][self->tp_hybBandBorder], 532 &pBP[self->tp_hybBandBorder], scaleX, 533 (HP_SIZE - 3 + 10 - 1) - self->tp_hybBandBorder); 534 535 { 536 combineSignalCplxScale2( 537 &self->hybOutputRealDry__FDK[ch][HP_SIZE - 3 + 10 - 1], 538 &self->hybOutputImagDry__FDK[ch][HP_SIZE - 3 + 10 - 1], 539 &self->hybOutputRealWet__FDK[ch][HP_SIZE - 3 + 10 - 1], 540 &self->hybOutputImagWet__FDK[ch][HP_SIZE - 3 + 10 - 1], scaleX, 541 cplxHybBands - (HP_SIZE - 3 + 10 - 1)); 542 } 543 } 544 } 545 546 return (SACDEC_ERROR)MPS_OK; 547 ; 548} 549