Coverage Report

Created: 2026-05-16 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fdk-aac/libAACdec/src/aacdec_drc.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2023 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
/**************************** AAC decoder library ******************************
96
97
   Author(s):   Christian Griebel
98
99
   Description: Dynamic range control (DRC) decoder tool for AAC
100
101
*******************************************************************************/
102
103
#include "aacdec_drc.h"
104
105
#include "channelinfo.h"
106
#include "aac_rom.h"
107
108
#include "sbrdecoder.h"
109
110
/*
111
 * Dynamic Range Control
112
 */
113
114
/* For parameter conversion */
115
0
#define DRC_PARAMETER_BITS (7)
116
0
#define DRC_MAX_QUANT_STEPS (1 << DRC_PARAMETER_BITS)
117
0
#define DRC_MAX_QUANT_FACTOR (DRC_MAX_QUANT_STEPS - 1)
118
#define DRC_PARAM_QUANT_STEP \
119
2.59k
  (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR))
120
2.25M
#define DRC_PARAM_SCALE (1)
121
#define DRC_SCALING_MAX \
122
2.59k
  ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127))
123
124
849k
#define DRC_BLOCK_LEN (1024)
125
849k
#define DRC_BAND_MULT (4)
126
849k
#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT)
127
128
14.3k
#define MAX_REFERENCE_LEVEL (127)
129
130
0
#define DRC_HEAVY_THRESHOLD_DB (10)
131
132
52.3k
#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */
133
134
43.1k
#define OFF 0
135
9.58M
#define ON 1
136
137
0
static INT convert_drcParam(FIXP_DBL param_dbl) {
138
  /* converts an internal DRC boost/cut scaling factor in FIXP_DBL
139
     (which is downscaled by DRC_PARAM_SCALE)
140
     back to an integer value between 0 and 127. */
141
0
  LONG param_long;
142
143
0
  param_long = (LONG)param_dbl >> 7;
144
0
  param_long = param_long * (INT)DRC_MAX_QUANT_FACTOR;
145
0
  param_long >>= 31 - 7 - DRC_PARAM_SCALE - 1;
146
0
  param_long += 1; /* for rounding */
147
0
  param_long >>= 1;
148
149
0
  return (INT)param_long;
150
0
}
151
152
/*!
153
\brief  Disable DRC
154
155
\self Handle of DRC info
156
157
\return none
158
*/
159
2.74M
void aacDecoder_drcDisable(HANDLE_AAC_DRC self) {
160
2.74M
  self->enable = 0;
161
2.74M
  self->applyExtGain = 0;
162
2.74M
  self->progRefLevelPresent = 0;
163
2.74M
}
164
165
/*!
166
\brief Reset DRC information
167
168
\self Handle of DRC info
169
170
\return none
171
*/
172
14.3k
void aacDecoder_drcReset(HANDLE_AAC_DRC self) {
173
14.3k
  self->applyExtGain = 0;
174
14.3k
  self->additionalGainPrev = AACDEC_DRC_GAIN_INIT_VALUE;
175
14.3k
  self->additionalGainFilterState = AACDEC_DRC_GAIN_INIT_VALUE;
176
14.3k
  self->additionalGainFilterState1 = AACDEC_DRC_GAIN_INIT_VALUE;
177
14.3k
}
178
179
/*!
180
  \brief Initialize DRC information
181
182
  \self Handle of DRC info
183
184
  \return none
185
*/
186
14.3k
void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
187
14.3k
  CDrcParams *pParams;
188
189
14.3k
  if (self == NULL) {
190
0
    return;
191
0
  }
192
193
  /* init control fields */
194
14.3k
  self->enable = OFF;
195
14.3k
  self->numThreads = 0;
196
197
  /* init params */
198
14.3k
  pParams = &self->params;
199
14.3k
  pParams->bsDelayEnable = 0;
200
14.3k
  pParams->cut = FL2FXCONST_DBL(0.0f);
201
14.3k
  pParams->usrCut = FL2FXCONST_DBL(0.0f);
202
14.3k
  pParams->boost = FL2FXCONST_DBL(0.0f);
203
14.3k
  pParams->usrBoost = FL2FXCONST_DBL(0.0f);
204
14.3k
  pParams->targetRefLevel = 96;
205
14.3k
  pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
206
14.3k
  pParams->applyHeavyCompression = OFF;
207
14.3k
  pParams->usrApplyHeavyCompression = OFF;
208
209
14.3k
  pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING;
210
14.3k
  pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */
211
212
14.3k
  self->update = 1;
213
14.3k
  self->numOutChannels = 0;
214
14.3k
  self->prevAacNumChannels = 0;
215
216
  /* initial program ref level = target ref level */
217
14.3k
  self->progRefLevel = pParams->targetRefLevel;
218
14.3k
  self->progRefLevelPresent = 0;
219
14.3k
  self->presMode = -1;
220
221
14.3k
  aacDecoder_drcReset(self);
222
14.3k
}
223
224
/*!
225
  \brief Initialize DRC control data for one channel
226
227
  \self Handle of DRC info
228
229
  \return none
230
*/
231
718k
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
232
718k
  if (pDrcChData != NULL) {
233
718k
    pDrcChData->expiryCount = 0;
234
718k
    pDrcChData->numBands = 1;
235
718k
    pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
236
718k
    pDrcChData->drcValue[0] = 0;
237
718k
    pDrcChData->drcInterpolationScheme = 0;
238
718k
    pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
239
718k
  }
