Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2012 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