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 /**************************** SBR encoder library ****************************** 96 97 Author(s): M. Neuendorf, N. Rettelbach, M. Multrus 98 99 Description: PS parameter extraction, encoding 100 101 *******************************************************************************/ 102 103 /*! 104 \file 105 \brief PS parameter extraction, encoding functions $Revision: 96441 $ 106 */ 107 108 #include "ps_main.h" 109 #include "ps_encode.h" 110 #include "qmf.h" 111 #include "sbr_misc.h" 112 #include "sbrenc_ram.h" 113 114 #include "genericStds.h" 115 116 inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL *X, const FIXP_DBL *Y, 117 FIXP_DBL *Z, INT n) { 118 for (INT i = 0; i < n; i++) Z[i] = (X[i] >> 1) + (Y[i] >> 1); 119 } 120 121 #define LOG10_2_10 3.01029995664f /* 10.0f*log10(2.f) */ 122 123 static const INT 124 iidGroupBordersLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES + 1] = { 125 0, 1, 2, 3, 4, 5, /* 6 subqmf subbands - 0th qmf subband */ 126 6, 7, /* 2 subqmf subbands - 1st qmf subband */ 127 8, 9, /* 2 subqmf subbands - 2nd qmf subband */ 128 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71}; 129 130 static const UCHAR 131 iidGroupWidthLdLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = { 132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5}; 133 134 static const INT subband2parameter20[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = 135 {1, 0, 0, 1, 2, 3, /* 6 subqmf subbands - 0th qmf subband */ 136 4, 5, /* 2 subqmf subbands - 1st qmf subband */ 137 6, 7, /* 2 subqmf subbands - 2nd qmf subband */ 138 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; 139 140 typedef enum { 141 MAX_TIME_DIFF_FRAMES = 20, 142 MAX_PS_NOHEADER_CNT = 10, 143 MAX_NOENV_CNT = 10, 144 DO_NOT_USE_THIS_MODE = 0x7FFFFF 145 } __PS_CONSTANTS; 146 147 static const FIXP_DBL iidQuant_fx[15] = { 148 (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000, 149 (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000, 150 (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, 151 (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000, 152 (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000}; 153 154 static const FIXP_DBL iidQuantFine_fx[31] = { 155 (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001, 156 (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000, 157 (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000, (FIXP_DBL)0xe0000000, 158 (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000, 159 (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, 160 (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, 161 (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000, 162 (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000, 163 (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000, 164 (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff, 165 (FIXP_DBL)0x63ffffff}; 166 167 static const FIXP_DBL iccQuant[8] = { 168 (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f, 169 (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000, 170 (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000}; 171 172 static FDK_PSENC_ERROR InitPSData(HANDLE_PS_DATA hPsData) { 173 FDK_PSENC_ERROR error = PSENC_OK; 174 175 if (hPsData == NULL) { 176 error = PSENC_INVALID_HANDLE; 177 } else { 178 int i, env; 179 FDKmemclear(hPsData, sizeof(PS_DATA)); 180 181 for (i = 0; i < PS_MAX_BANDS; i++) { 182 hPsData->iidIdxLast[i] = 0; 183 hPsData->iccIdxLast[i] = 0; 184 } 185 186 hPsData->iidEnable = hPsData->iidEnableLast = 0; 187 hPsData->iccEnable = hPsData->iccEnableLast = 0; 188 hPsData->iidQuantMode = hPsData->iidQuantModeLast = PS_IID_RES_COARSE; 189 hPsData->iccQuantMode = hPsData->iccQuantModeLast = PS_ICC_ROT_A; 190 191 for (env = 0; env < PS_MAX_ENVELOPES; env++) { 192 hPsData->iccDiffMode[env] = PS_DELTA_FREQ; 193 hPsData->iccDiffMode[env] = PS_DELTA_FREQ; 194 195 for (i = 0; i < PS_MAX_BANDS; i++) { 196 hPsData->iidIdx[env][i] = 0; 197 hPsData->iccIdx[env][i] = 0; 198 } 199 } 200 201 hPsData->nEnvelopesLast = 0; 202 203 hPsData->headerCnt = MAX_PS_NOHEADER_CNT; 204 hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; 205 hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; 206 hPsData->noEnvCnt = MAX_NOENV_CNT; 207 } 208 209 return error; 210 } 211 212 static FIXP_DBL quantizeCoef(const FIXP_DBL *RESTRICT input, const INT nBands, 213 const FIXP_DBL *RESTRICT quantTable, 214 const INT idxOffset, const INT nQuantSteps, 215 INT *RESTRICT quantOut) { 216 INT idx, band; 217 FIXP_DBL quantErr = FL2FXCONST_DBL(0.f); 218 219 for (band = 0; band < nBands; band++) { 220 for (idx = 0; idx < nQuantSteps - 1; idx++) { 221 if (fixp_abs((input[band] >> 1) - (quantTable[idx + 1] >> 1)) > 222 fixp_abs((input[band] >> 1) - (quantTable[idx] >> 1))) { 223 break; 224 } 225 } 226 quantErr += (fixp_abs(input[band] - quantTable[idx]) >> 227 PS_QUANT_SCALE); /* don't scale before subtraction; diff 228 smaller (64-25)/64 */ 229 quantOut[band] = idx - idxOffset; 230 } 231 232 return quantErr; 233 } 234 235 static INT getICCMode(const INT nBands, const INT rotType) { 236 INT mode = 0; 237 238 switch (nBands) { 239 case PS_BANDS_COARSE: 240 mode = PS_RES_COARSE; 241 break; 242 case PS_BANDS_MID: 243 mode = PS_RES_MID; 244 break; 245 default: 246 mode = 0; 247 } 248 if (rotType == PS_ICC_ROT_B) { 249 mode += 3; 250 } 251 252 return mode; 253 } 254 255 static INT getIIDMode(const INT nBands, const INT iidRes) { 256 INT mode = 0; 257 258 switch (nBands) { 259 case PS_BANDS_COARSE: 260 mode = PS_RES_COARSE; 261 break; 262 case PS_BANDS_MID: 263 mode = PS_RES_MID; 264 break; 265 default: 266 mode = 0; 267 break; 268 } 269 270 if (iidRes == PS_IID_RES_FINE) { 271 mode += 3; 272 } 273 274 return mode; 275 } 276 277 static INT envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], 278 FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], 279 INT psBands, INT nEnvelopes) { 280 #define THRESH_SCALE 7 281 282 INT reducible = 1; /* true */ 283 INT e = 0, b = 0; 284 FIXP_DBL dIid = FL2FXCONST_DBL(0.f); 285 FIXP_DBL dIcc = FL2FXCONST_DBL(0.f); 286 287 FIXP_DBL iidErrThreshold, iccErrThreshold; 288 FIXP_DBL iidMeanError, iccMeanError; 289 290 /* square values to prevent sqrt, 291 multiply bands to prevent division; bands shifted DFRACT_BITS instead 292 (DFRACT_BITS-1) because fMultDiv2 used*/ 293 iidErrThreshold = 294 fMultDiv2(FL2FXCONST_DBL(6.5f * 6.5f / (IID_SCALE_FT * IID_SCALE_FT)), 295 (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE))); 296 iccErrThreshold = 297 fMultDiv2(FL2FXCONST_DBL(0.75f * 0.75f), 298 (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE))); 299 300 if (nEnvelopes <= 1) { 301 reducible = 0; 302 } else { 303 /* mean error criterion */ 304 for (e = 0; (e < nEnvelopes / 2) && (reducible != 0); e++) { 305 iidMeanError = iccMeanError = FL2FXCONST_DBL(0.f); 306 for (b = 0; b < psBands; b++) { 307 dIid = (iid[2 * e][b] >> 1) - 308 (iid[2 * e + 1][b] >> 1); /* scale 1 bit; squared -> 2 bit */ 309 dIcc = (icc[2 * e][b] >> 1) - (icc[2 * e + 1][b] >> 1); 310 iidMeanError += fPow2Div2(dIid) >> (5 - 1); /* + (bands=20) scale = 5 */ 311 iccMeanError += fPow2Div2(dIcc) >> (5 - 1); 312 } /* --> scaling = 7 bit = THRESH_SCALE !! */ 313 314 /* instead sqrt values are squared! 315 instead of division, multiply threshold with psBands 316 scaling necessary!! */ 317 318 /* quit as soon as threshold is reached */ 319 if ((iidMeanError > (iidErrThreshold)) || 320 (iccMeanError > (iccErrThreshold))) { 321 reducible = 0; 322 } 323 } 324 } /* nEnvelopes != 1 */ 325 326 return reducible; 327 } 328 329 static void processIidData(PS_DATA *psData, 330 FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], 331 const INT psBands, const INT nEnvelopes, 332 const FIXP_DBL quantErrorThreshold) { 333 INT iidIdxFine[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 334 INT iidIdxCoarse[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 335 336 FIXP_DBL errIID = FL2FXCONST_DBL(0.f); 337 FIXP_DBL errIIDFine = FL2FXCONST_DBL(0.f); 338 INT bitsIidFreq = 0; 339 INT bitsIidTime = 0; 340 INT bitsFineTot = 0; 341 INT bitsCoarseTot = 0; 342 INT error = 0; 343 INT env, band; 344 INT diffMode[PS_MAX_ENVELOPES], diffModeFine[PS_MAX_ENVELOPES]; 345 INT loudnDiff = 0; 346 INT iidTransmit = 0; 347 348 /* Quantize IID coefficients */ 349 for (env = 0; env < nEnvelopes; env++) { 350 errIID += 351 quantizeCoef(iid[env], psBands, iidQuant_fx, 7, 15, iidIdxCoarse[env]); 352 errIIDFine += quantizeCoef(iid[env], psBands, iidQuantFine_fx, 15, 31, 353 iidIdxFine[env]); 354 } 355 356 /* normalize error to number of envelopes, ps bands 357 errIID /= psBands*nEnvelopes; 358 errIIDFine /= psBands*nEnvelopes; */ 359 360 /* Check if IID coefficients should be used in this frame */ 361 psData->iidEnable = 0; 362 for (env = 0; env < nEnvelopes; env++) { 363 for (band = 0; band < psBands; band++) { 364 loudnDiff += fixp_abs(iidIdxCoarse[env][band]); 365 iidTransmit++; 366 } 367 } 368 369 if (loudnDiff > 370 fMultI(FL2FXCONST_DBL(0.7f), iidTransmit)) { /* 0.7f empiric value */ 371 psData->iidEnable = 1; 372 } 373 374 /* if iid not active -> RESET data */ 375 if (psData->iidEnable == 0) { 376 psData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; 377 for (env = 0; env < nEnvelopes; env++) { 378 psData->iidDiffMode[env] = PS_DELTA_FREQ; 379 FDKmemclear(psData->iidIdx[env], sizeof(INT) * psBands); 380 } 381 return; 382 } 383 384 /* count COARSE quantization bits for first envelope*/ 385 bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], NULL, psBands, 386 PS_IID_RES_COARSE, PS_DELTA_FREQ, &error); 387 388 if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) || 389 (psData->iidQuantModeLast == PS_IID_RES_FINE)) { 390 bitsIidTime = DO_NOT_USE_THIS_MODE; 391 } else { 392 bitsIidTime = 393 FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], psData->iidIdxLast, psBands, 394 PS_IID_RES_COARSE, PS_DELTA_TIME, &error); 395 } 396 397 /* decision DELTA_FREQ vs DELTA_TIME */ 398 if (bitsIidTime > bitsIidFreq) { 399 diffMode[0] = PS_DELTA_FREQ; 400 bitsCoarseTot = bitsIidFreq; 401 } else { 402 diffMode[0] = PS_DELTA_TIME; 403 bitsCoarseTot = bitsIidTime; 404 } 405 406 /* count COARSE quantization bits for following envelopes*/ 407 for (env = 1; env < nEnvelopes; env++) { 408 bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], NULL, psBands, 409 PS_IID_RES_COARSE, PS_DELTA_FREQ, &error); 410 bitsIidTime = 411 FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], iidIdxCoarse[env - 1], 412 psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error); 413 414 /* decision DELTA_FREQ vs DELTA_TIME */ 415 if (bitsIidTime > bitsIidFreq) { 416 diffMode[env] = PS_DELTA_FREQ; 417 bitsCoarseTot += bitsIidFreq; 418 } else { 419 diffMode[env] = PS_DELTA_TIME; 420 bitsCoarseTot += bitsIidTime; 421 } 422 } 423 424 /* count FINE quantization bits for first envelope*/ 425 bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], NULL, psBands, 426 PS_IID_RES_FINE, PS_DELTA_FREQ, &error); 427 428 if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) || 429 (psData->iidQuantModeLast == PS_IID_RES_COARSE)) { 430 bitsIidTime = DO_NOT_USE_THIS_MODE; 431 } else { 432 bitsIidTime = 433 FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], psData->iidIdxLast, psBands, 434 PS_IID_RES_FINE, PS_DELTA_TIME, &error); 435 } 436 437 /* decision DELTA_FREQ vs DELTA_TIME */ 438 if (bitsIidTime > bitsIidFreq) { 439 diffModeFine[0] = PS_DELTA_FREQ; 440 bitsFineTot = bitsIidFreq; 441 } else { 442 diffModeFine[0] = PS_DELTA_TIME; 443 bitsFineTot = bitsIidTime; 444 } 445 446 /* count FINE quantization bits for following envelopes*/ 447 for (env = 1; env < nEnvelopes; env++) { 448 bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], NULL, psBands, 449 PS_IID_RES_FINE, PS_DELTA_FREQ, &error); 450 bitsIidTime = 451 FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], iidIdxFine[env - 1], psBands, 452 PS_IID_RES_FINE, PS_DELTA_TIME, &error); 453 454 /* decision DELTA_FREQ vs DELTA_TIME */ 455 if (bitsIidTime > bitsIidFreq) { 456 diffModeFine[env] = PS_DELTA_FREQ; 457 bitsFineTot += bitsIidFreq; 458 } else { 459 diffModeFine[env] = PS_DELTA_TIME; 460 bitsFineTot += bitsIidTime; 461 } 462 } 463 464 if (bitsFineTot == bitsCoarseTot) { 465 /* if same number of bits is needed, use the quantization with lower error 466 */ 467 if (errIIDFine < errIID) { 468 bitsCoarseTot = DO_NOT_USE_THIS_MODE; 469 } else { 470 bitsFineTot = DO_NOT_USE_THIS_MODE; 471 } 472 } else { 473 /* const FIXP_DBL minThreshold = 474 * FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes)); 475 */ 476 const FIXP_DBL minThreshold = 477 (FIXP_DBL)((LONG)0x00019999 * (psBands * nEnvelopes)); 478 479 /* decision RES_FINE vs RES_COARSE */ 480 /* test if errIIDFine*quantErrorThreshold < errIID */ 481 /* shiftVal 2 comes from scaling of quantErrorThreshold */ 482 if (fixMax(((errIIDFine >> 1) + (minThreshold >> 1)) >> 1, 483 fMult(quantErrorThreshold, errIIDFine)) < (errIID >> 2)) { 484 bitsCoarseTot = DO_NOT_USE_THIS_MODE; 485 } else if (fixMax(((errIID >> 1) + (minThreshold >> 1)) >> 1, 486 fMult(quantErrorThreshold, errIID)) < (errIIDFine >> 2)) { 487 bitsFineTot = DO_NOT_USE_THIS_MODE; 488 } 489 } 490 491 /* decision RES_FINE vs RES_COARSE */ 492 if (bitsFineTot < bitsCoarseTot) { 493 psData->iidQuantMode = PS_IID_RES_FINE; 494 for (env = 0; env < nEnvelopes; env++) { 495 psData->iidDiffMode[env] = diffModeFine[env]; 496 FDKmemcpy(psData->iidIdx[env], iidIdxFine[env], psBands * sizeof(INT)); 497 } 498 } else { 499 psData->iidQuantMode = PS_IID_RES_COARSE; 500 for (env = 0; env < nEnvelopes; env++) { 501 psData->iidDiffMode[env] = diffMode[env]; 502 FDKmemcpy(psData->iidIdx[env], iidIdxCoarse[env], psBands * sizeof(INT)); 503 } 504 } 505 506 /* Count DELTA_TIME encoding streaks */ 507 for (env = 0; env < nEnvelopes; env++) { 508 if (psData->iidDiffMode[env] == PS_DELTA_TIME) 509 psData->iidTimeCnt++; 510 else 511 psData->iidTimeCnt = 0; 512 } 513 } 514 515 static INT similarIid(PS_DATA *psData, const INT psBands, 516 const INT nEnvelopes) { 517 const INT diffThr = (psData->iidQuantMode == PS_IID_RES_COARSE) ? 2 : 3; 518 const INT sumDiffThr = diffThr * psBands / 4; 519 INT similar = 0; 520 INT diff = 0; 521 INT sumDiff = 0; 522 INT env = 0; 523 INT b = 0; 524 if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) { 525 similar = 1; 526 for (env = 0; env < nEnvelopes; env++) { 527 sumDiff = 0; 528 b = 0; 529 do { 530 diff = fixp_abs(psData->iidIdx[env][b] - psData->iidIdxLast[b]); 531 sumDiff += diff; 532 if ((diff > diffThr) /* more than x quantization steps in any band */ 533 || (sumDiff > sumDiffThr)) { /* more than x quantisations steps 534 overall difference */ 535 similar = 0; 536 } 537 b++; 538 } while ((b < psBands) && (similar > 0)); 539 } 540 } /* nEnvelopes==1 */ 541 542 return similar; 543 } 544 545 static INT similarIcc(PS_DATA *psData, const INT psBands, 546 const INT nEnvelopes) { 547 const INT diffThr = 2; 548 const INT sumDiffThr = diffThr * psBands / 4; 549 INT similar = 0; 550 INT diff = 0; 551 INT sumDiff = 0; 552 INT env = 0; 553 INT b = 0; 554 if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) { 555 similar = 1; 556 for (env = 0; env < nEnvelopes; env++) { 557 sumDiff = 0; 558 b = 0; 559 do { 560 diff = fixp_abs(psData->iccIdx[env][b] - psData->iccIdxLast[b]); 561 sumDiff += diff; 562 if ((diff > diffThr) /* more than x quantisation step in any band */ 563 || (sumDiff > sumDiffThr)) { /* more than x quantisations steps 564 overall difference */ 565 similar = 0; 566 } 567 b++; 568 } while ((b < psBands) && (similar > 0)); 569 } 570 } /* nEnvelopes==1 */ 571 572 return similar; 573 } 574 575 static void processIccData( 576 PS_DATA *psData, 577 FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], /* const input values: 578 unable to declare as 579 const, since it does 580 not poINT to const 581 memory */ 582 const INT psBands, const INT nEnvelopes) { 583 FIXP_DBL errICC = FL2FXCONST_DBL(0.f); 584 INT env, band; 585 INT bitsIccFreq, bitsIccTime; 586 INT error = 0; 587 INT inCoherence = 0, iccTransmit = 0; 588 INT *iccIdxLast; 589 590 iccIdxLast = psData->iccIdxLast; 591 592 /* Quantize ICC coefficients */ 593 for (env = 0; env < nEnvelopes; env++) { 594 errICC += 595 quantizeCoef(icc[env], psBands, iccQuant, 0, 8, psData->iccIdx[env]); 596 } 597 598 /* Check if ICC coefficients should be used */ 599 psData->iccEnable = 0; 600 for (env = 0; env < nEnvelopes; env++) { 601 for (band = 0; band < psBands; band++) { 602 inCoherence += psData->iccIdx[env][band]; 603 iccTransmit++; 604 } 605 } 606 if (inCoherence > 607 fMultI(FL2FXCONST_DBL(0.5f), iccTransmit)) { /* 0.5f empiric value */ 608 psData->iccEnable = 1; 609 } 610 611 if (psData->iccEnable == 0) { 612 psData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; 613 for (env = 0; env < nEnvelopes; env++) { 614 psData->iccDiffMode[env] = PS_DELTA_FREQ; 615 FDKmemclear(psData->iccIdx[env], sizeof(INT) * psBands); 616 } 617 return; 618 } 619 620 for (env = 0; env < nEnvelopes; env++) { 621 bitsIccFreq = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], NULL, psBands, 622 PS_DELTA_FREQ, &error); 623 624 if (psData->iccTimeCnt < MAX_TIME_DIFF_FRAMES) { 625 bitsIccTime = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], iccIdxLast, 626 psBands, PS_DELTA_TIME, &error); 627 } else { 628 bitsIccTime = DO_NOT_USE_THIS_MODE; 629 } 630 631 if (bitsIccFreq > bitsIccTime) { 632 psData->iccDiffMode[env] = PS_DELTA_TIME; 633 psData->iccTimeCnt++; 634 } else { 635 psData->iccDiffMode[env] = PS_DELTA_FREQ; 636 psData->iccTimeCnt = 0; 637 } 638 iccIdxLast = psData->iccIdx[env]; 639 } 640 } 641 642 static void calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS], 643 FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS], 644 FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], 645 INT nEnvelopes, INT psBands) { 646 INT i = 0; 647 INT env = 0; 648 for (env = 0; env < nEnvelopes; env++) { 649 for (i = 0; i < psBands; i++) { 650 /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]); 651 */ 652 FIXP_DBL IID = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / IID_SCALE_FT), 653 (ldPwrL[env][i] - ldPwrR[env][i])); 654 655 IID = fixMin(IID, (FIXP_DBL)(MAXVAL_DBL >> (LD_DATA_SHIFT + 1))); 656 IID = fixMax(IID, (FIXP_DBL)(MINVAL_DBL >> (LD_DATA_SHIFT + 1))); 657 iid[env][i] = IID << (LD_DATA_SHIFT + 1); 658 } 659 } 660 } 661 662 static void calculateICC(FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS], 663 FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS], 664 FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS], 665 FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS], 666 FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], 667 INT nEnvelopes, INT psBands) { 668 INT i = 0; 669 INT env = 0; 670 INT border = psBands; 671 672 switch (psBands) { 673 case PS_BANDS_COARSE: 674 border = 5; 675 break; 676 case PS_BANDS_MID: 677 border = 11; 678 break; 679 default: 680 break; 681 } 682 683 for (env = 0; env < nEnvelopes; env++) { 684 for (i = 0; i < border; i++) { 685 /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] * 686 * pwrR[env][i]) , 1.f); 687 */ 688 int scale; 689 FIXP_DBL invNrg = invSqrtNorm2( 690 fMax(fMult(pwrL[env][i], pwrR[env][i]), (FIXP_DBL)1), &scale); 691 icc[env][i] = 692 SATURATE_LEFT_SHIFT(fMult(pwrCr[env][i], invNrg), scale, DFRACT_BITS); 693 } 694 695 for (; i < psBands; i++) { 696 int denom_e; 697 FIXP_DBL denom_m = fMultNorm(pwrL[env][i], pwrR[env][i], &denom_e); 698 699 if (denom_m == (FIXP_DBL)0) { 700 icc[env][i] = (FIXP_DBL)MAXVAL_DBL; 701 } else { 702 int num_e, result_e; 703 FIXP_DBL num_m, result_m; 704 705 num_e = CountLeadingBits( 706 fixMax(fixp_abs(pwrCr[env][i]), fixp_abs(pwrCi[env][i]))); 707 num_m = fPow2Div2((pwrCr[env][i] << num_e)) + 708 fPow2Div2((pwrCi[env][i] << num_e)); 709 710 result_m = fDivNorm(num_m, denom_m, &result_e); 711 result_e += (-2 * num_e + 1) - denom_e; 712 icc[env][i] = scaleValueSaturate(sqrtFixp(result_m >> (result_e & 1)), 713 (result_e + (result_e & 1)) >> 1); 714 } 715 } 716 } 717 } 718 719 void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode) { 720 INT group, bin; 721 INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups; 722 723 FDKmemclear(hPsEncode->psBandNrgScale, PS_MAX_BANDS * sizeof(SCHAR)); 724 725 for (group = 0; group < nIidGroups; group++) { 726 /* Translate group to bin */ 727 bin = hPsEncode->subband2parameterIndex[group]; 728 729 /* Translate from 20 bins to 10 bins */ 730 if (hPsEncode->psEncMode == PS_BANDS_COARSE) { 731 bin = bin >> 1; 732 } 733 734 hPsEncode->psBandNrgScale[bin] = 735 (hPsEncode->psBandNrgScale[bin] == 0) 736 ? (hPsEncode->iidGroupWidthLd[group] + 5) 737 : (fixMax(hPsEncode->iidGroupWidthLd[group], 738 hPsEncode->psBandNrgScale[bin]) + 739 1); 740 } 741 } 742 743 FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode) { 744 FDK_PSENC_ERROR error = PSENC_OK; 745 746 if (phPsEncode == NULL) { 747 error = PSENC_INVALID_HANDLE; 748 } else { 749 HANDLE_PS_ENCODE hPsEncode = NULL; 750 if (NULL == (hPsEncode = GetRam_PsEncode())) { 751 error = PSENC_MEMORY_ERROR; 752 goto bail; 753 } 754 FDKmemclear(hPsEncode, sizeof(PS_ENCODE)); 755 *phPsEncode = hPsEncode; /* return allocated handle */ 756 } 757 bail: 758 return error; 759 } 760 761 FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode, 762 const PS_BANDS psEncMode, 763 const FIXP_DBL iidQuantErrorThreshold) { 764 FDK_PSENC_ERROR error = PSENC_OK; 765 766 if (NULL == hPsEncode) { 767 error = PSENC_INVALID_HANDLE; 768 } else { 769 if (PSENC_OK != (InitPSData(&hPsEncode->psData))) { 770 goto bail; 771 } 772 773 switch (psEncMode) { 774 case PS_BANDS_COARSE: 775 case PS_BANDS_MID: 776 hPsEncode->nQmfIidGroups = QMF_GROUPS_LO_RES; 777 hPsEncode->nSubQmfIidGroups = SUBQMF_GROUPS_LO_RES; 778 FDKmemcpy(hPsEncode->iidGroupBorders, iidGroupBordersLoRes, 779 (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups + 1) * 780 sizeof(INT)); 781 FDKmemcpy(hPsEncode->subband2parameterIndex, subband2parameter20, 782 (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) * 783 sizeof(INT)); 784 FDKmemcpy(hPsEncode->iidGroupWidthLd, iidGroupWidthLdLoRes, 785 (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) * 786 sizeof(UCHAR)); 787 break; 788 default: 789 error = PSENC_INIT_ERROR; 790 goto bail; 791 } 792 793 hPsEncode->psEncMode = psEncMode; 794 hPsEncode->iidQuantErrorThreshold = iidQuantErrorThreshold; 795 FDKsbrEnc_initPsBandNrgScale(hPsEncode); 796 } 797 bail: 798 return error; 799 } 800 801 FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode) { 802 FDK_PSENC_ERROR error = PSENC_OK; 803 804 if (NULL != phPsEncode) { 805 FreeRam_PsEncode(phPsEncode); 806 } 807 808 return error; 809 } 810 811 typedef struct { 812 FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 813 FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 814 FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 815 FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 816 FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 817 FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 818 819 } PS_PWR_DATA; 820 821 FDK_PSENC_ERROR FDKsbrEnc_PSEncode( 822 HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale, 823 UINT maxEnvelopes, 824 FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], 825 const INT frameSize, const INT sendHeader) { 826 FDK_PSENC_ERROR error = PSENC_OK; 827 828 HANDLE_PS_DATA hPsData = &hPsEncode->psData; 829 FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 830 FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS]; 831 int envBorder[PS_MAX_ENVELOPES + 1]; 832 833 int group, bin, col, subband, band; 834 int i = 0; 835 836 int env = 0; 837 int psBands = (int)hPsEncode->psEncMode; 838 int nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups; 839 int nEnvelopes = fixMin(maxEnvelopes, (UINT)PS_MAX_ENVELOPES); 840 841 C_ALLOC_SCRATCH_START(pwrData, PS_PWR_DATA, 1) 842 843 for (env = 0; env < nEnvelopes + 1; env++) { 844 envBorder[env] = fMultI(GetInvInt(nEnvelopes), frameSize * env); 845 } 846 847 for (env = 0; env < nEnvelopes; env++) { 848 /* clear energy array */ 849 for (band = 0; band < psBands; band++) { 850 pwrData->pwrL[env][band] = pwrData->pwrR[env][band] = 851 pwrData->pwrCr[env][band] = pwrData->pwrCi[env][band] = FIXP_DBL(1); 852 } 853 854 /**** calculate energies and correlation ****/ 855 856 /* start with hybrid data */ 857 for (group = 0; group < nIidGroups; group++) { 858 /* Translate group to bin */ 859 bin = hPsEncode->subband2parameterIndex[group]; 860 861 /* Translate from 20 bins to 10 bins */ 862 if (hPsEncode->psEncMode == PS_BANDS_COARSE) { 863 bin >>= 1; 864 } 865 866 /* determine group border */ 867 int bScale = hPsEncode->psBandNrgScale[bin]; 868 869 FIXP_DBL pwrL_env_bin = pwrData->pwrL[env][bin]; 870 FIXP_DBL pwrR_env_bin = pwrData->pwrR[env][bin]; 871 FIXP_DBL pwrCr_env_bin = pwrData->pwrCr[env][bin]; 872 FIXP_DBL pwrCi_env_bin = pwrData->pwrCi[env][bin]; 873 874 int scale = (int)dynBandScale[bin]; 875 for (col = envBorder[env]; col < envBorder[env + 1]; col++) { 876 for (subband = hPsEncode->iidGroupBorders[group]; 877 subband < hPsEncode->iidGroupBorders[group + 1]; subband++) { 878 FIXP_DBL l_real = (hybridData[col][0][0][subband]) << scale; 879 FIXP_DBL l_imag = (hybridData[col][0][1][subband]) << scale; 880 FIXP_DBL r_real = (hybridData[col][1][0][subband]) << scale; 881 FIXP_DBL r_imag = (hybridData[col][1][1][subband]) << scale; 882 883 pwrL_env_bin += (fPow2Div2(l_real) + fPow2Div2(l_imag)) >> bScale; 884 pwrR_env_bin += (fPow2Div2(r_real) + fPow2Div2(r_imag)) >> bScale; 885 pwrCr_env_bin += 886 (fMultDiv2(l_real, r_real) + fMultDiv2(l_imag, r_imag)) >> bScale; 887 pwrCi_env_bin += 888 (fMultDiv2(r_real, l_imag) - fMultDiv2(l_real, r_imag)) >> bScale; 889 } 890 } 891 /* assure, nrg's of left and right channel are not negative; necessary on 892 * 16 bit multiply units */ 893 pwrData->pwrL[env][bin] = fixMax((FIXP_DBL)0, pwrL_env_bin); 894 pwrData->pwrR[env][bin] = fixMax((FIXP_DBL)0, pwrR_env_bin); 895 896 pwrData->pwrCr[env][bin] = pwrCr_env_bin; 897 pwrData->pwrCi[env][bin] = pwrCi_env_bin; 898 899 } /* nIidGroups */ 900 901 /* calc logarithmic energy */ 902 LdDataVector(pwrData->pwrL[env], pwrData->ldPwrL[env], psBands); 903 LdDataVector(pwrData->pwrR[env], pwrData->ldPwrR[env], psBands); 904 905 } /* nEnvelopes */ 906 907 /* calculate iid and icc */ 908 calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands); 909 calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi, 910 icc, nEnvelopes, psBands); 911 912 /*** Envelope Reduction ***/ 913 while (envelopeReducible(iid, icc, psBands, nEnvelopes)) { 914 int e = 0; 915 /* sum energies of two neighboring envelopes */ 916 nEnvelopes >>= 1; 917 for (e = 0; e < nEnvelopes; e++) { 918 FDKsbrEnc_addFIXP_DBL(pwrData->pwrL[2 * e], pwrData->pwrL[2 * e + 1], 919 pwrData->pwrL[e], psBands); 920 FDKsbrEnc_addFIXP_DBL(pwrData->pwrR[2 * e], pwrData->pwrR[2 * e + 1], 921 pwrData->pwrR[e], psBands); 922 FDKsbrEnc_addFIXP_DBL(pwrData->pwrCr[2 * e], pwrData->pwrCr[2 * e + 1], 923 pwrData->pwrCr[e], psBands); 924 FDKsbrEnc_addFIXP_DBL(pwrData->pwrCi[2 * e], pwrData->pwrCi[2 * e + 1], 925 pwrData->pwrCi[e], psBands); 926 927 /* calc logarithmic energy */ 928 LdDataVector(pwrData->pwrL[e], pwrData->ldPwrL[e], psBands); 929 LdDataVector(pwrData->pwrR[e], pwrData->ldPwrR[e], psBands); 930 931 /* reduce number of envelopes and adjust borders */ 932 envBorder[e] = envBorder[2 * e]; 933 } 934 envBorder[nEnvelopes] = envBorder[2 * nEnvelopes]; 935 936 /* re-calculate iid and icc */ 937 calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands); 938 calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi, 939 icc, nEnvelopes, psBands); 940 } 941 942 /* */ 943 if (sendHeader) { 944 hPsData->headerCnt = MAX_PS_NOHEADER_CNT; 945 hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; 946 hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; 947 hPsData->noEnvCnt = MAX_NOENV_CNT; 948 } 949 950 /*** Parameter processing, quantisation etc ***/ 951 processIidData(hPsData, iid, psBands, nEnvelopes, 952 hPsEncode->iidQuantErrorThreshold); 953 processIccData(hPsData, icc, psBands, nEnvelopes); 954 955 /*** Initialize output struct ***/ 956 957 /* PS Header on/off ? */ 958 if ((hPsData->headerCnt < MAX_PS_NOHEADER_CNT) && 959 ((hPsData->iidQuantMode == hPsData->iidQuantModeLast) && 960 (hPsData->iccQuantMode == hPsData->iccQuantModeLast)) && 961 ((hPsData->iidEnable == hPsData->iidEnableLast) && 962 (hPsData->iccEnable == hPsData->iccEnableLast))) { 963 hPsOut->enablePSHeader = 0; 964 } else { 965 hPsOut->enablePSHeader = 1; 966 hPsData->headerCnt = 0; 967 } 968 969 /* nEnvelopes = 0 ? */ 970 if ((hPsData->noEnvCnt < MAX_NOENV_CNT) && 971 (similarIid(hPsData, psBands, nEnvelopes)) && 972 (similarIcc(hPsData, psBands, nEnvelopes))) { 973 hPsOut->nEnvelopes = nEnvelopes = 0; 974 hPsData->noEnvCnt++; 975 } else { 976 hPsData->noEnvCnt = 0; 977 } 978 979 if (nEnvelopes > 0) { 980 hPsOut->enableIID = hPsData->iidEnable; 981 hPsOut->iidMode = getIIDMode(psBands, hPsData->iidQuantMode); 982 983 hPsOut->enableICC = hPsData->iccEnable; 984 hPsOut->iccMode = getICCMode(psBands, hPsData->iccQuantMode); 985 986 hPsOut->enableIpdOpd = 0; 987 hPsOut->frameClass = 0; 988 hPsOut->nEnvelopes = nEnvelopes; 989 990 for (env = 0; env < nEnvelopes; env++) { 991 hPsOut->frameBorder[env] = envBorder[env + 1]; 992 hPsOut->deltaIID[env] = (PS_DELTA)hPsData->iidDiffMode[env]; 993 hPsOut->deltaICC[env] = (PS_DELTA)hPsData->iccDiffMode[env]; 994 for (band = 0; band < psBands; band++) { 995 hPsOut->iid[env][band] = hPsData->iidIdx[env][band]; 996 hPsOut->icc[env][band] = hPsData->iccIdx[env][band]; 997 } 998 } 999 1000 /* IPD OPD not supported right now */ 1001 FDKmemclear(hPsOut->ipd, 1002 PS_MAX_ENVELOPES * PS_MAX_BANDS * sizeof(PS_DELTA)); 1003 for (env = 0; env < PS_MAX_ENVELOPES; env++) { 1004 hPsOut->deltaIPD[env] = PS_DELTA_FREQ; 1005 hPsOut->deltaOPD[env] = PS_DELTA_FREQ; 1006 } 1007 1008 FDKmemclear(hPsOut->ipdLast, PS_MAX_BANDS * sizeof(INT)); 1009 FDKmemclear(hPsOut->opdLast, PS_MAX_BANDS * sizeof(INT)); 1010 1011 for (band = 0; band < PS_MAX_BANDS; band++) { 1012 hPsOut->iidLast[band] = hPsData->iidIdxLast[band]; 1013 hPsOut->iccLast[band] = hPsData->iccIdxLast[band]; 1014 } 1015 1016 /* save iids and iccs for differential time coding in the next frame */ 1017 hPsData->nEnvelopesLast = nEnvelopes; 1018 hPsData->iidEnableLast = hPsData->iidEnable; 1019 hPsData->iccEnableLast = hPsData->iccEnable; 1020 hPsData->iidQuantModeLast = hPsData->iidQuantMode; 1021 hPsData->iccQuantModeLast = hPsData->iccQuantMode; 1022 for (i = 0; i < psBands; i++) { 1023 hPsData->iidIdxLast[i] = hPsData->iidIdx[nEnvelopes - 1][i]; 1024 hPsData->iccIdxLast[i] = hPsData->iccIdx[nEnvelopes - 1][i]; 1025 } 1026 } /* Envelope > 0 */ 1027 1028 C_ALLOC_SCRATCH_END(pwrData, PS_PWR_DATA, 1) 1029 1030 return error; 1031 } 1032