240
718k
}
241
242
/*!
243
  \brief  Set one single DRC parameter
244
245
  \self   Handle of DRC info.
246
  \param  Parameter to be set.
247
  \value  Value to be set.
248
249
  \return an error code.
250
*/
251
AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
252
1.12M
                                         AACDEC_DRC_PARAM param, INT value) {
253
1.12M
  AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
254
255
1.12M
  switch (param) {
256
0
    case DRC_CUT_SCALE:
257
      /* set attenuation scale factor */
258
0
      if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
259
0
        return AAC_DEC_SET_PARAM_FAIL;
260
0
      }
261
0
      if (self == NULL) {
262
0
        return AAC_DEC_INVALID_HANDLE;
263
0
      }
264
0
      self->params.usrCut = (FIXP_DBL)(
265
0
          (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
266
0
      self->update = 1;
267
0
      break;
268
0
    case DRC_BOOST_SCALE:
269
      /* set boost factor */
270
0
      if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
271
0
        return AAC_DEC_SET_PARAM_FAIL;
272
0
      }
273
0
      if (self == NULL) {
274
0
        return AAC_DEC_INVALID_HANDLE;
275
0
      }
276
0
      self->params.usrBoost = (FIXP_DBL)(
277
0
          (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
278
0
      self->update = 1;
279
0
      break;
280
0
    case TARGET_REF_LEVEL:
281
0
      if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) {
282
0
        return AAC_DEC_SET_PARAM_FAIL;
283
0
      }
284
0
      if (self == NULL) {
285
0
        return AAC_DEC_INVALID_HANDLE;
286
0
      }
287
0
      if (value < 0) {
288
0
        self->params.targetRefLevel = -1;
289
0
      } else {
290
0
        if (self->params.targetRefLevel != (SCHAR)value) {
291
0
          self->params.targetRefLevel = (SCHAR)value;
292
0
          self->progRefLevel = (SCHAR)value; /* Always set the program reference
293
                                                level equal to the target level
294
                                                according to 4.5.2.7.3 of
295
                                                ISO/IEC 14496-3. */
296
0
        }
297
0
        self->update = 1;
298
0
      }
299
0
      break;
300
0
    case APPLY_HEAVY_COMPRESSION:
301
0
      if ((value != OFF) && (value != ON)) {
302
0
        return AAC_DEC_SET_PARAM_FAIL;
303
0
      }
304
0
      if (self == NULL) {
305
0
        return AAC_DEC_INVALID_HANDLE;
306
0
      }
307
      /* Store new parameter value */
308
0
      self->params.usrApplyHeavyCompression = (UCHAR)value;
309
0
      self->update = 1;
310
0
      break;
311
0
    case DEFAULT_PRESENTATION_MODE:
312
0
      if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED ||
313
0
          value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) {
314
0
        return AAC_DEC_SET_PARAM_FAIL;
315
0
      }
316
0
      if (self == NULL) {
317
0
        return AAC_DEC_INVALID_HANDLE;
318
0
      }
319
0
      self->params.defaultPresentationMode =
320
0
          (AACDEC_DRC_PARAMETER_HANDLING)value;
321
0
      self->update = 1;
322
0
      break;
323
0
    case ENCODER_TARGET_LEVEL:
324
0
      if (value > MAX_REFERENCE_LEVEL || value < 0) {
325
0
        return AAC_DEC_SET_PARAM_FAIL;
326
0
      }
327
0
      if (self == NULL) {
328
0
        return AAC_DEC_INVALID_HANDLE;
329
0
      }
330
0
      self->params.encoderTargetLevel = (UCHAR)value;
331
0
      self->update = 1;
332
0
      break;
333
48.9k
    case DRC_BS_DELAY:
334
48.9k
      if (value < 0 || value > 1) {
335
0
        return AAC_DEC_SET_PARAM_FAIL;
336
0
      }
337
48.9k
      if (self == NULL) {
338
0
        return AAC_DEC_INVALID_HANDLE;
339
0
      }
340
48.9k
      self->params.bsDelayEnable = value;
341
48.9k
      break;
342
1.07M
    case DRC_DATA_EXPIRY_FRAME:
343
1.07M
      if (self == NULL) {
344
0
        return AAC_DEC_INVALID_HANDLE;
345
0
      }
346
1.07M
      self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
347
1.07M
      break;
348
0
    case MAX_OUTPUT_CHANNELS:
349
0
      if (self == NULL) {
350
0
        return AAC_DEC_INVALID_HANDLE;
351
0
      }
352
0
      self->numOutChannels = (INT)value;
353
0
      self->update = 1;
354
0
      break;
355
0
    default:
356
0
      return AAC_DEC_SET_PARAM_FAIL;
357
1.12M
  } /* switch(param) */
358
359
1.12M
  return ErrorStatus;
360
1.12M
}
361
362
static int parseExcludedChannels(UINT *excludedChnsMask,
363
56.4k
                                 HANDLE_FDK_BITSTREAM bs) {
364
56.4k
  UINT excludeMask = 0;
365
56.4k
  UINT i, j;
366
56.4k
  int bitCnt = 9;
367
368
451k
  for (i = 0, j = 1; i < 7; i++, j <<= 1) {
369
394k
    if (FDKreadBits(bs, 1)) {
370
218k
      excludeMask |= j;
371
218k
    }
372
394k
  }
373
374
  /* additional_excluded_chns */
375
1.00M
  while (FDKreadBits(bs, 1)) {
376
7.60M
    for (i = 0; i < 7; i++, j <<= 1) {
377
6.65M
      if (FDKreadBits(bs, 1)) {
378
3.78M
        excludeMask |= j;
379
3.78M
      }
380
6.65M
    }
381
950k
    bitCnt += 9;
382
950k
    FDK_ASSERT(j < (UINT)-1);
383
950k
  }
384
385
56.4k
  *excludedChnsMask = excludeMask;
386
387
56.4k
  return (bitCnt);
388
56.4k
}
389
390
/*!
391
  \brief Save DRC payload bitstream position
392
393
  \self Handle of DRC info
394
  \bs Handle of FDK bitstream
395
396
  \return The number of DRC payload bits
397
*/
398
int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs,
399
128k
                              AACDEC_DRC_PAYLOAD_TYPE type) {
400
128k
  UINT bsStartPos;
401
128k
  int i, numBands = 1, bitCnt = 0;
402
403
128k
  if (self == NULL) {
404
0
    return 0;
405
0
  }
406
407
128k
  bsStartPos = FDKgetValidBits(bs);
408
409
128k
  switch (type) {
410
81.2k
    case MPEG_DRC_EXT_DATA: {
411
81.2k
      bitCnt = 4;
412
413
81.2k
      if (FDKreadBits(bs, 1)) { /* pce_tag_present */
414
51.2k
        FDKreadBits(bs, 8);     /* pce_instance_tag + drc_tag_reserved_bits */
415
51.2k
        bitCnt += 8;
416
51.2k
      }
417
418
81.2k
      if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
419
58.0k
        FDKreadBits(bs, 7);     /* exclude mask [0..7] */
420
58.0k
        bitCnt += 8;
421
896k
        while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
422
838k
          FDKreadBits(bs, 7);        /* exclude mask [x..y] */
423
838k
          bitCnt += 8;
424
838k
        }
425
58.0k
      }
426
427
81.2k
      if (FDKreadBits(bs, 1)) {         /* drc_bands_present */
428
28.7k
        numBands += FDKreadBits(bs, 4); /* drc_band_incr */
429
28.7k
        FDKreadBits(bs, 4);             /* reserved */
430
28.7k
        bitCnt += 8;
431
232k
        for (i = 0; i < numBands; i++) {
432
203k
          FDKreadBits(bs, 8); /* drc_band_top[i] */
433
203k
          bitCnt += 8;
434
203k
        }
435
28.7k
      }
436
437
81.2k
      if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
438
22.3k
        FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
439
22.3k
        bitCnt += 8;
440
22.3k
      }
441
442
337k
      for (i = 0; i < numBands; i++) {
443
256k
        FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
444
256k
        bitCnt += 8;
445
256k
      }
446
447
81.2k
      if ((self->numPayloads < MAX_DRC_THREADS) &&
448
78.1k
          ((INT)FDKgetValidBits(bs) >= 0)) {
449
76.2k
        self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
450
76.2k
      }
451
81.2k
    } break;
452
453
47.6k
    case DVB_DRC_ANC_DATA:
454
47.6k
      bitCnt += 8;
455
      /* check sync word */
456
47.6k
      if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
457
9.58k
        int dmxLevelsPresent, compressionPresent;
458
9.58k
        int coarseGrainTcPresent, fineGrainTcPresent;
459
460
        /* bs_info field */
