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 /************************* MPEG-D DRC decoder library **************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "fixpoint_math.h"
    104 #include "drcDec_reader.h"
    105 #include "drcDec_tools.h"
    106 #include "drcDec_rom.h"
    107 #include "drcDecoder.h"
    108 
    109 /* MPEG-D DRC AMD 1 */
    110 
    111 #define UNIDRCCONFEXT_PARAM_DRC 0x1
    112 #define UNIDRCCONFEXT_V1 0x2
    113 #define UNIDRCLOUDEXT_EQ 0x1
    114 
    115 #define UNIDRCGAINEXT_TERM 0x0
    116 #define UNIDRCLOUDEXT_TERM 0x0
    117 #define UNIDRCCONFEXT_TERM 0x0
    118 
    119 static int _getZ(const int nNodesMax) {
    120   /* Z is the minimum codeword length that is needed to encode all possible
    121    * timeDelta values */
    122   /* Z = ceil(log2(2*nNodesMax)) */
    123   int Z = 1;
    124   while ((1 << Z) < (2 * nNodesMax)) {
    125     Z++;
    126   }
    127   return Z;
    128 }
    129 
    130 static int _getTimeDeltaMin(const GAIN_SET* pGset, const int deltaTminDefault) {
    131   if (pGset->timeDeltaMinPresent) {
    132     return pGset->timeDeltaMin;
    133   } else {
    134     return deltaTminDefault;
    135   }
    136 }
    137 
    138 /* compare and assign */
    139 static inline int _compAssign(UCHAR* dest, const UCHAR src) {
    140   int diff = 0;
    141   if (*dest != src) diff = 1;
    142   *dest = src;
    143   return diff;
    144 }
    145 
    146 static inline int _compAssign(ULONG* dest, const ULONG src) {
    147   int diff = 0;
    148   if (*dest != src) diff = 1;
    149   *dest = src;
    150   return diff;
    151 }
    152 
    153 typedef const SCHAR (*Huffman)[2];
    154 
    155 int _decodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
    156                      HANDLE_FDK_BITSTREAM hBs) /*!< Handle to bitbuffer */
    157 {
    158   SCHAR index = 0;
    159   int value, bit;
    160 
    161   while (index >= 0) {
    162     bit = FDKreadBits(hBs, 1);
    163     index = h[index][bit];
    164   }
    165 
    166   value = index + 64; /* Add offset */
    167 
    168   return value;
    169 }
    170 
    171 /**********/
    172 /* uniDrc */
    173 /**********/
    174 
    175 DRC_ERROR
    176 drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    177                   HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    178                   const int frameSize, const int deltaTminDefault,
    179                   HANDLE_UNI_DRC_GAIN hUniDrcGain) {
    180   DRC_ERROR err = DE_OK;
    181   int loudnessInfoSetPresent, uniDrcConfigPresent;
    182 
    183   loudnessInfoSetPresent = FDKreadBits(hBs, 1);
    184   if (loudnessInfoSetPresent) {
    185     uniDrcConfigPresent = FDKreadBits(hBs, 1);
    186     if (uniDrcConfigPresent) {
    187       err = drcDec_readUniDrcConfig(hBs, hUniDrcConfig);
    188       if (err) {
    189         /* clear config, if parsing error occured */
    190         FDKmemclear(hUniDrcConfig, sizeof(UNI_DRC_CONFIG));
    191         hUniDrcConfig->diff = 1;
    192       }
    193     }
    194     err = drcDec_readLoudnessInfoSet(hBs, hLoudnessInfoSet);
    195     if (err) {
    196       /* clear config, if parsing error occured */
    197       FDKmemclear(hLoudnessInfoSet, sizeof(LOUDNESS_INFO_SET));
    198       hLoudnessInfoSet->diff = 1;
    199     }
    200   }
    201 
    202   if (hUniDrcGain != NULL) {
    203     err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
    204                                 hUniDrcGain);
    205     if (err) return err;
    206   }
    207 
    208   return err;
    209 }
    210 
    211 /**************/
    212 /* uniDrcGain */
    213 /**************/
    214 
    215 static FIXP_SGL _decodeGainInitial(
    216     HANDLE_FDK_BITSTREAM hBs, const GAIN_CODING_PROFILE gainCodingProfile) {
    217   int sign, magn;
    218   FIXP_SGL gainInitial = (FIXP_SGL)0;
    219   switch (gainCodingProfile) {
    220     case GCP_REGULAR:
    221       sign = FDKreadBits(hBs, 1);
    222       magn = FDKreadBits(hBs, 8);
    223 
    224       gainInitial =
    225           (FIXP_SGL)(magn << (FRACT_BITS - 1 - 3 - 7)); /* magn * 0.125; */
    226       if (sign) gainInitial = -gainInitial;
    227       break;
    228     case GCP_FADING:
    229       sign = FDKreadBits(hBs, 1);
    230       if (sign == 0)
    231         gainInitial = (FIXP_SGL)0;
    232       else {
    233         magn = FDKreadBits(hBs, 10);
    234         gainInitial = -(FIXP_SGL)(
    235             (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
    236       }
    237       break;
    238     case GCP_CLIPPING_DUCKING:
    239       sign = FDKreadBits(hBs, 1);
    240       if (sign == 0)
    241         gainInitial = (FIXP_SGL)0;
    242       else {
    243         magn = FDKreadBits(hBs, 8);
    244         gainInitial = -(FIXP_SGL)(
    245             (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
    246       }
    247       break;
    248     case GCP_CONSTANT:
    249       break;
    250   }
    251   return gainInitial;
    252 }
    253 
    254 static int _decodeNNodes(HANDLE_FDK_BITSTREAM hBs) {
    255   int nNodes = 0, endMarker = 0;
    256 
    257   /* decode number of nodes */
    258   while (endMarker != 1) {
    259     nNodes++;
    260     if (nNodes >= 128) break;
    261     endMarker = FDKreadBits(hBs, 1);
    262   }
    263   return nNodes;
    264 }
    265 
    266 static void _decodeGains(HANDLE_FDK_BITSTREAM hBs,
    267                          const GAIN_CODING_PROFILE gainCodingProfile,
    268                          const int nNodes, GAIN_NODE* pNodes) {
    269   int k, deltaGain;
    270   Huffman deltaGainCodebook;
    271 
    272   pNodes[0].gainDb = _decodeGainInitial(hBs, gainCodingProfile);
    273 
    274   if (gainCodingProfile == GCP_CLIPPING_DUCKING) {
    275     deltaGainCodebook = (Huffman)&deltaGain_codingProfile_2_huffman;
    276   } else {
    277     deltaGainCodebook = (Huffman)&deltaGain_codingProfile_0_1_huffman;
    278   }
    279 
    280   for (k = 1; k < nNodes; k++) {
    281     deltaGain = _decodeHuffmanCW(deltaGainCodebook, hBs);
    282     if (k >= 16) continue;
    283     /* gain_dB_e = 7 */
    284     pNodes[k].gainDb =
    285         pNodes[k - 1].gainDb +
    286         (FIXP_SGL)(deltaGain << (FRACT_BITS - 1 - 7 -
    287                                  3)); /* pNodes[k-1].gainDb + 0.125*deltaGain */
    288   }
    289 }
    290 
    291 static void _decodeSlopes(HANDLE_FDK_BITSTREAM hBs,
    292                           const GAIN_INTERPOLATION_TYPE gainInterpolationType,
    293                           const int nNodes, GAIN_NODE* pNodes) {
    294   int k = 0;
    295 
    296   if (gainInterpolationType == GIT_SPLINE) {
    297     /* decode slope steepness */
    298     for (k = 0; k < nNodes; k++) {
    299       _decodeHuffmanCW((Huffman)&slopeSteepness_huffman, hBs);
    300     }
    301   }
    302 }
    303 
    304 static int _decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs, const int Z) {
    305   int prefix, mu;
    306 
    307   prefix = FDKreadBits(hBs, 2);
    308   switch (prefix) {
    309     case 0x0:
    310       return 1;
    311     case 0x1:
    312       mu = FDKreadBits(hBs, 2);
    313       return mu + 2;
    314     case 0x2:
    315       mu = FDKreadBits(hBs, 3);
    316       return mu + 6;
    317     case 0x3:
    318       mu = FDKreadBits(hBs, Z);
    319       return mu + 14;
    320     default:
    321       return 0;
    322   }
    323 }
    324 
    325 static void _decodeTimes(HANDLE_FDK_BITSTREAM hBs, const int deltaTmin,
    326                          const int frameSize, const int fullFrame,
    327                          const int timeOffset, const int Z, const int nNodes,
    328                          GAIN_NODE* pNodes) {
    329   int timeDelta, k;
    330   int timeOffs = timeOffset;
    331   int frameEndFlag, nodeTimeTmp, nodeResFlag;
    332 
    333   if (fullFrame == 0) {
    334     frameEndFlag = FDKreadBits(hBs, 1);
    335   } else {
    336     frameEndFlag = 1;
    337   }
    338 
    339   if (frameEndFlag ==
    340       1) { /* frameEndFlag == 1 signals that the last node is at the end of the
    341               DRC frame */
    342     nodeResFlag = 0;
    343     for (k = 0; k < nNodes - 1; k++) {
    344       /* decode a delta time value */
    345       timeDelta = _decodeTimeDelta(hBs, Z);
    346       if (k >= (16 - 1)) continue;
    347       /* frameEndFlag == 1 needs special handling for last node with node
    348        * reservoir */
    349       nodeTimeTmp = timeOffs + timeDelta * deltaTmin;
    350       if (nodeTimeTmp > frameSize + timeOffset) {
    351         if (nodeResFlag == 0) {
    352           pNodes[k].time = frameSize + timeOffset;
    353           nodeResFlag = 1;
    354         }
    355         pNodes[k + 1].time = nodeTimeTmp;
    356       } else {
    357         pNodes[k].time = nodeTimeTmp;
    358       }
    359       timeOffs = nodeTimeTmp;
    360     }
    361     if (nodeResFlag == 0) {
    362       k = fMin(k, 16 - 1);
    363       pNodes[k].time = frameSize + timeOffset;
    364     }
    365   } else {
    366     for (k = 0; k < nNodes; k++) {
    367       /* decode a delta time value */
    368       timeDelta = _decodeTimeDelta(hBs, Z);
    369       if (k >= 16) continue;
    370       pNodes[k].time = timeOffs + timeDelta * deltaTmin;
    371       timeOffs = pNodes[k].time;
    372     }
    373   }
    374 }
    375 
    376 static void _readNodes(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
    377                        const int frameSize, const int timeDeltaMin,
    378                        UCHAR* pNNodes, GAIN_NODE* pNodes) {
    379   int timeOffset, drcGainCodingMode, nNodes;
    380   int Z = _getZ(frameSize / timeDeltaMin);
    381   if (gainSet->timeAlignment == 0) {
    382     timeOffset = -1;
    383   } else {
    384     timeOffset = -timeDeltaMin +
    385                  (timeDeltaMin - 1) /
    386                      2; /* timeOffset = - deltaTmin + floor((deltaTmin-1)/2); */
    387   }
    388 
    389   drcGainCodingMode = FDKreadBits(hBs, 1);
    390   if (drcGainCodingMode == 0) {
    391     /* "simple" mode: only one node at the end of the frame with slope = 0 */
    392     nNodes = 1;
    393     pNodes[0].gainDb = _decodeGainInitial(
    394         hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile);
    395     pNodes[0].time = frameSize + timeOffset;
    396   } else {
    397     nNodes = _decodeNNodes(hBs);
    398 
    399     _decodeSlopes(hBs, (GAIN_INTERPOLATION_TYPE)gainSet->gainInterpolationType,
    400                   nNodes, pNodes);
    401 
    402     _decodeTimes(hBs, timeDeltaMin, frameSize, gainSet->fullFrame, timeOffset,
    403                  Z, nNodes, pNodes);
    404 
    405     _decodeGains(hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile, nNodes,
    406                  pNodes);
    407   }
    408   *pNNodes = (UCHAR)nNodes;
    409 }
    410 
    411 static void _readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
    412                                  const int frameSize, const int timeDeltaMin,
    413                                  UCHAR* pNNodes, GAIN_NODE pNodes[16]) {
    414   SHORT timeBufPrevFrame[16], timeBufCurFrame[16];
    415   int nNodesNodeRes, nNodesCur, k, m;
    416 
    417   if (gainSet->gainCodingProfile == GCP_CONSTANT) {
    418     *pNNodes = 1;
    419     pNodes[0].time = frameSize - 1;
    420     pNodes[0].gainDb = (FIXP_SGL)0;
    421   } else {
    422     _readNodes(hBs, gainSet, frameSize, timeDeltaMin, pNNodes, pNodes);
    423 
    424     /* count number of nodes in node reservoir */
    425     nNodesNodeRes = 0;
    426     nNodesCur = 0;
    427     /* count and buffer nodes from node reservoir */
    428     for (k = 0; k < *pNNodes; k++) {
    429       if (k >= 16) continue;
    430       if (pNodes[k].time >= frameSize) {
    431         /* write node reservoir times into buffer */
    432         timeBufPrevFrame[nNodesNodeRes] = pNodes[k].time;
    433         nNodesNodeRes++;
    434       } else { /* times from current frame */
    435         timeBufCurFrame[nNodesCur] = pNodes[k].time;
    436         nNodesCur++;
    437       }
    438     }
    439     /* compose right time order (bit reservoir first) */
    440     for (k = 0; k < nNodesNodeRes; k++) {
    441       /* subtract two time frameSize: one to remove node reservoir offset and
    442        * one to get the negative index relative to the current frame
    443        */
    444       pNodes[k].time = timeBufPrevFrame[k] - 2 * frameSize;
    445     }
    446     /* ...and times from current frame */
    447     for (m = 0; m < nNodesCur; m++, k++) {
    448       pNodes[k].time = timeBufCurFrame[m];
    449     }
    450   }
    451 }
    452 
    453 static DRC_ERROR _readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,
    454                                           UNI_DRC_GAIN_EXTENSION* pExt) {
    455   DRC_ERROR err = DE_OK;
    456   int k, bitSizeLen, extSizeBits, bitSize;
    457 
    458   k = 0;
    459   pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
    460   while (pExt->uniDrcGainExtType[k] != UNIDRCGAINEXT_TERM) {
    461     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
    462     bitSizeLen = FDKreadBits(hBs, 3);
    463     extSizeBits = bitSizeLen + 4;
    464 
    465     bitSize = FDKreadBits(hBs, extSizeBits);
    466     pExt->extBitSize[k] = bitSize + 1;
    467 
    468     switch (pExt->uniDrcGainExtType[k]) {
    469       /* add future extensions here */
    470       default:
    471         FDKpushFor(hBs, pExt->extBitSize[k]);
    472         break;
    473     }
    474     k++;
    475     pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
    476   }
    477 
    478   return err;
    479 }
    480 
    481 DRC_ERROR
    482 drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
    483                       HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
    484                       const int deltaTminDefault,
    485                       HANDLE_UNI_DRC_GAIN hUniDrcGain) {
    486   DRC_ERROR err = DE_OK;
    487   int seq, gainSequenceCount;
    488   DRC_COEFFICIENTS_UNI_DRC* pCoef =
    489       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
    490   if (pCoef == NULL) return DE_OK;
    491   if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
    492 
    493   gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
    494 
    495   for (seq = 0; seq < gainSequenceCount; seq++) {
    496     UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
    497     GAIN_SET* gainSet;
    498     int timeDeltaMin;
    499     UCHAR tmpNNodes = 0;
    500     GAIN_NODE tmpNodes[16];
    501 
    502     if ((index >= pCoef->gainSetCount) || (index >= 12)) return DE_NOT_OK;
    503     gainSet = &(pCoef->gainSet[index]);
    504 
    505     timeDeltaMin = _getTimeDeltaMin(gainSet, deltaTminDefault);
    506 
    507     _readDrcGainSequence(hBs, gainSet, frameSize, timeDeltaMin, &tmpNNodes,
    508                          tmpNodes);
    509 
    510     hUniDrcGain->nNodes[seq] = tmpNNodes;
    511     FDKmemcpy(hUniDrcGain->gainNode[seq], tmpNodes,
    512               fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
    513   }
    514 
    515   hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
    516   if (hUniDrcGain->uniDrcGainExtPresent == 1) {
    517     err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
    518     if (err) return err;
    519   }
    520 
    521   return err;
    522 }
    523 
    524 /****************/
    525 /* uniDrcConfig */
    526 /****************/
    527 
    528 static void _decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,
    529                                        DUCKING_MODIFICATION* pDMod, int isBox) {
    530   int bsDuckingScaling, sigma, mu;
    531 
    532   if (isBox) FDKpushFor(hBs, 7); /* reserved */
    533   pDMod->duckingScalingPresent = FDKreadBits(hBs, 1);
    534 
    535   if (pDMod->duckingScalingPresent) {
    536     if (isBox) FDKpushFor(hBs, 4); /* reserved */
    537     bsDuckingScaling = FDKreadBits(hBs, 4);
    538     sigma = bsDuckingScaling >> 3;
    539     mu = bsDuckingScaling & 0x7;
    540 
    541     if (sigma) {
    542       pDMod->duckingScaling = (FIXP_SGL)(
    543           (7 - mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 - 0.125 * (1 + mu); */
    544     } else {
    545       pDMod->duckingScaling = (FIXP_SGL)(
    546           (9 + mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 + 0.125 * (1 + mu); */
    547     }
    548   } else {
    549     pDMod->duckingScaling = (FIXP_SGL)(1 << (FRACT_BITS - 1 - 2)); /* 1.0 */
    550   }
    551 }
    552 
    553 static void _decodeGainModification(HANDLE_FDK_BITSTREAM hBs, const int version,
    554                                     int bandCount, GAIN_MODIFICATION* pGMod,
    555                                     int isBox) {
    556   int sign, bsGainOffset, bsAttenuationScaling, bsAmplificationScaling;
    557 
    558   if (version > 0) {
    559     int b, shapeFilterPresent;
    560 
    561     if (isBox) {
    562       FDKpushFor(hBs, 4); /* reserved */
    563       bandCount = FDKreadBits(hBs, 4);
    564     }
    565 
    566     for (b = 0; b < bandCount; b++) {
    567       if (isBox) {
    568         FDKpushFor(hBs, 4); /* reserved */
    569         pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
    570         pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
    571         pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
    572         pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
    573       }
    574 
    575       if (!isBox)
    576         pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
    577       if (pGMod[b].targetCharacteristicLeftPresent) {
    578         if (isBox) FDKpushFor(hBs, 4); /* reserved */
    579         pGMod[b].targetCharacteristicLeftIndex = FDKreadBits(hBs, 4);
    580       }
    581       if (!isBox)
    582         pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
    583       if (pGMod[b].targetCharacteristicRightPresent) {
    584         if (isBox) FDKpushFor(hBs, 4); /* reserved */
    585         pGMod[b].targetCharacteristicRightIndex = FDKreadBits(hBs, 4);
    586       }
    587       if (!isBox) pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
    588       if (pGMod[b].gainScalingPresent) {
    589         bsAttenuationScaling = FDKreadBits(hBs, 4);
    590         pGMod[b].attenuationScaling = (FIXP_SGL)(
    591             bsAttenuationScaling
    592             << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
    593         bsAmplificationScaling = FDKreadBits(hBs, 4);
    594         pGMod[b].amplificationScaling = (FIXP_SGL)(
    595             bsAmplificationScaling
    596             << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
    597       }
    598       if (!isBox) pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
    599       if (pGMod[b].gainOffsetPresent) {
    600         if (isBox) FDKpushFor(hBs, 2); /* reserved */
    601         sign = FDKreadBits(hBs, 1);
    602         bsGainOffset = FDKreadBits(hBs, 5);
    603         pGMod[b].gainOffset = (FIXP_SGL)(
    604             (1 + bsGainOffset)
    605             << (FRACT_BITS - 1 - 2 - 4)); /* (1+bsGainOffset) * 0.25; */
    606         if (sign) {
    607           pGMod[b].gainOffset = -pGMod[b].gainOffset;
    608         }
    609       }
    610     }
    611     if (bandCount == 1) {
    612       shapeFilterPresent = FDKreadBits(hBs, 1);
    613       if (shapeFilterPresent) {
    614         if (isBox) FDKpushFor(hBs, 3); /* reserved */
    615         FDKpushFor(hBs, 4);            /* pGMod->shapeFilterIndex */
    616       } else {
    617         if (isBox) FDKpushFor(hBs, 7); /* reserved */
    618       }
    619     }
    620   } else {
    621     int b, gainScalingPresent, gainOffsetPresent;
    622     FIXP_SGL attenuationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
    623              amplificationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
    624              gainOffset = (FIXP_SGL)0;
    625     if (isBox) FDKpushFor(hBs, 7); /* reserved */
    626     gainScalingPresent = FDKreadBits(hBs, 1);
    627     if (gainScalingPresent) {
    628       bsAttenuationScaling = FDKreadBits(hBs, 4);
    629       attenuationScaling = (FIXP_SGL)(
    630           bsAttenuationScaling
    631           << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
    632       bsAmplificationScaling = FDKreadBits(hBs, 4);
    633       amplificationScaling = (FIXP_SGL)(
    634           bsAmplificationScaling
    635           << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
    636     }
    637     if (isBox) FDKpushFor(hBs, 7); /* reserved */
    638     gainOffsetPresent = FDKreadBits(hBs, 1);
    639     if (gainOffsetPresent) {
    640       if (isBox) FDKpushFor(hBs, 2); /* reserved */
    641       sign = FDKreadBits(hBs, 1);
    642       bsGainOffset = FDKreadBits(hBs, 5);
    643       gainOffset =
    644           (FIXP_SGL)((1 + bsGainOffset) << (FRACT_BITS - 1 - 2 -
    645                                             4)); /* (1+bsGainOffset) * 0.25; */
    646       if (sign) {
    647         gainOffset = -gainOffset;
    648       }
    649     }
    650     for (b = 0; b < 4; b++) {
    651       pGMod[b].targetCharacteristicLeftPresent = 0;
    652       pGMod[b].targetCharacteristicRightPresent = 0;
    653       pGMod[b].gainScalingPresent = gainScalingPresent;
    654       pGMod[b].attenuationScaling = attenuationScaling;
    655       pGMod[b].amplificationScaling = amplificationScaling;
    656       pGMod[b].gainOffsetPresent = gainOffsetPresent;
    657       pGMod[b].gainOffset = gainOffset;
    658     }
    659   }
    660 }
    661 
    662 static void _readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs, const int version,
    663                                    DRC_CHARACTERISTIC* pDChar, int isBox) {
    664   if (version == 0) {
    665     if (isBox) FDKpushFor(hBs, 1); /* reserved */
    666     pDChar->cicpIndex = FDKreadBits(hBs, 7);
    667     if (pDChar->cicpIndex > 0) {
    668       pDChar->present = 1;
    669       pDChar->isCICP = 1;
    670     } else {
    671       pDChar->present = 0;
    672     }
    673   } else {
    674     pDChar->present = FDKreadBits(hBs, 1);
    675     if (isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
    676     if (pDChar->present) {
    677       if (!isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
    678       if (pDChar->isCICP) {
    679         if (isBox) FDKpushFor(hBs, 1); /* reserved */
    680         pDChar->cicpIndex = FDKreadBits(hBs, 7);
    681       } else {
    682         pDChar->custom.left = FDKreadBits(hBs, 4);
    683         pDChar->custom.right = FDKreadBits(hBs, 4);
    684       }
    685     }
    686   }
    687 }
    688 
    689 static void _readBandBorder(HANDLE_FDK_BITSTREAM hBs, BAND_BORDER* pBBord,
    690                             int drcBandType, int isBox) {
    691   if (drcBandType) {
    692     if (isBox) FDKpushFor(hBs, 4); /* reserved */
    693     pBBord->crossoverFreqIndex = FDKreadBits(hBs, 4);
    694   } else {
    695     if (isBox) FDKpushFor(hBs, 6); /* reserved */
    696     pBBord->startSubBandIndex = FDKreadBits(hBs, 10);
    697   }
    698 }
    699 
    700 static DRC_ERROR _readGainSet(HANDLE_FDK_BITSTREAM hBs, const int version,
    701                               int* gainSequenceIndex, GAIN_SET* pGSet,
    702                               int isBox) {
    703   if (isBox) FDKpushFor(hBs, 2); /* reserved */
    704   pGSet->gainCodingProfile = FDKreadBits(hBs, 2);
    705   pGSet->gainInterpolationType = FDKreadBits(hBs, 1);
    706   pGSet->fullFrame = FDKreadBits(hBs, 1);
    707   pGSet->timeAlignment = FDKreadBits(hBs, 1);
    708   pGSet->timeDeltaMinPresent = FDKreadBits(hBs, 1);
    709 
    710   if (pGSet->timeDeltaMinPresent) {
    711     int bsTimeDeltaMin;
    712     if (isBox) FDKpushFor(hBs, 5); /* reserved */
    713     bsTimeDeltaMin = FDKreadBits(hBs, 11);
    714     pGSet->timeDeltaMin = bsTimeDeltaMin + 1;
    715   }
    716 
    717   if (pGSet->gainCodingProfile != GCP_CONSTANT) {
    718     int i;
    719     if (isBox) FDKpushFor(hBs, 3); /* reserved */
    720     pGSet->bandCount = FDKreadBits(hBs, 4);
    721     if (pGSet->bandCount > 4) return DE_MEMORY_ERROR;
    722 
    723     if ((pGSet->bandCount > 1) || isBox) {
    724       pGSet->drcBandType = FDKreadBits(hBs, 1);
    725     }
    726 
    727     for (i = 0; i < pGSet->bandCount; i++) {
    728       if (version == 0) {
    729         *gainSequenceIndex = (*gainSequenceIndex) + 1;
    730       } else {
    731         int indexPresent;
    732         indexPresent = (isBox) ? 1 : FDKreadBits(hBs, 1);
    733         if (indexPresent) {
    734           int bsIndex;
    735           bsIndex = FDKreadBits(hBs, 6);
    736           *gainSequenceIndex = bsIndex;
    737         } else {
    738           *gainSequenceIndex = (*gainSequenceIndex) + 1;
    739         }
    740       }
    741       pGSet->gainSequenceIndex[i] = *gainSequenceIndex;
    742       _readDrcCharacteristic(hBs, version, &(pGSet->drcCharacteristic[i]),
    743                              isBox);
    744     }
    745     for (i = 1; i < pGSet->bandCount; i++) {
    746       _readBandBorder(hBs, &(pGSet->bandBorder[i]), pGSet->drcBandType, isBox);
    747     }
    748   } else {
    749     pGSet->bandCount = 1;
    750     *gainSequenceIndex = (*gainSequenceIndex) + 1;
    751     pGSet->gainSequenceIndex[0] = *gainSequenceIndex;
    752   }
    753 
    754   return DE_OK;
    755 }
    756 
    757 static DRC_ERROR _readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,
    758                                               const CHARACTERISTIC_SIDE side,
    759                                               UCHAR* pCharacteristicFormat,
    760                                               CUSTOM_DRC_CHAR* pCChar,
    761                                               int isBox) {
    762   if (isBox) FDKpushFor(hBs, 7); /* reserved */
    763   *pCharacteristicFormat = FDKreadBits(hBs, 1);
    764   if (*pCharacteristicFormat == CF_SIGMOID) {
    765     int bsGain, bsIoRatio, bsExp;
    766     if (isBox) FDKpushFor(hBs, 1); /* reserved */
    767     bsGain = FDKreadBits(hBs, 6);
    768     if (side == CS_LEFT) {
    769       pCChar->sigmoid.gain = (FIXP_SGL)(bsGain << (FRACT_BITS - 1 - 6));
    770     } else {
    771       pCChar->sigmoid.gain = (FIXP_SGL)(-bsGain << (FRACT_BITS - 1 - 6));
    772     }
    773     bsIoRatio = FDKreadBits(hBs, 4);
    774     /* pCChar->sigmoid.ioRatio = 0.05 + 0.15 * bsIoRatio; */
    775     pCChar->sigmoid.ioRatio =
    776         FL2FXCONST_SGL(0.05f / (float)(1 << 2)) +
    777         (FIXP_SGL)((((3 * bsIoRatio) << (FRACT_BITS - 1)) / 5) >> 4);
    778     bsExp = FDKreadBits(hBs, 4);
    779     if (bsExp < 15) {
    780       pCChar->sigmoid.exp = (FIXP_SGL)((1 + 2 * bsExp) << (FRACT_BITS - 1 - 5));
    781     } else {
    782       pCChar->sigmoid.exp = (FIXP_SGL)MAXVAL_SGL; /* represents infinity */
    783     }
    784     pCChar->sigmoid.flipSign = FDKreadBits(hBs, 1);
    785   } else { /* CF_NODES */
    786     int i, bsCharacteristicNodeCount, bsNodeLevelDelta, bsNodeGain;
    787     if (isBox) FDKpushFor(hBs, 6); /* reserved */
    788     bsCharacteristicNodeCount = FDKreadBits(hBs, 2);
    789     pCChar->nodes.characteristicNodeCount = bsCharacteristicNodeCount + 1;
    790     if (pCChar->nodes.characteristicNodeCount > 4) return DE_MEMORY_ERROR;
    791     pCChar->nodes.nodeLevel[0] = DRC_INPUT_LOUDNESS_TARGET_SGL;
    792     pCChar->nodes.nodeGain[0] = (FIXP_SGL)0;
    793     for (i = 0; i < pCChar->nodes.characteristicNodeCount; i++) {
    794       if (isBox) FDKpushFor(hBs, 3); /* reserved */
    795       bsNodeLevelDelta = FDKreadBits(hBs, 5);
    796       if (side == CS_LEFT) {
    797         pCChar->nodes.nodeLevel[i + 1] =
    798             pCChar->nodes.nodeLevel[i] -
    799             (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
    800       } else {
    801         pCChar->nodes.nodeLevel[i + 1] =
    802             pCChar->nodes.nodeLevel[i] +
    803             (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
    804       }
    805       bsNodeGain = FDKreadBits(hBs, 8);
    806       pCChar->nodes.nodeGain[i + 1] = (FIXP_SGL)(
    807           (bsNodeGain - 128)
    808           << (FRACT_BITS - 1 - 1 - 7)); /* 0.5f * bsNodeGain - 64.0f; */
    809     }
    810   }
    811   return DE_OK;
    812 }
    813 
    814 static void _skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs) {
    815   int i;
    816   int downmixIdPresent, additionalDownmixIdPresent,
    817       additionalDownmixIdCount = 0;
    818   int drcSetIdPresent, additionalDrcSetIdPresent, additionalDrcSetIdCount = 0;
    819   int eqSetIdPresent, additionalEqSetIdPresent, additionalEqSetIdCount = 0;
    820   int loudEqGainSequenceCount, drcCharacteristicFormatIsCICP;
    821 
    822   FDKpushFor(hBs, 4); /* loudEqSetId */
    823   FDKpushFor(hBs, 4); /* drcLocation */
    824   downmixIdPresent = FDKreadBits(hBs, 1);
    825   if (downmixIdPresent) {
    826     FDKpushFor(hBs, 7); /* downmixId */
    827     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
    828     if (additionalDownmixIdPresent) {
    829       additionalDownmixIdCount = FDKreadBits(hBs, 7);
    830       for (i = 0; i < additionalDownmixIdCount; i++) {
    831         FDKpushFor(hBs, 7); /* additionalDownmixId */
    832       }
    833     }
    834   }
    835 
    836   drcSetIdPresent = FDKreadBits(hBs, 1);
    837   if (drcSetIdPresent) {
    838     FDKpushFor(hBs, 6); /* drcSetId */
    839     additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
    840     if (additionalDrcSetIdPresent) {
    841       additionalDrcSetIdCount = FDKreadBits(hBs, 6);
    842       for (i = 0; i < additionalDrcSetIdCount; i++) {
    843         FDKpushFor(hBs, 6); /* additionalDrcSetId; */
    844       }
    845     }
    846   }
    847 
    848   eqSetIdPresent = FDKreadBits(hBs, 1);
    849   if (eqSetIdPresent) {
    850     FDKpushFor(hBs, 6); /* eqSetId */
    851     additionalEqSetIdPresent = FDKreadBits(hBs, 1);
    852     if (additionalEqSetIdPresent) {
    853       additionalEqSetIdCount = FDKreadBits(hBs, 6);
    854       for (i = 0; i < additionalEqSetIdCount; i++) {
    855         FDKpushFor(hBs, 6); /* additionalEqSetId; */
    856       }
    857     }
    858   }
    859 
    860   FDKpushFor(hBs, 1); /* loudnessAfterDrc */
    861   FDKpushFor(hBs, 1); /* loudnessAfterEq */
    862   loudEqGainSequenceCount = FDKreadBits(hBs, 6);
    863   for (i = 0; i < loudEqGainSequenceCount; i++) {
    864     FDKpushFor(hBs, 6); /* gainSequenceIndex */
    865     drcCharacteristicFormatIsCICP = FDKreadBits(hBs, 1);
    866     if (drcCharacteristicFormatIsCICP) {
    867       FDKpushFor(hBs, 7); /* drcCharacteristic */
    868     } else {
    869       FDKpushFor(hBs, 4); /* drcCharacteristicLeftIndex */
    870       FDKpushFor(hBs, 4); /* drcCharacteristicRightIndex */
    871     }
    872     FDKpushFor(hBs, 6); /* frequencyRangeIndex */
    873     FDKpushFor(hBs, 3); /* bsLoudEqScaling */
    874     FDKpushFor(hBs, 5); /* bsLoudEqOffset */
    875   }
    876 }
    877 
    878 static void _skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs) {
    879   int nEqNodes, k, bits;
    880   nEqNodes = FDKreadBits(hBs, 5);
    881   nEqNodes += 2;
    882   for (k = 0; k < nEqNodes; k++) {
    883     bits = FDKreadBits(hBs, 1);
    884     if (!bits) {
    885       FDKpushFor(hBs, 4);
    886     }
    887   }
    888   FDKpushFor(hBs, 4 * (nEqNodes - 1));
    889   bits = FDKreadBits(hBs, 2);
    890   switch (bits) {
    891     case 0:
    892       FDKpushFor(hBs, 5);
    893       break;
    894     case 1:
    895     case 2:
    896       FDKpushFor(hBs, 4);
    897       break;
    898     case 3:
    899       FDKpushFor(hBs, 3);
    900       break;
    901   }
    902   FDKpushFor(hBs, 5 * (nEqNodes - 1));
    903 }
    904 
    905 static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
    906   int j, k;
    907   int eqDelayMaxPresent;
    908   int uniqueFilterBlockCount, filterElementCount, filterElementGainPresent;
    909   int uniqueTdFilterElementCount, eqFilterFormat, bsRealZeroRadiusOneCount,
    910       realZeroCount, genericZeroCount, realPoleCount, complexPoleCount,
    911       firFilterOrder;
    912   int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
    913       eqSubbandGainCount;
    914   EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat;
    915 
    916   eqDelayMaxPresent = FDKreadBits(hBs, 1);
    917   if (eqDelayMaxPresent) {
    918     FDKpushFor(hBs, 8); /* bsEqDelayMax */
    919   }
    920 
    921   uniqueFilterBlockCount = FDKreadBits(hBs, 6);
    922   for (j = 0; j < uniqueFilterBlockCount; j++) {
    923     filterElementCount = FDKreadBits(hBs, 6);
    924     for (k = 0; k < filterElementCount; k++) {
    925       FDKpushFor(hBs, 6); /* filterElementIndex */
    926       filterElementGainPresent = FDKreadBits(hBs, 1);
    927       if (filterElementGainPresent) {
    928         FDKpushFor(hBs, 10); /* bsFilterElementGain */
    929       }
    930     }
    931   }
    932   uniqueTdFilterElementCount = FDKreadBits(hBs, 6);
    933   for (j = 0; j < uniqueTdFilterElementCount; j++) {
    934     eqFilterFormat = FDKreadBits(hBs, 1);
    935     if (eqFilterFormat == 0) { /* pole/zero */
    936       bsRealZeroRadiusOneCount = FDKreadBits(hBs, 3);
    937       realZeroCount = FDKreadBits(hBs, 6);
    938       genericZeroCount = FDKreadBits(hBs, 6);
    939       realPoleCount = FDKreadBits(hBs, 4);
    940       complexPoleCount = FDKreadBits(hBs, 4);
    941       FDKpushFor(hBs, 2 * bsRealZeroRadiusOneCount * 1);
    942       FDKpushFor(hBs, realZeroCount * 8);
    943       FDKpushFor(hBs, genericZeroCount * 14);
    944       FDKpushFor(hBs, realPoleCount * 8);
    945       FDKpushFor(hBs, complexPoleCount * 14);
    946     } else { /* FIR coefficients */
    947       firFilterOrder = FDKreadBits(hBs, 7);
    948       FDKpushFor(hBs, 1);
    949       FDKpushFor(hBs, (firFilterOrder / 2 + 1) * 11);
    950     }
    951   }
    952   uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
    953   if (uniqueEqSubbandGainsCount > 0) {
    954     eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
    955     eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4);
    956     switch (eqSubbandGainFormat) {
    957       case GF_QMF32:
    958         eqSubbandGainCount = 32;
    959         break;
    960       case GF_QMFHYBRID39:
    961         eqSubbandGainCount = 39;
    962         break;
    963       case GF_QMF64:
    964         eqSubbandGainCount = 64;
    965         break;
    966       case GF_QMFHYBRID71:
    967         eqSubbandGainCount = 71;
    968         break;
    969       case GF_QMF128:
    970         eqSubbandGainCount = 128;
    971         break;
    972       case GF_QMFHYBRID135:
    973         eqSubbandGainCount = 135;
    974         break;
    975       case GF_UNIFORM:
    976       default:
    977         eqSubbandGainCount = FDKreadBits(hBs, 8);
    978         eqSubbandGainCount++;
    979         break;
    980     }
    981     for (k = 0; k < uniqueEqSubbandGainsCount; k++) {
    982       if (eqSubbandGainRepresentation == 1) {
    983         _skipEqSubbandGainSpline(hBs);
    984       } else {
    985         FDKpushFor(hBs, eqSubbandGainCount * 9);
    986       }
    987     }
    988   }
    989 }
    990 
    991 static void _skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,
    992                                  const int eqChannelGroupCount) {
    993   int i, eqCascadeGainPresent, filterBlockCount, eqPhaseAlignmentPresent;
    994   for (i = 0; i < eqChannelGroupCount; i++) {
    995     eqCascadeGainPresent = FDKreadBits(hBs, 1);
    996     if (eqCascadeGainPresent) {
    997       FDKpushFor(hBs, 10); /* bsEqCascadeGain */
    998     }
    999     filterBlockCount = FDKreadBits(hBs, 4);
   1000     FDKpushFor(hBs, filterBlockCount * 7); /* filterBlockIndex */
   1001   }
   1002   eqPhaseAlignmentPresent = FDKreadBits(hBs, 1);
   1003   {
   1004     if (eqPhaseAlignmentPresent) {
   1005       for (i = 0; i < eqChannelGroupCount; i++) {
   1006         FDKpushFor(hBs, (eqChannelGroupCount - i - 1) * 1);
   1007       }
   1008     }
   1009   }
   1010 }
   1011 
   1012 static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
   1013                                      HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1014   DRC_ERROR err = DE_OK;
   1015   int c, i, k, channelCount;
   1016   int downmixIdPresent, downmixId, eqApplyToDownmix, additionalDownmixIdPresent,
   1017       additionalDownmixIdCount = 0;
   1018   int additionalDrcSetIdPresent, additionalDrcSetIdCount;
   1019   int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
   1020       subbandGainsPresent, eqTransitionDurationPresent;
   1021 
   1022   FDKpushFor(hBs, 6); /* eqSetId */
   1023   FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
   1024   downmixIdPresent = FDKreadBits(hBs, 1);
   1025   if (downmixIdPresent) {
   1026     downmixId = FDKreadBits(hBs, 7);
   1027     eqApplyToDownmix = FDKreadBits(hBs, 1);
   1028     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1029     if (additionalDownmixIdPresent) {
   1030       additionalDownmixIdCount = FDKreadBits(hBs, 7);
   1031       FDKpushFor(hBs, additionalDownmixIdCount * 7); /* additionalDownmixId */
   1032     }
   1033   } else {
   1034     downmixId = 0;
   1035     eqApplyToDownmix = 0;
   1036   }
   1037   FDKpushFor(hBs, 6); /* drcSetId */
   1038   additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
   1039   if (additionalDrcSetIdPresent) {
   1040     additionalDrcSetIdCount = FDKreadBits(hBs, 6);
   1041     for (i = 0; i < additionalDrcSetIdCount; i++) {
   1042       FDKpushFor(hBs, 6); /* additionalDrcSetId */
   1043     }
   1044   }
   1045   FDKpushFor(hBs, 16); /* eqSetPurpose */
   1046   dependsOnEqSetPresent = FDKreadBits(hBs, 1);
   1047   if (dependsOnEqSetPresent) {
   1048     FDKpushFor(hBs, 6); /* dependsOnEqSet */
   1049   } else {
   1050     FDKpushFor(hBs, 1); /* noIndependentEqUse */
   1051   }
   1052 
   1053   channelCount = hUniDrcConfig->channelLayout.baseChannelCount;
   1054   if ((downmixIdPresent == 1) && (eqApplyToDownmix == 1) && (downmixId != 0) &&
   1055       (downmixId != DOWNMIX_ID_ANY_DOWNMIX) &&
   1056       (additionalDownmixIdCount == 0)) {
   1057     DOWNMIX_INSTRUCTIONS* pDown =
   1058         selectDownmixInstructions(hUniDrcConfig, downmixId);
   1059     if (pDown == NULL) return DE_NOT_OK;
   1060 
   1061     channelCount =
   1062         pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
   1063   } else if ((downmixId == DOWNMIX_ID_ANY_DOWNMIX) ||
   1064              (additionalDownmixIdCount > 1)) {
   1065     channelCount = 1;
   1066   }
   1067 
   1068   eqChannelGroupCount = 0;
   1069   for (c = 0; c < channelCount; c++) {
   1070     UCHAR eqChannelGroupForChannel[8];
   1071     int newGroup = 1;
   1072     if (c >= 8) return DE_MEMORY_ERROR;
   1073     eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
   1074     for (k = 0; k < c; k++) {
   1075       if (eqChannelGroupForChannel[c] == eqChannelGroupForChannel[k]) {
   1076         newGroup = 0;
   1077       }
   1078     }
   1079     if (newGroup == 1) {
   1080       eqChannelGroupCount += 1;
   1081     }
   1082   }
   1083   tdFilterCascadePresent = FDKreadBits(hBs, 1);
   1084   if (tdFilterCascadePresent) {
   1085     _skipTdFilterCascade(hBs, eqChannelGroupCount);
   1086   }
   1087   subbandGainsPresent = FDKreadBits(hBs, 1);
   1088   if (subbandGainsPresent) {
   1089     FDKpushFor(hBs, eqChannelGroupCount * 6); /* subbandGainsIndex */
   1090   }
   1091   eqTransitionDurationPresent = FDKreadBits(hBs, 1);
   1092   if (eqTransitionDurationPresent) {
   1093     FDKpushFor(hBs, 5); /* bsEqTransitionDuration */
   1094   }
   1095   return err;
   1096 }
   1097 
   1098 static void _skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs) {
   1099   FDKpushFor(hBs, 4); /* drcLocation */
   1100   FDKpushFor(hBs, 7); /* drcCharacteristic */
   1101 }
   1102 
   1103 static DRC_ERROR _readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,
   1104                                             const int version,
   1105                                             DRC_COEFFICIENTS_UNI_DRC* pCoef) {
   1106   DRC_ERROR err = DE_OK;
   1107   int i, bsDrcFrameSize;
   1108   int gainSequenceIndex = -1;
   1109 
   1110   pCoef->drcLocation = FDKreadBits(hBs, 4);
   1111   pCoef->drcFrameSizePresent = FDKreadBits(hBs, 1);
   1112 
   1113   if (pCoef->drcFrameSizePresent == 1) {
   1114     bsDrcFrameSize = FDKreadBits(hBs, 15);
   1115     pCoef->drcFrameSize = bsDrcFrameSize + 1;
   1116   }
   1117   if (version == 0) {
   1118     int gainSequenceCount = 0, gainSetCount;
   1119     pCoef->characteristicLeftCount = 0;
   1120     pCoef->characteristicRightCount = 0;
   1121     gainSetCount = FDKreadBits(hBs, 6);
   1122     pCoef->gainSetCount = fMin(gainSetCount, 12);
   1123     for (i = 0; i < gainSetCount; i++) {
   1124       GAIN_SET tmpGset;
   1125       FDKmemclear(&tmpGset, sizeof(GAIN_SET));
   1126       err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
   1127       if (err) return err;
   1128       gainSequenceCount += tmpGset.bandCount;
   1129 
   1130       if (i >= 12) continue;
   1131       pCoef->gainSet[i] = tmpGset;
   1132     }
   1133     pCoef->gainSequenceCount = gainSequenceCount;
   1134   } else { /* (version == 1) */
   1135     UCHAR drcCharacteristicLeftPresent, drcCharacteristicRightPresent;
   1136     UCHAR shapeFiltersPresent, shapeFilterCount, tmpPresent;
   1137     int gainSetCount;
   1138     drcCharacteristicLeftPresent = FDKreadBits(hBs, 1);
   1139     if (drcCharacteristicLeftPresent) {
   1140       pCoef->characteristicLeftCount = FDKreadBits(hBs, 4);
   1141       if ((pCoef->characteristicLeftCount + 1) > 16) return DE_MEMORY_ERROR;
   1142       for (i = 0; i < pCoef->characteristicLeftCount; i++) {
   1143         err = _readCustomDrcCharacteristic(
   1144             hBs, CS_LEFT, &(pCoef->characteristicLeftFormat[i + 1]),
   1145             &(pCoef->customCharacteristicLeft[i + 1]), 0);
   1146         if (err) return err;
   1147       }
   1148     }
   1149     drcCharacteristicRightPresent = FDKreadBits(hBs, 1);
   1150     if (drcCharacteristicRightPresent) {
   1151       pCoef->characteristicRightCount = FDKreadBits(hBs, 4);
   1152       if ((pCoef->characteristicRightCount + 1) > 16) return DE_MEMORY_ERROR;
   1153       for (i = 0; i < pCoef->characteristicRightCount; i++) {
   1154         err = _readCustomDrcCharacteristic(
   1155             hBs, CS_RIGHT, &(pCoef->characteristicRightFormat[i + 1]),
   1156             &(pCoef->customCharacteristicRight[i + 1]), 0);
   1157         if (err) return err;
   1158       }
   1159     }
   1160     shapeFiltersPresent = FDKreadBits(hBs, 1);
   1161     if (shapeFiltersPresent) {
   1162       shapeFilterCount = FDKreadBits(hBs, 4);
   1163       for (i = 0; i < shapeFilterCount; i++) {
   1164         tmpPresent = FDKreadBits(hBs, 1);
   1165         if (tmpPresent) /* lfCutParams */
   1166           FDKpushFor(hBs, 5);
   1167 
   1168         tmpPresent = FDKreadBits(hBs, 1);
   1169         if (tmpPresent) /* lfBoostParams */
   1170           FDKpushFor(hBs, 5);
   1171 
   1172         tmpPresent = FDKreadBits(hBs, 1);
   1173         if (tmpPresent) /* hfCutParams */
   1174           FDKpushFor(hBs, 5);
   1175 
   1176         tmpPresent = FDKreadBits(hBs, 1);
   1177         if (tmpPresent) /* hfBoostParams */
   1178           FDKpushFor(hBs, 5);
   1179       }
   1180     }
   1181     pCoef->gainSequenceCount = FDKreadBits(hBs, 6);
   1182     gainSetCount = FDKreadBits(hBs, 6);
   1183     pCoef->gainSetCount = fMin(gainSetCount, 12);
   1184     for (i = 0; i < gainSetCount; i++) {
   1185       GAIN_SET tmpGset;
   1186       FDKmemclear(&tmpGset, sizeof(GAIN_SET));
   1187       err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
   1188       if (err) return err;
   1189 
   1190       if (i >= 12) continue;
   1191       pCoef->gainSet[i] = tmpGset;
   1192     }
   1193   }
   1194   for (i = 0; i < 12; i++) {
   1195     pCoef->gainSetIndexForGainSequence[i] = 255;
   1196   }
   1197   for (i = 0; i < pCoef->gainSetCount; i++) {
   1198     int b;
   1199     for (b = 0; b < pCoef->gainSet[i].bandCount; b++) {
   1200       if (pCoef->gainSet[i].gainSequenceIndex[b] >= 12) continue;
   1201       pCoef->gainSetIndexForGainSequence[pCoef->gainSet[i]
   1202                                              .gainSequenceIndex[b]] = i;
   1203     }
   1204   }
   1205 
   1206   return err;
   1207 }
   1208 
   1209 static void _skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs) {
   1210   int drcSetEffect;
   1211   int additionalDownmixIdPresent, additionalDownmixIdCount,
   1212       limiterPeakTargetPresent;
   1213   int drcSetTargetLoudnessPresent, drcSetTargetLoudnessValueLowerPresent;
   1214 
   1215   FDKpushFor(hBs, 6); /* drcSetId */
   1216   FDKpushFor(hBs, 4); /* drcLocation */
   1217   FDKpushFor(hBs, 7); /* downmixId */
   1218   additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1219   if (additionalDownmixIdPresent) {
   1220     additionalDownmixIdCount = FDKreadBits(hBs, 3);
   1221     FDKpushFor(hBs, 7 * additionalDownmixIdCount); /* additionalDownmixId */
   1222   }
   1223 
   1224   drcSetEffect = FDKreadBits(hBs, 16);
   1225   if (!(drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF))) {
   1226     limiterPeakTargetPresent = FDKreadBits(hBs, 1);
   1227     if (limiterPeakTargetPresent) {
   1228       FDKpushFor(hBs, 8); /* bsLimiterPeakTarget */
   1229     }
   1230   }
   1231 
   1232   drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
   1233   if (drcSetTargetLoudnessPresent) {
   1234     FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueUpper */
   1235     drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
   1236     if (drcSetTargetLoudnessValueLowerPresent) {
   1237       FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueLower */
   1238     }
   1239   }
   1240 }
   1241 
   1242 static DRC_ERROR _readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,
   1243                                             const int version,
   1244                                             HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
   1245                                             DRC_INSTRUCTIONS_UNI_DRC* pInst) {
   1246   DRC_ERROR err = DE_OK;
   1247   int i, g, c;
   1248   int downmixIdPresent, additionalDownmixIdPresent, additionalDownmixIdCount;
   1249   int bsLimiterPeakTarget, channelCount;
   1250   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
   1251   int repeatParameters, bsRepeatParametersCount;
   1252   int repeatSequenceIndex, bsRepeatSequenceCount;
   1253   SCHAR* gainSetIndex = pInst->gainSetIndex;
   1254   SCHAR channelGroupForChannel[8];
   1255   DUCKING_MODIFICATION duckingModificationForChannelGroup[8];
   1256 
   1257   pInst->drcSetId = FDKreadBits(hBs, 6);
   1258   if (version == 0) {
   1259     /* Assume all v0 DRC sets to be manageable in terms of complexity */
   1260     pInst->drcSetComplexityLevel = 2;
   1261   } else {
   1262     pInst->drcSetComplexityLevel = FDKreadBits(hBs, 4);
   1263   }
   1264   pInst->drcLocation = FDKreadBits(hBs, 4);
   1265   if (version == 0) {
   1266     downmixIdPresent = 1;
   1267   } else {
   1268     downmixIdPresent = FDKreadBits(hBs, 1);
   1269   }
   1270   if (downmixIdPresent) {
   1271     pInst->downmixId[0] = FDKreadBits(hBs, 7);
   1272     if (version == 0) {
   1273       if (pInst->downmixId[0] == 0)
   1274         pInst->drcApplyToDownmix = 0;
   1275       else
   1276         pInst->drcApplyToDownmix = 1;
   1277     } else {
   1278       pInst->drcApplyToDownmix = FDKreadBits(hBs, 1);
   1279     }
   1280 
   1281     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1282     if (additionalDownmixIdPresent) {
   1283       additionalDownmixIdCount = FDKreadBits(hBs, 3);
   1284       if ((1 + additionalDownmixIdCount) > 8) return DE_MEMORY_ERROR;
   1285       for (i = 0; i < additionalDownmixIdCount; i++) {
   1286         pInst->downmixId[i + 1] = FDKreadBits(hBs, 7);
   1287       }
   1288       pInst->downmixIdCount = 1 + additionalDownmixIdCount;
   1289     } else {
   1290       pInst->downmixIdCount = 1;
   1291     }
   1292   } else {
   1293     pInst->downmixId[0] = 0;
   1294     pInst->downmixIdCount = 1;
   1295   }
   1296 
   1297   pInst->drcSetEffect = FDKreadBits(hBs, 16);
   1298 
   1299   if ((pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) {
   1300     pInst->limiterPeakTargetPresent = FDKreadBits(hBs, 1);
   1301     if (pInst->limiterPeakTargetPresent) {
   1302       bsLimiterPeakTarget = FDKreadBits(hBs, 8);
   1303       pInst->limiterPeakTarget = -(FIXP_SGL)(
   1304           bsLimiterPeakTarget
   1305           << (FRACT_BITS - 1 - 3 - 5)); /* - bsLimiterPeakTarget * 0.125; */
   1306     }
   1307   }
   1308 
   1309   pInst->drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
   1310 
   1311   /* set default values */
   1312   pInst->drcSetTargetLoudnessValueUpper = 0;
   1313   pInst->drcSetTargetLoudnessValueLower = -63;
   1314 
   1315   if (pInst->drcSetTargetLoudnessPresent == 1) {
   1316     int bsDrcSetTargetLoudnessValueUpper, bsDrcSetTargetLoudnessValueLower;
   1317     int drcSetTargetLoudnessValueLowerPresent;
   1318     bsDrcSetTargetLoudnessValueUpper = FDKreadBits(hBs, 6);
   1319     pInst->drcSetTargetLoudnessValueUpper =
   1320         bsDrcSetTargetLoudnessValueUpper - 63;
   1321     drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
   1322     if (drcSetTargetLoudnessValueLowerPresent == 1) {
   1323       bsDrcSetTargetLoudnessValueLower = FDKreadBits(hBs, 6);
   1324       pInst->drcSetTargetLoudnessValueLower =
   1325           bsDrcSetTargetLoudnessValueLower - 63;
   1326     }
   1327   }
   1328 
   1329   pInst->dependsOnDrcSetPresent = FDKreadBits(hBs, 1);
   1330 
   1331   pInst->noIndependentUse = 0;
   1332   if (pInst->dependsOnDrcSetPresent) {
   1333     pInst->dependsOnDrcSet = FDKreadBits(hBs, 6);
   1334   } else {
   1335     pInst->noIndependentUse = FDKreadBits(hBs, 1);
   1336   }
   1337 
   1338   if (version == 0) {
   1339     pInst->requiresEq = 0;
   1340   } else {
   1341     pInst->requiresEq = FDKreadBits(hBs, 1);
   1342   }
   1343 
   1344   pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
   1345 
   1346   pInst->drcChannelCount = channelCount =
   1347       hUniDrcConfig->channelLayout.baseChannelCount;
   1348 
   1349   if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
   1350     DUCKING_MODIFICATION* pDModForChannel =
   1351         pInst->duckingModificationForChannel;
   1352     c = 0;
   1353     while (c < channelCount) {
   1354       int bsGainSetIndex;
   1355       bsGainSetIndex = FDKreadBits(hBs, 6);
   1356       if (c >= 8) return DE_MEMORY_ERROR;
   1357       gainSetIndex[c] = bsGainSetIndex - 1;
   1358       _decodeDuckingModification(hBs, &(pDModForChannel[c]), 0);
   1359 
   1360       c++;
   1361       repeatParameters = FDKreadBits(hBs, 1);
   1362       if (repeatParameters == 1) {
   1363         bsRepeatParametersCount = FDKreadBits(hBs, 5);
   1364         bsRepeatParametersCount += 1;
   1365         for (i = 0; i < bsRepeatParametersCount; i++) {
   1366           if (c >= 8) return DE_MEMORY_ERROR;
   1367           gainSetIndex[c] = gainSetIndex[c - 1];
   1368           pDModForChannel[c] = pDModForChannel[c - 1];
   1369           c++;
   1370         }
   1371       }
   1372     }
   1373     if (c > channelCount) {
   1374       return DE_NOT_OK;
   1375     }
   1376 
   1377     err = deriveDrcChannelGroups(
   1378         pInst->drcSetEffect, pInst->drcChannelCount, gainSetIndex,
   1379         pDModForChannel, &pInst->nDrcChannelGroups,
   1380         pInst->gainSetIndexForChannelGroup, channelGroupForChannel,
   1381         duckingModificationForChannelGroup);
   1382     if (err) return (err);
   1383   } else {
   1384     int deriveChannelCount = 0;
   1385     if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
   1386         (pInst->downmixId[0] != DOWNMIX_ID_BASE_LAYOUT) &&
   1387         (pInst->downmixId[0] != DOWNMIX_ID_ANY_DOWNMIX) &&
   1388         (pInst->downmixIdCount == 1)) {
   1389       if (hUniDrcConfig->downmixInstructionsCount != 0) {
   1390         DOWNMIX_INSTRUCTIONS* pDown =
   1391             selectDownmixInstructions(hUniDrcConfig, pInst->downmixId[0]);
   1392         if (pDown == NULL) return DE_NOT_OK;
   1393         pInst->drcChannelCount = channelCount =
   1394             pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
   1395       } else {
   1396         deriveChannelCount = 1;
   1397         channelCount = 1;
   1398       }
   1399     } else if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
   1400                ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
   1401                 (pInst->downmixIdCount > 1))) {
   1402       /* Set maximum channel count as upper border. The effective channel count
   1403        * is set at the process function. */
   1404       pInst->drcChannelCount = 8;
   1405       channelCount = 1;
   1406     }
   1407 
   1408     c = 0;
   1409     while (c < channelCount) {
   1410       int bsGainSetIndex;
   1411       bsGainSetIndex = FDKreadBits(hBs, 6);
   1412       if (c >= 8) return DE_MEMORY_ERROR;
   1413       gainSetIndex[c] = bsGainSetIndex - 1;
   1414       c++;
   1415       repeatSequenceIndex = FDKreadBits(hBs, 1);
   1416 
   1417       if (repeatSequenceIndex == 1) {
   1418         bsRepeatSequenceCount = FDKreadBits(hBs, 5);
   1419         bsRepeatSequenceCount += 1;
   1420         if (deriveChannelCount) {
   1421           channelCount = 1 + bsRepeatSequenceCount;
   1422         }
   1423         for (i = 0; i < bsRepeatSequenceCount; i++) {
   1424           if (c >= 8) return DE_MEMORY_ERROR;
   1425           gainSetIndex[c] = bsGainSetIndex - 1;
   1426           c++;
   1427         }
   1428       }
   1429     }
   1430     if (c > channelCount) {
   1431       return DE_NOT_OK;
   1432     }
   1433     if (deriveChannelCount) {
   1434       pInst->drcChannelCount = channelCount;
   1435     }
   1436 
   1437     /* DOWNMIX_ID_ANY_DOWNMIX: channelCount is 1. Distribute gainSetIndex to all
   1438      * channels. */
   1439     if ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
   1440         (pInst->downmixIdCount > 1)) {
   1441       for (c = 1; c < pInst->drcChannelCount; c++) {
   1442         gainSetIndex[c] = gainSetIndex[0];
   1443       }
   1444     }
   1445 
   1446     err = deriveDrcChannelGroups(pInst->drcSetEffect, pInst->drcChannelCount,
   1447                                  gainSetIndex, NULL, &pInst->nDrcChannelGroups,
   1448                                  pInst->gainSetIndexForChannelGroup,
   1449                                  channelGroupForChannel, NULL);
   1450     if (err) return (err);
   1451 
   1452     for (g = 0; g < pInst->nDrcChannelGroups; g++) {
   1453       int set, bandCount;
   1454       set = pInst->gainSetIndexForChannelGroup[g];
   1455 
   1456       /* get bandCount */
   1457       if (pCoef != NULL && set < pCoef->gainSetCount) {
   1458         bandCount = pCoef->gainSet[set].bandCount;
   1459       } else {
   1460         bandCount = 1;
   1461       }
   1462 
   1463       _decodeGainModification(hBs, version, bandCount,
   1464                               pInst->gainModificationForChannelGroup[g], 0);
   1465     }
   1466   }
   1467 
   1468   return err;
   1469 }
   1470 
   1471 static DRC_ERROR _readChannelLayout(HANDLE_FDK_BITSTREAM hBs,
   1472                                     CHANNEL_LAYOUT* pChan) {
   1473   DRC_ERROR err = DE_OK;
   1474 
   1475   pChan->baseChannelCount = FDKreadBits(hBs, 7);
   1476 
   1477   if (pChan->baseChannelCount > 8) return DE_NOT_OK;
   1478 
   1479   pChan->layoutSignalingPresent = FDKreadBits(hBs, 1);
   1480 
   1481   if (pChan->layoutSignalingPresent) {
   1482     pChan->definedLayout = FDKreadBits(hBs, 8);
   1483 
   1484     if (pChan->definedLayout == 0) {
   1485       int i;
   1486       for (i = 0; i < pChan->baseChannelCount; i++) {
   1487         if (i < 8) {
   1488           pChan->speakerPosition[i] = FDKreadBits(hBs, 7);
   1489         } else {
   1490           FDKpushFor(hBs, 7);
   1491         }
   1492       }
   1493     }
   1494   }
   1495   return err;
   1496 }
   1497 
   1498 static DRC_ERROR _readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,
   1499                                           const int version,
   1500                                           CHANNEL_LAYOUT* pChan,
   1501                                           DOWNMIX_INSTRUCTIONS* pDown) {
   1502   DRC_ERROR err = DE_OK;
   1503 
   1504   pDown->downmixId = FDKreadBits(hBs, 7);
   1505   pDown->targetChannelCount = FDKreadBits(hBs, 7);
   1506   pDown->targetLayout = FDKreadBits(hBs, 8);
   1507   pDown->downmixCoefficientsPresent = FDKreadBits(hBs, 1);
   1508 
   1509   if (pDown->downmixCoefficientsPresent) {
   1510     int nDownmixCoeffs = pDown->targetChannelCount * pChan->baseChannelCount;
   1511     int i;
   1512     if (nDownmixCoeffs > 8 * 8) return DE_NOT_OK;
   1513     if (version == 0) {
   1514       pDown->bsDownmixOffset = 0;
   1515       for (i = 0; i < nDownmixCoeffs; i++) {
   1516         /* LFE downmix coefficients are not supported. */
   1517         pDown->downmixCoefficient[i] = downmixCoeff[FDKreadBits(hBs, 4)];
   1518       }
   1519     } else {
   1520       pDown->bsDownmixOffset = FDKreadBits(hBs, 4);
   1521       for (i = 0; i < nDownmixCoeffs; i++) {
   1522         pDown->downmixCoefficient[i] = downmixCoeffV1[FDKreadBits(hBs, 5)];
   1523       }
   1524     }
   1525   }
   1526   return err;
   1527 }
   1528 
   1529 static DRC_ERROR _readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,
   1530                                      HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1531   DRC_ERROR err = DE_OK;
   1532   int downmixInstructionsV1Present;
   1533   int drcCoeffsAndInstructionsUniDrcV1Present;
   1534   int loudEqInstructionsPresent, loudEqInstructionsCount;
   1535   int eqPresent, eqInstructionsCount;
   1536   int i, offset;
   1537   int diff = hUniDrcConfig->diff;
   1538 
   1539   downmixInstructionsV1Present = FDKreadBits(hBs, 1);
   1540   if (downmixInstructionsV1Present == 1) {
   1541     diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1,
   1542                         FDKreadBits(hBs, 7));
   1543     offset = hUniDrcConfig->downmixInstructionsCountV0;
   1544     hUniDrcConfig->downmixInstructionsCount = fMin(
   1545         (UCHAR)(offset + hUniDrcConfig->downmixInstructionsCountV1), (UCHAR)6);
   1546     for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV1; i++) {
   1547       DOWNMIX_INSTRUCTIONS tmpDown;
   1548       FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
   1549       err = _readDownmixInstructions(hBs, 1, &hUniDrcConfig->channelLayout,
   1550                                      &tmpDown);
   1551       if (err) return err;
   1552       if ((offset + i) >= 6) continue;
   1553       if (!diff)
   1554         diff |= (FDKmemcmp(&tmpDown,
   1555                            &(hUniDrcConfig->downmixInstructions[offset + i]),
   1556                            sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
   1557       hUniDrcConfig->downmixInstructions[offset + i] = tmpDown;
   1558     }
   1559   } else {
   1560     diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1, 0);
   1561   }
   1562 
   1563   drcCoeffsAndInstructionsUniDrcV1Present = FDKreadBits(hBs, 1);
   1564   if (drcCoeffsAndInstructionsUniDrcV1Present == 1) {
   1565     diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1,
   1566                         FDKreadBits(hBs, 3));
   1567     offset = hUniDrcConfig->drcCoefficientsUniDrcCountV0;
   1568     hUniDrcConfig->drcCoefficientsUniDrcCount =
   1569         fMin((UCHAR)(offset + hUniDrcConfig->drcCoefficientsUniDrcCountV1),
   1570              (UCHAR)2);
   1571     for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV1; i++) {
   1572       DRC_COEFFICIENTS_UNI_DRC tmpCoef;
   1573       FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
   1574       err = _readDrcCoefficientsUniDrc(hBs, 1, &tmpCoef);
   1575       if (err) return err;
   1576       if ((offset + i) >= 2) continue;
   1577       if (!diff)
   1578         diff |= (FDKmemcmp(&tmpCoef,
   1579                            &(hUniDrcConfig->drcCoefficientsUniDrc[offset + i]),
   1580                            sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
   1581       hUniDrcConfig->drcCoefficientsUniDrc[offset + i] = tmpCoef;
   1582     }
   1583 
   1584     diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1,
   1585                         FDKreadBits(hBs, 6));
   1586     offset = hUniDrcConfig->drcInstructionsUniDrcCount;
   1587     hUniDrcConfig->drcInstructionsUniDrcCount =
   1588         fMin((UCHAR)(offset + hUniDrcConfig->drcInstructionsUniDrcCountV1),
   1589              (UCHAR)12);
   1590     for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
   1591       DRC_INSTRUCTIONS_UNI_DRC tmpInst;
   1592       FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
   1593       err = _readDrcInstructionsUniDrc(hBs, 1, hUniDrcConfig, &tmpInst);
   1594       if (err) return err;
   1595       if ((offset + i) >= 12) continue;
   1596       if (!diff)
   1597         diff |= (FDKmemcmp(&tmpInst,
   1598                            &(hUniDrcConfig->drcInstructionsUniDrc[offset + i]),
   1599                            sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
   1600       hUniDrcConfig->drcInstructionsUniDrc[offset + i] = tmpInst;
   1601     }
   1602   } else {
   1603     diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1, 0);
   1604     diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1, 0);
   1605   }
   1606 
   1607   loudEqInstructionsPresent = FDKreadBits(hBs, 1);
   1608   if (loudEqInstructionsPresent == 1) {
   1609     loudEqInstructionsCount = FDKreadBits(hBs, 4);
   1610     for (i = 0; i < loudEqInstructionsCount; i++) {
   1611       _skipLoudEqInstructions(hBs);
   1612     }
   1613   }
   1614 
   1615   eqPresent = FDKreadBits(hBs, 1);
   1616   if (eqPresent == 1) {
   1617     _skipEqCoefficients(hBs);
   1618     eqInstructionsCount = FDKreadBits(hBs, 4);
   1619     for (i = 0; i < eqInstructionsCount; i++) {
   1620       _skipEqInstructions(hBs, hUniDrcConfig);
   1621     }
   1622   }
   1623 
   1624   hUniDrcConfig->diff = diff;
   1625 
   1626   return err;
   1627 }
   1628 
   1629 static DRC_ERROR _readUniDrcConfigExtension(
   1630     HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1631   DRC_ERROR err = DE_OK;
   1632   int k, bitSizeLen, extSizeBits, bitSize;
   1633   INT nBitsRemaining;
   1634   UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt);
   1635 
   1636   k = 0;
   1637   pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
   1638   while (pExt->uniDrcConfigExtType[k] != UNIDRCCONFEXT_TERM) {
   1639     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
   1640     bitSizeLen = FDKreadBits(hBs, 4);
   1641     extSizeBits = bitSizeLen + 4;
   1642 
   1643     bitSize = FDKreadBits(hBs, extSizeBits);
   1644     pExt->extBitSize[k] = bitSize + 1;
   1645     nBitsRemaining = (INT)FDKgetValidBits(hBs);
   1646 
   1647     switch (pExt->uniDrcConfigExtType[k]) {
   1648       case UNIDRCCONFEXT_V1:
   1649         err = _readDrcExtensionV1(hBs, hUniDrcConfig);
   1650         if (err) return err;
   1651         if (nBitsRemaining !=
   1652             ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
   1653           return DE_NOT_OK;
   1654         break;
   1655       case UNIDRCCONFEXT_PARAM_DRC:
   1656       /* add future extensions here */
   1657       default:
   1658         FDKpushFor(hBs, pExt->extBitSize[k]);
   1659         break;
   1660     }
   1661     k++;
   1662     pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
   1663   }
   1664 
   1665   return err;
   1666 }
   1667 
   1668 DRC_ERROR
   1669 drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
   1670                         HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1671   DRC_ERROR err = DE_OK;
   1672   int i, diff = 0;
   1673   int drcDescriptionBasicPresent, drcCoefficientsBasicCount,
   1674       drcInstructionsBasicCount;
   1675   CHANNEL_LAYOUT tmpChan;
   1676   FDKmemclear(&tmpChan, sizeof(CHANNEL_LAYOUT));
   1677   if (hUniDrcConfig == NULL) return DE_NOT_OK;
   1678 
   1679   diff |= _compAssign(&hUniDrcConfig->sampleRatePresent, FDKreadBits(hBs, 1));
   1680 
   1681   if (hUniDrcConfig->sampleRatePresent == 1) {
   1682     diff |=
   1683         _compAssign(&hUniDrcConfig->sampleRate, FDKreadBits(hBs, 18) + 1000);
   1684   }
   1685 
   1686   diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV0,
   1687                       FDKreadBits(hBs, 7));
   1688 
   1689   drcDescriptionBasicPresent = FDKreadBits(hBs, 1);
   1690   if (drcDescriptionBasicPresent == 1) {
   1691     drcCoefficientsBasicCount = FDKreadBits(hBs, 3);
   1692     drcInstructionsBasicCount = FDKreadBits(hBs, 4);
   1693   } else {
   1694     drcCoefficientsBasicCount = 0;
   1695     drcInstructionsBasicCount = 0;
   1696   }
   1697 
   1698   diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV0,
   1699                       FDKreadBits(hBs, 3));
   1700   diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV0,
   1701                       FDKreadBits(hBs, 6));
   1702 
   1703   err = _readChannelLayout(hBs, &tmpChan);
   1704   if (err) return err;
   1705 
   1706   if (!diff)
   1707     diff |= (FDKmemcmp(&tmpChan, &hUniDrcConfig->channelLayout,
   1708                        sizeof(CHANNEL_LAYOUT)) != 0);
   1709   hUniDrcConfig->channelLayout = tmpChan;
   1710 
   1711   hUniDrcConfig->downmixInstructionsCount =
   1712       fMin(hUniDrcConfig->downmixInstructionsCountV0, (UCHAR)6);
   1713   for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV0; i++) {
   1714     DOWNMIX_INSTRUCTIONS tmpDown;
   1715     FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
   1716     err = _readDownmixInstructions(hBs, 0, &hUniDrcConfig->channelLayout,
   1717                                    &tmpDown);
   1718     if (err) return err;
   1719     if (i >= 6) continue;
   1720     if (!diff)
   1721       diff |= (FDKmemcmp(&tmpDown, &(hUniDrcConfig->downmixInstructions[i]),
   1722                          sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
   1723     hUniDrcConfig->downmixInstructions[i] = tmpDown;
   1724   }
   1725 
   1726   for (i = 0; i < drcCoefficientsBasicCount; i++) {
   1727     _skipDrcCoefficientsBasic(hBs);
   1728   }
   1729   for (i = 0; i < drcInstructionsBasicCount; i++) {
   1730     _skipDrcInstructionsBasic(hBs);
   1731   }
   1732 
   1733   hUniDrcConfig->drcCoefficientsUniDrcCount =
   1734       fMin(hUniDrcConfig->drcCoefficientsUniDrcCountV0, (UCHAR)2);
   1735   for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV0; i++) {
   1736     DRC_COEFFICIENTS_UNI_DRC tmpCoef;
   1737     FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
   1738     err = _readDrcCoefficientsUniDrc(hBs, 0, &tmpCoef);
   1739     if (err) return err;
   1740     if (i >= 2) continue;
   1741     if (!diff)
   1742       diff |= (FDKmemcmp(&tmpCoef, &(hUniDrcConfig->drcCoefficientsUniDrc[i]),
   1743                          sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
   1744     hUniDrcConfig->drcCoefficientsUniDrc[i] = tmpCoef;
   1745   }
   1746 
   1747   hUniDrcConfig->drcInstructionsUniDrcCount =
   1748       fMin(hUniDrcConfig->drcInstructionsUniDrcCountV0, (UCHAR)12);
   1749   for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCountV0; i++) {
   1750     DRC_INSTRUCTIONS_UNI_DRC tmpInst;
   1751     FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
   1752     err = _readDrcInstructionsUniDrc(hBs, 0, hUniDrcConfig, &tmpInst);
   1753     if (err) return err;
   1754     if (i >= 12) continue;
   1755     if (!diff)
   1756       diff |= (FDKmemcmp(&tmpInst, &(hUniDrcConfig->drcInstructionsUniDrc[i]),
   1757                          sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
   1758     hUniDrcConfig->drcInstructionsUniDrc[i] = tmpInst;
   1759   }
   1760 
   1761   diff |=
   1762       _compAssign(&hUniDrcConfig->uniDrcConfigExtPresent, FDKreadBits(hBs, 1));
   1763   hUniDrcConfig->diff = diff;
   1764 
   1765   if (hUniDrcConfig->uniDrcConfigExtPresent == 1) {
   1766     err = _readUniDrcConfigExtension(hBs, hUniDrcConfig);
   1767     if (err) return err;
   1768   }
   1769 
   1770   return err;
   1771 }
   1772 
   1773 /*******************/
   1774 /* loudnessInfoSet */
   1775 /*******************/
   1776 
   1777 static DRC_ERROR _decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,
   1778                                     const UCHAR methodDefinition,
   1779                                     FIXP_DBL* methodValue, INT isBox) {
   1780   int tmp;
   1781   FIXP_DBL val;
   1782   switch (methodDefinition) {
   1783     case MD_UNKNOWN_OTHER:
   1784     case MD_PROGRAM_LOUDNESS:
   1785     case MD_ANCHOR_LOUDNESS:
   1786     case MD_MAX_OF_LOUDNESS_RANGE:
   1787     case MD_MOMENTARY_LOUDNESS_MAX:
   1788     case MD_SHORT_TERM_LOUDNESS_MAX:
   1789       tmp = FDKreadBits(hBs, 8);
   1790       val = FL2FXCONST_DBL(-57.75f / (float)(1 << 7)) +
   1791             (FIXP_DBL)(
   1792                 tmp << (DFRACT_BITS - 1 - 2 - 7)); /* -57.75 + tmp * 0.25; */
   1793       break;
   1794     case MD_LOUDNESS_RANGE:
   1795       tmp = FDKreadBits(hBs, 8);
   1796       if (tmp == 0)
   1797         val = (FIXP_DBL)0;
   1798       else if (tmp <= 128)
   1799         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 2 - 7)); /* tmp * 0.25; */
   1800       else if (tmp <= 204) {
   1801         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 1 - 7)) -
   1802               FL2FXCONST_DBL(32.0f / (float)(1 << 7)); /* 0.5 * tmp - 32.0f; */
   1803       } else {
   1804         /* downscale by 1 more bit to prevent overflow at intermediate result */
   1805         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 8)) -
   1806               FL2FXCONST_DBL(134.0f / (float)(1 << 8)); /* tmp - 134.0; */
   1807         val <<= 1;
   1808       }
   1809       break;
   1810     case MD_MIXING_LEVEL:
   1811       tmp = FDKreadBits(hBs, isBox ? 8 : 5);
   1812       val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)) +
   1813             FL2FXCONST_DBL(80.0f / (float)(1 << 7)); /* tmp + 80.0; */
   1814       break;
   1815     case MD_ROOM_TYPE:
   1816       tmp = FDKreadBits(hBs, isBox ? 8 : 2);
   1817       val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)); /* tmp; */
   1818       break;
   1819     case MD_SHORT_TERM_LOUDNESS:
   1820       tmp = FDKreadBits(hBs, 8);
   1821       val = FL2FXCONST_DBL(-116.0f / (float)(1 << 7)) +
   1822             (FIXP_DBL)(
   1823                 tmp << (DFRACT_BITS - 1 - 1 - 7)); /* -116.0 + tmp * 0.5; */
   1824       break;
   1825     default:
   1826       return DE_NOT_OK; /* invalid methodDefinition value */
   1827   }
   1828   *methodValue = val;
   1829   return DE_OK;
   1830 }
   1831 
   1832 static DRC_ERROR _readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,
   1833                                           LOUDNESS_MEASUREMENT* pMeas) {
   1834   DRC_ERROR err = DE_OK;
   1835 
   1836   pMeas->methodDefinition = FDKreadBits(hBs, 4);
   1837   err =
   1838       _decodeMethodValue(hBs, pMeas->methodDefinition, &pMeas->methodValue, 0);
   1839   if (err) return err;
   1840   pMeas->measurementSystem = FDKreadBits(hBs, 4);
   1841   pMeas->reliability = FDKreadBits(hBs, 2);
   1842 
   1843   return err;
   1844 }
   1845 
   1846 static DRC_ERROR _readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs, const int version,
   1847                                    LOUDNESS_INFO* loudnessInfo) {
   1848   DRC_ERROR err = DE_OK;
   1849   int bsSamplePeakLevel, bsTruePeakLevel, i;
   1850   int measurementCount;
   1851 
   1852   loudnessInfo->drcSetId = FDKreadBits(hBs, 6);
   1853   if (version >= 1) {
   1854     loudnessInfo->eqSetId = FDKreadBits(hBs, 6);
   1855   } else {
   1856     loudnessInfo->eqSetId = 0;
   1857   }
   1858   loudnessInfo->downmixId = FDKreadBits(hBs, 7);
   1859 
   1860   loudnessInfo->samplePeakLevelPresent = FDKreadBits(hBs, 1);
   1861   if (loudnessInfo->samplePeakLevelPresent) {
   1862     bsSamplePeakLevel = FDKreadBits(hBs, 12);
   1863     if (bsSamplePeakLevel == 0) {
   1864       loudnessInfo->samplePeakLevelPresent = 0;
   1865       loudnessInfo->samplePeakLevel = (FIXP_DBL)0;
   1866     } else { /* 20.0 - bsSamplePeakLevel * 0.03125; */
   1867       loudnessInfo->samplePeakLevel =
   1868           FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
   1869           (FIXP_DBL)(bsSamplePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
   1870     }
   1871   }
   1872 
   1873   loudnessInfo->truePeakLevelPresent = FDKreadBits(hBs, 1);
   1874   if (loudnessInfo->truePeakLevelPresent) {
   1875     bsTruePeakLevel = FDKreadBits(hBs, 12);
   1876     if (bsTruePeakLevel == 0) {
   1877       loudnessInfo->truePeakLevelPresent = 0;
   1878       loudnessInfo->truePeakLevel = (FIXP_DBL)0;
   1879     } else {
   1880       loudnessInfo->truePeakLevel =
   1881           FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
   1882           (FIXP_DBL)(bsTruePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
   1883     }
   1884     loudnessInfo->truePeakLevelMeasurementSystem = FDKreadBits(hBs, 4);
   1885     loudnessInfo->truePeakLevelReliability = FDKreadBits(hBs, 2);
   1886   }
   1887 
   1888   measurementCount = FDKreadBits(hBs, 4);
   1889   loudnessInfo->measurementCount = fMin(measurementCount, 8);
   1890   for (i = 0; i < measurementCount; i++) {
   1891     LOUDNESS_MEASUREMENT tmpMeas;
   1892     FDKmemclear(&tmpMeas, sizeof(LOUDNESS_MEASUREMENT));
   1893     err = _readLoudnessMeasurement(hBs, &tmpMeas);
   1894     if (err) return err;
   1895     if (i >= 8) continue;
   1896     loudnessInfo->loudnessMeasurement[i] = tmpMeas;
   1897   }
   1898 
   1899   return err;
   1900 }
   1901 
   1902 static DRC_ERROR _readLoudnessInfoSetExtEq(
   1903     HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1904   DRC_ERROR err = DE_OK;
   1905   int i, offset;
   1906   int diff = hLoudnessInfoSet->diff;
   1907 
   1908   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV1,
   1909                       FDKreadBits(hBs, 6));
   1910   diff |=
   1911       _compAssign(&hLoudnessInfoSet->loudnessInfoCountV1, FDKreadBits(hBs, 6));
   1912 
   1913   offset = hLoudnessInfoSet->loudnessInfoAlbumCountV0;
   1914   hLoudnessInfoSet->loudnessInfoAlbumCount = fMin(
   1915       (UCHAR)(offset + hLoudnessInfoSet->loudnessInfoAlbumCountV1), (UCHAR)12);
   1916   for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV1; i++) {
   1917     LOUDNESS_INFO tmpLoud;
   1918     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   1919     err = _readLoudnessInfo(hBs, 1, &tmpLoud);
   1920     if (err) return err;
   1921     if ((offset + i) >= 12) continue;
   1922     if (!diff)
   1923       diff |= (FDKmemcmp(&tmpLoud,
   1924                          &(hLoudnessInfoSet->loudnessInfoAlbum[offset + i]),
   1925                          sizeof(LOUDNESS_INFO)) != 0);
   1926     hLoudnessInfoSet->loudnessInfoAlbum[offset + i] = tmpLoud;
   1927   }
   1928 
   1929   offset = hLoudnessInfoSet->loudnessInfoCountV0;
   1930   hLoudnessInfoSet->loudnessInfoCount =
   1931       fMin((UCHAR)(offset + hLoudnessInfoSet->loudnessInfoCountV1), (UCHAR)12);
   1932   for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV1; i++) {
   1933     LOUDNESS_INFO tmpLoud;
   1934     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   1935     err = _readLoudnessInfo(hBs, 1, &tmpLoud);
   1936     if (err) return err;
   1937     if ((offset + i) >= 12) continue;
   1938     if (!diff)
   1939       diff |=
   1940           (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[offset + i]),
   1941                      sizeof(LOUDNESS_INFO)) != 0);
   1942     hLoudnessInfoSet->loudnessInfo[offset + i] = tmpLoud;
   1943   }
   1944   hLoudnessInfoSet->diff = diff;
   1945   return err;
   1946 }
   1947 
   1948 static DRC_ERROR _readLoudnessInfoSetExtension(
   1949     HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1950   DRC_ERROR err = DE_OK;
   1951   int k, bitSizeLen, extSizeBits, bitSize;
   1952   INT nBitsRemaining;
   1953   LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt);
   1954 
   1955   k = 0;
   1956   pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
   1957   while (pExt->loudnessInfoSetExtType[k] != UNIDRCLOUDEXT_TERM) {
   1958     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
   1959     bitSizeLen = FDKreadBits(hBs, 4);
   1960     extSizeBits = bitSizeLen + 4;
   1961 
   1962     bitSize = FDKreadBits(hBs, extSizeBits);
   1963     pExt->extBitSize[k] = bitSize + 1;
   1964     nBitsRemaining = (INT)FDKgetValidBits(hBs);
   1965 
   1966     switch (pExt->loudnessInfoSetExtType[k]) {
   1967       case UNIDRCLOUDEXT_EQ:
   1968         err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet);
   1969         if (err) return err;
   1970         if (nBitsRemaining !=
   1971             ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
   1972           return DE_NOT_OK;
   1973         break;
   1974       /* add future extensions here */
   1975       default:
   1976         FDKpushFor(hBs, pExt->extBitSize[k]);
   1977         break;
   1978     }
   1979     k++;
   1980     pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
   1981   }
   1982 
   1983   return err;
   1984 }
   1985 
   1986 /* Parser for loundessInfoSet() */
   1987 DRC_ERROR
   1988 drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
   1989                            HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1990   DRC_ERROR err = DE_OK;
   1991   int i, diff = 0;
   1992   if (hLoudnessInfoSet == NULL) return DE_NOT_OK;
   1993 
   1994   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV0,
   1995                       FDKreadBits(hBs, 6));
   1996   diff |=
   1997       _compAssign(&hLoudnessInfoSet->loudnessInfoCountV0, FDKreadBits(hBs, 6));
   1998 
   1999   hLoudnessInfoSet->loudnessInfoAlbumCount =
   2000       fMin(hLoudnessInfoSet->loudnessInfoAlbumCountV0, (UCHAR)12);
   2001   for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV0; i++) {
   2002     LOUDNESS_INFO tmpLoud;
   2003     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   2004     err = _readLoudnessInfo(hBs, 0, &tmpLoud);
   2005     if (err) return err;
   2006     if (i >= 12) continue;
   2007     if (!diff)
   2008       diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfoAlbum[i]),
   2009                          sizeof(LOUDNESS_INFO)) != 0);
   2010     hLoudnessInfoSet->loudnessInfoAlbum[i] = tmpLoud;
   2011   }
   2012 
   2013   hLoudnessInfoSet->loudnessInfoCount =
   2014       fMin(hLoudnessInfoSet->loudnessInfoCountV0, (UCHAR)12);
   2015   for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV0; i++) {
   2016     LOUDNESS_INFO tmpLoud;
   2017     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   2018     err = _readLoudnessInfo(hBs, 0, &tmpLoud);
   2019     if (err) return err;
   2020     if (i >= 12) continue;
   2021     if (!diff)
   2022       diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[i]),
   2023                          sizeof(LOUDNESS_INFO)) != 0);
   2024     hLoudnessInfoSet->loudnessInfo[i] = tmpLoud;
   2025   }
   2026 
   2027   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoSetExtPresent,
   2028                       FDKreadBits(hBs, 1));
   2029   hLoudnessInfoSet->diff = diff;
   2030 
   2031   if (hLoudnessInfoSet->loudnessInfoSetExtPresent) {
   2032     err = _readLoudnessInfoSetExtension(hBs, hLoudnessInfoSet);
   2033     if (err) return err;
   2034   }
   2035 
   2036   return err;
   2037 }
   2038