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