461
9.58k
        FDKreadBits(
462
9.58k
            bs,
463
9.58k
            8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
464
9.58k
        bitCnt += 8;
465
466
        /* Evaluate ancillary_data_status */
467
9.58k
        FDKreadBits(bs, 3); /* reserved, set to 0 */
468
9.58k
        dmxLevelsPresent =
469
9.58k
            FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
470
9.58k
        FDKreadBits(bs, 1);     /* reserved, set to 0 */
471
9.58k
        compressionPresent =
472
9.58k
            FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
473
9.58k
        coarseGrainTcPresent =
474
9.58k
            FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
475
9.58k
        fineGrainTcPresent =
476
9.58k
            FDKreadBits(bs, 1); /* fine_grain_timecode_status */
477
9.58k
        bitCnt += 8;
478
479
        /* MPEG4 downmixing levels */
480
9.58k
        if (dmxLevelsPresent) {
481
7.92k
          FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
482
7.92k
          bitCnt += 8;
483
7.92k
        }
484
        /* audio coding mode and compression status */
485
9.58k
        if (compressionPresent) {
486
8.73k
          FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
487
8.73k
          bitCnt += 16;
488
8.73k
        }
489
        /* coarse grain timecode */
490
9.58k
        if (coarseGrainTcPresent) {
491
3.34k
          FDKreadBits(bs, 16); /* coarse_grain_timecode */
492
3.34k
          bitCnt += 16;
493
3.34k
        }
494
        /* fine grain timecode */
495
9.58k
        if (fineGrainTcPresent) {
496
3.17k
          FDKreadBits(bs, 16); /* fine_grain_timecode */
497
3.17k
          bitCnt += 16;
498
3.17k
        }
499
9.58k
        if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
500
4.76k
          self->dvbAncDataPosition = bsStartPos;
501
4.76k
          self->dvbAncDataAvailable = 1;
502
4.76k
        }
503
9.58k
      }
504
47.6k
      break;
505
506
0
    default:
507
0
      break;
508
128k
  }
509
510
128k
  return (bitCnt);
511
128k
}
512
513
/*!
514
  \brief Parse DRC parameters from bitstream
515
516
  \bs Handle of FDK bitstream (in)
517
  \pDrcBs Pointer to DRC payload data container (out)
518
  \payloadPosition Bitstream position of MPEG DRC data chunk (in)
519
520
  \return Flag telling whether new DRC data has been found or not.
521
*/
522
static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs,
523
75.8k
                               UINT payloadPosition) {
524
75.8k
  int i, numBands;
525
526
  /* Move to the beginning of the DRC payload field */
527
75.8k
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
528
529
  /* pce_tag_present */
530
75.8k
  if (FDKreadBits(bs, 1)) {
531
46.1k
    pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
532
    /* only one program supported */
533
46.1k
    FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
534
46.1k
  } else {
535
29.6k
    pDrcBs->pceInstanceTag = -1; /* not present */
536
29.6k
  }
537
538
75.8k
  if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
539
    /* get excluded_chn_mask */
540
56.4k
    parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
541
56.4k
  } else {
542
19.3k
    pDrcBs->excludedChnsMask = 0;
543
19.3k
  }
544
545
75.8k
  numBands = 1;
546
75.8k
  if (FDKreadBits(bs, 1)) /* drc_bands_present */
547
25.6k
  {
548
    /* get band_incr */
549
25.6k
    numBands += FDKreadBits(bs, 4); /* drc_band_incr */
550
25.6k
    pDrcBs->channelData.drcInterpolationScheme =
551
25.6k
        FDKreadBits(bs, 4); /* drc_interpolation_scheme */
552
    /* band_top */
553
204k
    for (i = 0; i < numBands; i++) {
554
178k
      pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
555
178k
    }
556
50.1k
  } else {
557
50.1k
    pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
558
50.1k
                                     1; /* ... comprising the whole spectrum. */
559
50.1k
    ;
560
50.1k
  }
561
562
75.8k
  pDrcBs->channelData.numBands = numBands;
563
564
75.8k
  if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
565
19.1k
  {
566
19.1k
    pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
567
19.1k
    FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
568
56.6k
  } else {
569
56.6k
    pDrcBs->progRefLevel = -1;
570
56.6k
  }
571
572
304k
  for (i = 0; i < numBands; i++) {
573
229k
    pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
574
229k
                                      << 7; /* dyn_rng_sgn[i] */
575
229k
    pDrcBs->channelData.drcValue[i] |=
576
229k
        FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
577
229k
  }
578
579
  /* Set DRC payload type */
580
75.8k
  pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
581
582
75.8k
  return (1);
583
75.8k
}
584
585
/*!
586
  \brief Parse heavy compression value transported in DSEs of DVB streams with
587
  MPEG-4 content.
588
589
  \bs Handle of FDK bitstream (in)
590
  \pDrcBs Pointer to DRC payload data container (out)
591
  \payloadPosition Bitstream position of DVB ancillary data chunk
592
593
  \return Flag telling whether new DRC data has been found or not.
594
*/
595
606
#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */
596
597
static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
598
                                         CDrcPayload *pDrcBs,
599
4.62k
                                         UINT payloadPosition) {
600
4.62k
  int foundDrcData = 0;
601
4.62k
  int dmxLevelsPresent, compressionPresent;
602
603
  /* Move to the beginning of the DRC payload field */
604
4.62k
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
605
606
  /* Sanity checks */
607
4.62k
  if (FDKgetValidBits(bs) < 24) {
608
0
    return 0;
609
0
  }
610
611
  /* Check sync word */
612
4.62k
  if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
613
2.65k
    return 0;
614
2.65k
  }
615
616
  /* Evaluate bs_info field */
617
1.96k
  if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
618
    /* No MPEG-4 audio data */
619
570
    return 0;
620
570
  }
621
1.39k
  FDKreadBits(bs, 2);                    /* dolby_surround_mode */
622
1.39k
  pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
623
1.39k
  FDKreadBits(bs, 1);                    /* stereo_downmix_mode */
624
1.39k
  if (FDKreadBits(bs, 1) != 0) {         /* reserved, set to 0 */
625
78
    return 0;
626
78
  }
627
628
  /* Evaluate ancillary_data_status */
629
1.31k
  if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
630
377
    return 0;
631
377
  }
632
942
  dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
633
942
  /*extensionPresent =*/FDKreadBits(bs,
634
942
                                    1); /* ancillary_data_extension_status; */
635
942
  compressionPresent =
636
942
      FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
637
942
  /*coarseGrainTcPresent =*/FDKreadBits(bs,
638
942
                                        1); /* coarse_grain_timecode_status */
639
942
  /*fineGrainTcPresent   =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */
640
641
942
  if (dmxLevelsPresent) {
642
6
    FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
643
6
  }
644
645
  /* audio_coding_mode_and_compression_status */
646
942
  if (compressionPresent) {
647
936
    UCHAR compressionOn, compressionValue;
648
649
    /* audio_coding_mode */
650
936
    if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
651
395
      return 0;
652
395
    }
653
541
    compressionOn = (UCHAR)FDKreadBits(bs, 1);    /* compression_on */
654
541
    compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */
