Coverage Report

Created: 2025-08-29 06:06

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