Home | History | Annotate | Download | only in src
      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