655
656
541
    if (compressionOn) {
657
      /* A compression value is available so store the data just like MPEG DRC
658
       * data */
659
469
      pDrcBs->channelData.numBands = 1; /* One band ... */
660
469
      pDrcBs->channelData.drcValue[0] =
661
469
          compressionValue; /* ... with one value ... */
662
469
      pDrcBs->channelData.bandTop[0] =
663
469
          DRC_BLOCK_LEN_DIV_BAND_MULT -
664
469
          1; /* ... comprising the whole spectrum. */
665
469
      ;
666
469
      pDrcBs->pceInstanceTag = -1; /* Not present */
667
469
      pDrcBs->progRefLevel = -1;   /* Not present */
668
469
      pDrcBs->channelData.drcDataType =
669
469
          DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
670
469
      foundDrcData = 1;
671
469
    }
672
541
  }
673
674
547
  return (foundDrcData);
675
942
}
676
677
/*
678
 * Extract DRC payload from bitstream and map it to channels.
679
 *   Valid return values are:
680
 *     -1 : An unexpected error occured.
681
 *      0 : No error and no valid DRC data available.
682
 *      1 : No error and valid DRC data has been mapped.
683
 */
684
static int aacDecoder_drcExtractAndMap(
685
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
686
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
687
    UCHAR pceInstanceTag,
688
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
689
                               canonical channel index */
690
2.55M
    int validChannels) {
691
2.55M
  CDrcPayload threadBs[MAX_DRC_THREADS];
692
2.55M
  CDrcPayload *validThreadBs[MAX_DRC_THREADS];
693
2.55M
  CDrcParams *pParams;
694
2.55M
  UINT backupBsPosition;
695
2.55M
  int result = 0;
696
2.55M
  int i, thread, validThreads = 0;
697
698
2.55M
  FDK_ASSERT(self != NULL);
699
2.55M
  FDK_ASSERT(hBs != NULL);
700
2.55M
  FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
701
702
2.55M
  pParams = &self->params;
703
704
2.55M
  self->numThreads = 0;
705
2.55M
  backupBsPosition = FDKgetValidBits(hBs);
706
707
2.63M
  for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
708
2.55M
       i++) {
709
    /* Init payload data chunk. The memclear is very important because it
710
       initializes the most values. Without it the module wouldn't work properly
711
       or crash. */
712
75.8k
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
713
75.8k
    threadBs[self->numThreads].channelData.bandTop[0] =
714
75.8k
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
715
716
    /* Extract payload */
717
75.8k
    self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
718
75.8k
                                            self->drcPayloadPosition[i]);
719
75.8k
  }
720
2.55M
  self->numPayloads = 0;
721
722
2.55M
  if (self->dvbAncDataAvailable &&
723
4.66k
      self->numThreads < MAX_DRC_THREADS) { /* Append a DVB heavy compression
724
                                               payload thread if available. */
725
726
    /* Init payload data chunk. The memclear is very important because it
727
       initializes the most values. Without it the module wouldn't work properly
728
       or crash. */
729
4.62k
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
730
4.62k
    threadBs[self->numThreads].channelData.bandTop[0] =
731
4.62k
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
732
733
    /* Extract payload */
734
4.62k
    self->numThreads += aacDecoder_drcReadCompression(
735
4.62k
        hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
736
4.62k
  }
737
2.55M
  self->dvbAncDataAvailable = 0;
738
739
  /* Reset the bitbufffer */
740
2.55M
  FDKpushBiDirectional(hBs, (INT)FDKgetValidBits(hBs) - (INT)backupBsPosition);
741
742
  /* calculate number of valid bits in excl_chn_mask */
743
744
  /* coupling channels not supported */
745
746
  /* check for valid threads */
747
2.63M
  for (thread = 0; thread < self->numThreads; thread++) {
748
76.2k
    CDrcPayload *pThreadBs = &threadBs[thread];
749
76.2k
    int numExclChns = 0;
750
751
76.2k
    switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
752
0
      default:
753
0
        continue;
754
75.8k
      case MPEG_DRC_EXT_DATA:
755
76.2k
      case DVB_DRC_ANC_DATA:
756
76.2k
        break;
757
76.2k
    }
758
759
76.2k
    if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
760
46.1k
      if (pThreadBs->pceInstanceTag != pceInstanceTag) {
761
41.6k
        continue; /* don't accept */
762
41.6k
      }
763
46.1k
    }
764
765
    /* calculate number of excluded channels */
766
34.6k
    if (pThreadBs->excludedChnsMask > 0) {
767
22.7k
      INT exclMask = pThreadBs->excludedChnsMask;
768
22.7k
      int ch;
769
59.1k
      for (ch = 0; ch < validChannels; ch++) {
770
36.3k
        numExclChns += exclMask & 0x1;
771
36.3k
        exclMask >>= 1;
772
36.3k
      }
773
22.7k
    }
774
34.6k
    if (numExclChns < validChannels) {
775
25.4k
      validThreadBs[validThreads] = pThreadBs;
776
25.4k
      validThreads++;
777
25.4k
    }
778
34.6k
  }
779
780
  /* map DRC bitstream information onto DRC channel information */
781
2.58M
  for (thread = 0; thread < validThreads; thread++) {
782
25.4k
    CDrcPayload *pThreadBs = validThreadBs[thread];
783
25.4k
    INT exclMask = pThreadBs->excludedChnsMask;
784
25.4k
    AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
785
25.4k
        (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
786
25.4k
    int ch;
787
788
    /* last progRefLevel transmitted is the one that is used
789
     * (but it should really only be transmitted once per block!)
790
     */
791
25.4k
    if (pThreadBs->progRefLevel >= 0) {
792
12.3k
      self->progRefLevel = pThreadBs->progRefLevel;
793
12.3k
      self->progRefLevelPresent = 1;
794
12.3k
      self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
795
12.3k
    }
796
797
25.4k
    if (drcPayloadType == DVB_DRC_ANC_DATA) {
798
      /* Announce the presentation mode of this valid thread. */
799
469
      self->presMode = pThreadBs->presMode;
800
469
    }
801
802
    /* SCE, CPE and LFE */
803
67.7k
    for (ch = 0; ch < validChannels; ch++) {
804
42.2k
      AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
805
42.2k
      int mapedChannel = channelMapping[ch];
806
807
42.2k
      if ((mapedChannel >= validChannels) ||
808
42.0k
          ((exclMask & (1 << mapedChannel)) != 0))
809
998
        continue;
810
811
41.2k
      if ((pParams->expiryFrame <= 0) ||
812
0
          (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
813
41.2k
           pParams->expiryFrame)) {
814
41.2k
        prvPayloadType =
815
41.2k
            (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
816
41.2k
                ->drcData.drcDataType;
817
41.2k
      }
818
41.2k
      if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
819
40.7k
           (prvPayloadType != DVB_DRC_ANC_DATA)) ||
820
479
          ((drcPayloadType == DVB_DRC_ANC_DATA) &&
821
476
           (pParams->applyHeavyCompression ==
822
41.1k
            ON))) { /* copy thread to channel */
823
41.1k
        pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
824
41.1k
        result = 1;
825
41.1k
      }
826
41.2k
    }
827
    /* CCEs not supported by now */
828
25.4k
  }
829
830
  /* Increment and check expiry counter for the program reference level: */
831
2.55M
  if ((pParams->expiryFrame > 0) &&
832
0
      (self->prlExpiryCount++ >
833
0
       pParams->expiryFrame)) { /* The program reference level is too old, so
834
                                   set it back to the target level. */
835
0
    self->progRefLevelPresent = 0;
836
0
    self->progRefLevel = pParams->targetRefLevel;
837
0
    self->prlExpiryCount = 0;
838
0
  }
839
840
2.55M
  return result;
841
2.55M
}
842
843
void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec,
844
                         CAacDecoderChannelInfo *pAacDecoderChannelInfo,
845
                         CDrcChannelData *pDrcChData, FIXP_DBL *extGain,
846
                         int ch, /* needed only for SBR */
847
4.20M
                         int aacFrameSize, int bSbrPresent) {
848
4.20M
  int band, bin, numBands;
849
4.20M
  int bottom = 0;
850
4.20M
  int modifyBins = 0;
851
852
4.20M
  FIXP_DBL max_mantissa;
853
4.20M
  INT max_exponent;
854
855
4.20M
  FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
856
4.20M
  INT norm_exponent = 1;
857
858
4.20M
  FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
859
4.20M
  INT fact_exponent[MAX_DRC_BANDS];
860
861
4.20M
  CDrcParams *pParams = &self->params;
862
863
4.20M
  FIXP_DBL *pSpectralCoefficient =
864
4.20M
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
865
4.20M
  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
866
4.20M
  SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
867
868
4.20M
  int winSeq = pIcsInfo->WindowSequence;
869
870
  /* Increment and check expiry counter */
871
4.20M
  if ((pParams->expiryFrame > 0) &&
872
0
      (++pDrcChData->expiryCount >
873
0
       pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */
874
0
    aacDecoder_drcInitChannelData(pDrcChData);
875
0
  }
876
877
4.20M
  if (self->enable != ON) {
878
1.45M
    sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
879
1.45M
    if (extGain != NULL) {
880
1.45M
      INT gainScale = (INT)*extGain;
881
      /* The gain scaling must be passed to the function in the buffer pointed
882
       * on by extGain. */
883
1.45M
      if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
884
1.45M
        *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
885
1.45M
      } else {
886
0
        FDK_ASSERT(0);
887
0
      }
888
1.45M
    }
889
1.45M
    return;
890
1.45M
  }
891
892
2.74M
  numBands = pDrcChData->numBands;
893
894
  /* If program reference normalization is done in the digital domain,
895
  modify factor to perform normalization.  prog_ref_level can
896
  alternatively be passed to the system for modification of the level in
897
  the analog domain.  Analog level modification avoids problems with
898
  reduced DAC SNR (if signal is attenuated) or clipping (if signal is
899
  boosted) */
900
901
2.74M
  if (pParams->targetRefLevel >= 0) {
902
    /* 0.5^((targetRefLevel - progRefLevel)/24) */
903
2.74M
    norm_mantissa =
904
2.74M
        fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
905
2.74M
               0,
906
2.74M
               (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
907
2.74M
                          (INT)(pParams->targetRefLevel - self->progRefLevel)),
908
2.74M
               3, &norm_exponent);
909
2.74M
  }
910
  /* Always export the normalization gain (if possible). */
911
2.74M
  if (extGain != NULL) {
912
2.74M
    INT gainScale = (INT)*extGain;
913
    /* The gain scaling must be passed to the function in the buffer pointed on
914
     * by extGain. */
915
2.74M
    if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
916
2.74M
      *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
917
2.74M
    } else {
918
0
      FDK_ASSERT(0);
919
0
    }
920
2.74M
  }
921
  /* Reset normalization gain since this module must not apply it */
922
2.74M
  norm_mantissa = FL2FXCONST_DBL(0.5f);
923
2.74M
  norm_exponent = 1;
924
925
  /* calc scale factors */
926
8.07M
  for (band = 0; band < numBands; band++) {
927
5.32M
    UCHAR drcVal = pDrcChData->drcValue[band];
928
929
5.32M
    fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
930
5.32M
    fact_exponent[band] = 1;
931
932
5.32M
    if ((pParams->applyHeavyCompression == ON) &&
933
23.9k
        ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
934
23.9k
         DVB_DRC_ANC_DATA)) {
935
622
      INT compressionFactorVal_e;
936
622
      int valX, valY;
937
938
622
      valX = drcVal >> 4;
939
622
      valY = drcVal & 0x0F;
940
941
      /* calculate the unscaled heavy compression factor.
942
         compressionFactor = 48.164 - 6.0206*valX - 0.4014*valY dB
943
         range: -48.166 dB to 48.164 dB */
944
622
      if (drcVal != 0x7F) {
945
606
        fact_mantissa[band] = fPowInt(
946
606
            FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
947
606
            0, valY, &compressionFactorVal_e);
948
949
        /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
950
606
        fact_mantissa[band] =
951
606
            fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);
952
953
606
        fact_exponent[band] =
954
606
            DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
955
606
      }
956
5.32M
    } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
957
5.32M
               MPEG_DRC_EXT_DATA) {
958
      /* apply the scaled dynamic range control words to factor.
959
       * if scaling drc_cut (or drc_boost), or control word drc_mantissa is 0
960
       * then there is no dynamic range compression
961
       *
962
       * if pDrcChData->drcSgn[band] is
963
       *  1 then gain is < 1 :  factor = 2^(-self->cut   *
964
       * pDrcChData->drcMag[band] / 24) 0 then gain is > 1 :  factor = 2^(
965
       * self->boost * pDrcChData->drcMag[band] / 24)
966
       */
967
968
3.02M
      if ((drcVal & 0x7F) > 0) {
969
2.25M
        FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;
970
971
2.25M
        fact_mantissa[band] = f2Pow(
972
2.25M
            (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
973
2.25M
                       (drcVal & 0x7F)),
974
2.25M
            3 + DRC_PARAM_SCALE, &fact_exponent[band]);
975
2.25M
      }
976
3.02M
    }
977
978
5.32M
    fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
979
5.32M
    fact_exponent[band] += norm_exponent;
980
981
5.32M
  } /* end loop over bands */
982
983
  /* normalizations */
984
2.74M
  {
985
2.74M
    int res;
986
987
2.74M
    max_mantissa = FL2FXCONST_DBL(0.0f);
988
2.74M
    max_exponent = 0;
989
8.07M
    for (band = 0; band < numBands; band++) {
990
5.32M
      max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
991
5.32M
      max_exponent = fixMax(max_exponent, fact_exponent[band]);
992
5.32M
    }
993
994
    /* left shift factors to gain accurancy */
995
2.74M
    res = CntLeadingZeros(max_mantissa) - 1;
996
997
    /* above topmost DRC band gain factor is 1 */
998
2.74M
    if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
999
269k
      res = 0;
1000
1001
2.74M
    if (res > 0) {
1002
2.48M
      res = fixMin(res, max_exponent);
1003
2.48M
      max_exponent -= res;
1004
1005
4.96M
      for (band = 0; band < numBands; band++) {
1006
2.48M
        fact_mantissa[band] <<= res;
1007
2.48M
        fact_exponent[band] -= res;
1008
2.48M
      }
1009
2.48M
    }
1010
1011
    /* normalize magnitudes to one scale factor */
1012
8.07M
    for (band = 0; band < numBands; band++) {
1013
5.32M
      if (fact_exponent[band] < max_exponent) {
1014
12.3k
        fact_mantissa[band] >>= max_exponent - fact_exponent[band];
1015
12.3k
      }
1016
5.32M
      if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
1017
2.84M
        modifyBins = 1;
1018
2.84M
      }
1019
5.32M
    }
1020
2.74M
    if (max_exponent != 1) {
1021
272k
      modifyBins = 1;
1022
272k
    }
1023
2.74M
  }
1024
1025
  /*  apply factor to spectral lines
1026
   *  short blocks must take care that bands fall on
1027
   *  block boundaries!
1028
   */
1029
2.74M
  if (!bSbrPresent) {
1030
1.47M
    bottom = 0;
1031
1032
1.47M
    if (!modifyBins) {
1033
      /* We don't have to modify the spectral bins because the fractional part
1034
         of all factors is 0.5. In order to keep accurancy we don't apply the
1035
         factor but decrease the exponent instead. */
1036
1.45M
      max_exponent -= 1;
1037
1.45M
    } else {
1038
90.8k
      for (band = 0; band < numBands; band++) {
1039
77.9k
        int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
1040
77.9k
                         aacFrameSize); /* ... * DRC_BAND_MULT; */
1041
1042
13.1M
        for (bin = bottom; bin < top; bin++) {
1043
13.1M
          pSpectralCoefficient[bin] =
1044
13.1M
              fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
1045
13.1M
        }
1046
1047
77.9k
        bottom = top;
1048
77.9k
      }
1049
12.8k
    }
1050
1051
    /* above topmost DRC band gain factor is 1 */
1052
1.47M
    if (max_exponent > 0) {
1053
7.07M
      for (bin = bottom; bin < aacFrameSize; bin += 1) {
1054
7.06M
        pSpectralCoefficient[bin] >>= max_exponent;
1055
7.06M
      }
1056
10.6k
    }
1057
1058
    /* adjust scaling */
1059
1.47M
    pSpecScale[0] += max_exponent;
1060
1061
1.47M
    if (winSeq == BLOCK_SHORT) {
1062
22.8k
      int win;
1063
182k
      for (win = 1; win < 8; win++) {
1064
159k
        pSpecScale[win] += max_exponent;
1065
159k
      }
1066
22.8k
    }
1067
1.47M
  } else {
1068
1.27M
    HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
1069
1.27M
    numBands = pDrcChData->numBands;
1070
1071
    /* feed factors into SBR decoder for application in QMF domain. */
1072
1.27M
    sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
1073
1.27M
                              max_exponent, pDrcChData->drcInterpolationScheme,
1074
1.27M
                              winSeq, pDrcChData->bandTop);
1075
1.27M
  }
1076
1077
2.74M
  return;
1078
2.74M
}
1079
1080
/*
1081
 * DRC parameter and presentation mode handling
1082
 */
1083
static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,
1084
                                            INT aacNumChannels,
1085
                                            SCHAR prevDrcProgRefLevel,
1086
2.55M
                                            SCHAR prevDrcPresMode) {
1087
2.55M
  int isDownmix, isMonoDownmix, isStereoDownmix;
1088
2.55M
  int dDmx, dHr;
1089
2.55M
  AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
1090
2.55M
  CDrcParams *p;
1091
1092
2.55M
  FDK_ASSERT(self != NULL);
1093
1094
2.55M
  p = &self->params;
1095
1096
2.55M
  if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;
1097
1098
2.55M
  if (self->presMode != prevDrcPresMode) self->update = 1;
1099
1100
2.55M
  if (self->prevAacNumChannels != aacNumChannels) self->update = 1;
1101
1102
  /* return if no relevant parameter has changed */
1103
2.55M
  if (!self->update) {
1104
2.52M
    return;
1105
2.52M
  }
1106
1107
  /* derive downmix property. aacNumChannels: number of channels in aac stream,
1108
   * numOutChannels: number of output channels */
1109
28.6k
  isDownmix = (aacNumChannels > self->numOutChannels);
1110
28.6k
  isDownmix = (isDownmix && (self->numOutChannels > 0));
1111
28.6k
  isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
1112
28.6k
  isStereoDownmix = (isDownmix && (self->numOutChannels == 2));
1113
1114
28.6k
  if ((self->presMode == 1) || (self->presMode == 2)) {
1115
1.39k
    drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
1116
27.2k
  } else { /* no presentation mode -> use parameter handling specified by
1117
              AAC_DRC_DEFAULT_PRESENTATION_MODE */
1118
27.2k
    drcParameterHandling = p->defaultPresentationMode;
1119
27.2k
  }
1120
1121
  /* by default, do as desired */
1122
28.6k
  p->cut = p->usrCut;
1123
28.6k
  p->boost = p->usrBoost;
1124
28.6k
  p->applyHeavyCompression = p->usrApplyHeavyCompression;
1125
1126
28.6k
  switch (drcParameterHandling) {
1127
27.2k
    case DISABLED_PARAMETER_HANDLING:
1128
27.2k
    default:
1129
      /* use drc parameters as requested */
1130
27.2k
      break;
1131
1132
27.2k
    case ENABLED_PARAMETER_HANDLING:
1133
      /* dDmx: estimated headroom reduction due to downmix, format: -1/4*dB
1134
         dDmx = floor(-4*20*log10(aacNumChannels/numOutChannels)) */
1135
0
      if (isDownmix) {
1136
0
        FIXP_DBL dmxTmp;
1137
0
        int e_log, e_mult;
1138
0
        dmxTmp = fDivNorm(self->numOutChannels,
1139
0
                          aacNumChannels); /* inverse division ->
1140
                                              negative sign after
1141
                                              logarithm */
1142
0
        dmxTmp = fLog2(dmxTmp, 0, &e_log);
1143
0
        dmxTmp = fMultNorm(
1144
0
            dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)),
1145
0
            &e_mult); /* e = e_log + e_mult + 5 */
1146
0
        dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1));
1147
0
      } else {
1148
0
        dDmx = 0;
1149
0
      }
1150
1151
      /* dHr: Full estimated (decoder) headroom reduction due to loudness
1152
       * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */
1153
0
      if (p->targetRefLevel >= 0) { /* if target level is provided */
1154
0
        dHr = p->targetRefLevel + dDmx - self->progRefLevel;
1155
0
      } else {
1156
0
        dHr = dDmx;
1157
0
      }
1158
1159
0
      if (dHr < 0) { /* if headroom is reduced */
1160
        /* Use compression, but as little as possible. */
1161
        /* eHr: Headroom provided by encoder, format: -1/4 dB */
1162
0
        int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0);
1163
0
        if (eHr <
1164
0
            dHr) { /* if encoder provides more headroom than decoder needs */
1165
          /* derive scaling of light DRC */
1166
0
          FIXP_DBL calcFactor_norm;
1167
0
          INT calcFactor; /* fraction of DRC gains that is minimally needed for
1168
                             clipping prevention */
1169
0
          calcFactor_norm =
1170
0
              fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */
1171
0
          calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE;
1172
          /* quantize to 128 steps */
1173
0
          calcFactor = convert_drcParam(
1174
0
              calcFactor_norm); /* convert to integer value between 0 and 127 */
1175
0
          calcFactor_norm = (FIXP_DBL)(
1176
0
              (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor);
1177
0
          p->cut = (calcFactor_norm > p->cut)
1178
0
                       ? calcFactor_norm
1179
0
                       : p->cut; /* use calcFactor_norm as lower limit */
1180
0
        } else {
1181
          /* encoder provides equal or less headroom than decoder needs */
1182
          /* the time domain limiter must always be active in this case. It is
1183
           * assumed that the framework activates it by default */
1184
0
          p->cut = DRC_SCALING_MAX;
1185
0
          if ((dHr - eHr) <=
1186
0
              -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if
1187
                                                headroom deficit is equal or
1188
                                                higher than
1189
                                                DRC_HEAVY_THRESHOLD_DB */
1190
0
            p->applyHeavyCompression = ON;
1191
0
          }
1192
0
        }
1193
0
      } else { /* dHr >= 0 */
1194
        /* no restrictions required, as headroom is not reduced. */
1195
        /* p->cut = p->usrCut; */
1196
0
      }
1197
0
      break;
1198
1199
      /* presentation mode 1 and 2 according to ETSI TS 101 154:
1200
         Digital Video Broadcasting (DVB); Specification for the use of Video
1201
         and Audio Coding in Broadcasting Applications based on the MPEG-2
1202
         Transport Stream, section C.5.4., "Decoding", and Table C.33. Also
1203
         according to amendment 4 to ISO/IEC 14496-3, section 4.5.2.14.2.4, and
1204
         Table AMD4.11. ISO DRC            -> applyHeavyCompression = OFF (Use
1205
         light compression, MPEG-style) Compression_value  ->
1206
         applyHeavyCompression = ON  (Use heavy compression, DVB-style) scaling
1207
         restricted -> p->cut = DRC_SCALING_MAX */
1208
1209
1.20k
    case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
1210
1.20k
      if ((p->targetRefLevel >= 0) &&
1211
1.20k
          (p->targetRefLevel <
1212
1.20k
           124)) { /* if target level is provided and > -31 dB */
1213
        /* playback up to -23 dB */
1214
1.20k
        p->applyHeavyCompression = ON;
1215
1.20k
      } else { /* target level <= -31 dB or not provided */
1216
        /* playback -31 dB */
1217
0
        if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
1218
0
          p->cut = DRC_SCALING_MAX;
1219
0
        }
1220
0
      }
1221
1.20k
      break;
1222
1223
198
    case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
1224
198
      if ((p->targetRefLevel >= 0) &&
1225
198
          (p->targetRefLevel <
1226
198
           124)) { /* if target level is provided and > -31 dB */
1227
        /* playback up to -23 dB */
1228
198
        if (isMonoDownmix) { /* if mono downmix */
1229
0
          p->applyHeavyCompression = ON;
1230
198
        } else {
1231
198
          p->applyHeavyCompression = OFF;
1232
198
          p->cut = DRC_SCALING_MAX;
1233
198
        }
1234
198
      } else { /* target level <= -31 dB or not provided */
1235
        /* playback -31 dB */
1236
0
        p->applyHeavyCompression = OFF;
1237
0
        if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
1238
0
          p->cut = DRC_SCALING_MAX;
1239
0
        }
1240
0
      }
1241
198
      break;
1242
28.6k
  } /*  switch (drcParameterHandling) */
1243
1244
  /* With heavy compression, there is no scaling.
1245
     Scaling factors are set for notification only. */
1246
28.6k
  if (p->applyHeavyCompression == ON) {
1247
1.20k
    p->boost = DRC_SCALING_MAX;
1248
1.20k
    p->cut = DRC_SCALING_MAX;
1249
1.20k
  }
1250
1251
  /* switch on/off processing */
1252
28.6k
  self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
1253
27.2k
                  (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
1254
1255
28.6k
  self->prevAacNumChannels = aacNumChannels;
1256
28.6k
  self->update = 0;
1257
28.6k
}
1258
1259
/*
1260
 * Prepare DRC processing
1261
 *   Valid return values are:
1262
 *     -1 : An unexpected error occured.
1263
 *      0 : No error and no valid DRC data available.
1264
 *      1 : No error and valid DRC data has been mapped.
1265
 */
1266
int aacDecoder_drcProlog(
1267
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
1268
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
1269
    UCHAR pceInstanceTag,
1270
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
1271
                               canonical channel index */
1272
2.55M
    int validChannels) {
1273
2.55M
  int result = 0;
1274
1275
2.55M
  if (self == NULL) {
1276
0
    return -1;
1277
0
  }
1278
1279
2.55M
  if (!self->params.bsDelayEnable) {
1280
    /* keep previous progRefLevel and presMode for update flag in
1281
     * drcParameterHandling */
1282
2.55M
    INT prevPRL, prevPM = 0;
1283
2.55M
    prevPRL = self->progRefLevel;
1284
2.55M
    prevPM = self->presMode;
1285
1286
2.55M
    result = aacDecoder_drcExtractAndMap(
1287
2.55M
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1288
2.55M
        validChannels);
1289
1290
2.55M
    if (result < 0) {
1291
0
      return result;
1292
0
    }
1293
1294
    /* Drc parameter handling */
1295
2.55M
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1296
2.55M
  }
1297
1298
2.55M
  return result;
1299
2.55M
}
1300
1301
/*
1302
 * Finalize DRC processing
1303
 *   Valid return values are:
1304
 *     -1 : An unexpected error occured.
1305
 *      0 : No error and no valid DRC data available.
1306
 *      1 : No error and valid DRC data has been mapped.
1307
 */
1308
int aacDecoder_drcEpilog(
1309
    HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs,
1310
    CAacDecoderStaticChannelInfo *pAacDecoderStaticChannelInfo[],
1311
    UCHAR pceInstanceTag,
1312
    UCHAR channelMapping[], /* Channel mapping translating drcChannel index to
1313
                               canonical channel index */
1314
2.45M
    int validChannels) {
1315
2.45M
  int result = 0;
1316
1317
2.45M
  if (self == NULL) {
1318
0
    return -1;
1319
0
  }
1320
1321
2.45M
  if (self->params.bsDelayEnable) {
1322
    /* keep previous progRefLevel and presMode for update flag in
1323
     * drcParameterHandling */
1324
0
    INT prevPRL, prevPM = 0;
1325
0
    prevPRL = self->progRefLevel;
1326
0
    prevPM = self->presMode;
1327
1328
0
    result = aacDecoder_drcExtractAndMap(
1329
0
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1330
0
        validChannels);
1331
1332
0
    if (result < 0) {
1333
0
      return result;
1334
0
    }
1335
1336
    /* Drc parameter handling */
1337
0
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1338
0
  }
1339
1340
2.45M
  return result;
1341
2.45M
}
1342
1343
/*
1344
 * Export relevant metadata info from bitstream payload.
1345
 */
1346
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
1347
2.45M
                           SCHAR *pProgRefLevel) {
1348
2.45M
  if (self != NULL) {
1349
2.45M
    if (pPresMode != NULL) {
1350
2.45M
      *pPresMode = self->presMode;
1351
2.45M
    }
1352
2.45M
    if (pProgRefLevel != NULL) {
1353
2.45M
      if (self->progRefLevelPresent) {
1354
172k
        *pProgRefLevel = self->progRefLevel;
1355
2.27M
      } else {
1356
2.27M
        *pProgRefLevel = -1;
1357
2.27M
      }
1358
2.45M
    }
1359
2.45M
  }
1360
2.45M
}
1361
1362
/**
1363
 * \brief  Apply DRC Level Normalization.
1364
 *
1365
 *         This function prepares/applies the gain values for the DRC Level
1366
 * Normalization and returns the exponent of the time data. The following two
1367
 * cases are handled:
1368
 *
1369
 *         - Limiter enabled:
1370
 *           The input data must be interleaved.
1371
 *           One gain per sample is written to the buffer pGainPerSample.
1372
 *           If necessary the time data is rescaled.
1373
 *
1374
 *         - Limiter disabled:
1375
 *           The input data can be interleaved or deinterleaved.
1376
 *           The gain values are applied to the time data.
1377
 *           If necessary the time data is rescaled.
1378
 *
1379
 * \param hDrcInfo                     [i/o] handle to drc data structure.
1380
 * \param samplesIn                    [i/o] pointer to time data.
1381
 * \param pGain                        [i  ] pointer to gain to be applied to
1382
 * the time data.
1383
 * \param pGainPerSample               [o  ] pointer to the gain per sample to
1384
 * be applied to the time data in the limiter.
1385
 * \param gain_scale                   [i  ] exponent to be applied to the time
1386
 * data.
1387
 * \param gain_delay                   [i  ] delay[samples] with which the gains
1388
 * in pGain shall be applied (gain_delay <= nSamples).
1389
 * \param nSamples                     [i  ] number of samples per frame.
1390
 * \param channels                     [i  ] number of channels.
1391
 * \param stride                       [i  ] channel stride of time data.
1392
 * \param limiterEnabled               [i  ] 1 if limiter is enabled, otherwise
1393
 * 0.
1394
 *
1395
 * \return exponent of time data
1396
 */
1397
INT applyDrcLevelNormalization(HANDLE_AAC_DRC hDrcInfo, PCM_DEC *samplesIn,
1398
                               FIXP_DBL *pGain, FIXP_DBL *pGainPerSample,
1399
                               const INT gain_scale, const UINT gain_delay,
1400
                               const UINT nSamples, const UINT channels,
1401
172k
                               const UINT stride, const UINT limiterEnabled) {
1402
172k
  UINT i;
1403
172k
  INT additionalGain_scaling;
1404
172k
  FIXP_DBL additionalGain;
1405
1406
172k
  FDK_ASSERT(gain_delay <= nSamples);
1407
1408
172k
  FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState;
1409
172k
  FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1;
1410
1411
172k
  if (!gain_delay) {
1412
0
    additionalGain = pGain[0];
1413
1414
    /* Apply the additional scaling gain_scale[0] that has no delay and no
1415
     * smoothing */
1416
0
    additionalGain_scaling =
1417
0
        fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
1418
0
    additionalGain = scaleValue(additionalGain, additionalGain_scaling);
1419
1420
    /* if it's not possible to fully apply gain_scale to additionalGain, apply
1421
     * it to the input signal */
1422
0
    additionalGain_scaling -= gain_scale;
1423
1424
0
    if (additionalGain_scaling) {
1425
0
      scaleValuesSaturate(samplesIn, channels * nSamples,
1426
0
                          -additionalGain_scaling);
1427
0
    }
1428
1429
0
    if (limiterEnabled) {
1430
0
      FDK_ASSERT(pGainPerSample != NULL);
1431
1432
0
      for (i = 0; i < nSamples; i++) {
1433
0
        pGainPerSample[i] = additionalGain;
1434
0
      }
1435
0
    } else {
1436
0
      for (i = 0; i < channels * nSamples; i++) {
1437
0
        samplesIn[i] = FIXP_DBL2PCM_DEC(fMult(samplesIn[i], additionalGain));
1438
0
      }
1439
0
    }
1440
172k
  } else {
1441
172k
    UINT inc;
1442
172k
    FIXP_DBL additionalGainUnfiltered;
1443
1444
172k
    inc = (stride == 1) ? channels : 1;
1445
1446
308M
    for (i = 0; i < nSamples; i++) {
1447
307M
      if (i < gain_delay) {
1448
163M
        additionalGainUnfiltered = hDrcInfo->additionalGainPrev;
1449
163M
      } else {
1450
144M
        additionalGainUnfiltered = pGain[0];
1451
144M
      }
1452
1453
      /* Smooth additionalGain */
1454
1455
      /* [b,a] = butter(1, 0.01) */
1456
307M
      static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
1457
307M
                                   FL2FXCONST_SGL(0.015466 * 2.0)};
1458
307M
      static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
1459
307M
                                   FL2FXCONST_SGL(-0.96907)};
1460
1461
307M
      additionalGain = -fMult(additionalGainSmoothState, a[1]) +
1462
307M
                       fMultDiv2(additionalGainUnfiltered, b[0]) +
1463
307M
                       fMultDiv2(additionalGainSmoothState1, b[1]);
1464
307M
      additionalGainSmoothState1 = additionalGainUnfiltered;
1465
307M
      additionalGainSmoothState = additionalGain;
1466
1467
      /* Apply the additional scaling gain_scale[0] that has no delay and no
1468
       * smoothing */
1469
307M
      additionalGain_scaling =
1470
307M
          fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
1471
307M
      additionalGain = scaleValue(additionalGain, additionalGain_scaling);
1472
1473
      /* if it's not possible to fully apply gain_scale[0] to additionalGain,
1474
       * apply it to the input signal */
1475
307M
      additionalGain_scaling -= gain_scale;
1476
1477
307M
      if (limiterEnabled) {
1478
300M
        FDK_ASSERT(stride == 1);
1479
300M
        FDK_ASSERT(pGainPerSample != NULL);
1480
1481
300M
        if (additionalGain_scaling) {
1482
95.6k
          scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling);
1483
95.6k
        }
1484
1485
300M
        pGainPerSample[i] = additionalGain;
1486
300M
      } else {
1487
7.53M
        if (additionalGain_scaling) {
1488
127k
          for (UINT k = 0; k < channels; k++) {
1489
109k
            scaleValuesSaturate(&samplesIn[k * stride], 1,
1490
109k
                                -additionalGain_scaling);
1491
109k
          }
1492
18.1k
        }
1493
1494
19.1M
        for (UINT k = 0; k < channels; k++) {
1495
11.5M
          samplesIn[k * stride] =
1496
11.5M
              FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain));
1497
11.5M
        }
1498
7.53M
      }
1499
1500
307M
      samplesIn += inc;
1501
307M
    }
1502
172k
  }
1503
1504
172k
  hDrcInfo->additionalGainPrev = pGain[0];
1505
172k
  hDrcInfo->additionalGainFilterState = additionalGainSmoothState;
1506
172k
  hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1;
1507
1508
172k
  return (AACDEC_DRC_GAIN_SCALING);
1509
172k
}