Coverage Report

Created: 2026-02-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
1.74k
  (FL2FXCONST_DBL(1.0f / (float)DRC_MAX_QUANT_FACTOR))
120
128k
#define DRC_PARAM_SCALE (1)
121
#define DRC_SCALING_MAX \
122
1.74k
  ((FIXP_DBL)((INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)127))
123
124
912k
#define DRC_BLOCK_LEN (1024)
125
912k
#define DRC_BAND_MULT (4)
126
912k
#define DRC_BLOCK_LEN_DIV_BAND_MULT (DRC_BLOCK_LEN / DRC_BAND_MULT)
127
128
22.1k
#define MAX_REFERENCE_LEVEL (127)
129
130
0
#define DRC_HEAVY_THRESHOLD_DB (10)
131
132
11.7k
#define DVB_ANC_DATA_SYNC_BYTE (0xBC) /* DVB ancillary data sync byte. */
133
134
66.5k
#define OFF 0
135
999k
#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
489k
void aacDecoder_drcDisable(HANDLE_AAC_DRC self) {
160
489k
  self->enable = 0;
161
489k
  self->applyExtGain = 0;
162
489k
  self->progRefLevelPresent = 0;
163
489k
}
164
165
/*!
166
\brief Reset DRC information
167
168
\self Handle of DRC info
169
170
\return none
171
*/
172
22.1k
void aacDecoder_drcReset(HANDLE_AAC_DRC self) {
173
22.1k
  self->applyExtGain = 0;
174
22.1k
  self->additionalGainPrev = AACDEC_DRC_GAIN_INIT_VALUE;
175
22.1k
  self->additionalGainFilterState = AACDEC_DRC_GAIN_INIT_VALUE;
176
22.1k
  self->additionalGainFilterState1 = AACDEC_DRC_GAIN_INIT_VALUE;
177
22.1k
}
178
179
/*!
180
  \brief Initialize DRC information
181
182
  \self Handle of DRC info
183
184
  \return none
185
*/
186
22.1k
void aacDecoder_drcInit(HANDLE_AAC_DRC self) {
187
22.1k
  CDrcParams *pParams;
188
189
22.1k
  if (self == NULL) {
190
0
    return;
191
0
  }
192
193
  /* init control fields */
194
22.1k
  self->enable = OFF;
195
22.1k
  self->numThreads = 0;
196
197
  /* init params */
198
22.1k
  pParams = &self->params;
199
22.1k
  pParams->bsDelayEnable = 0;
200
22.1k
  pParams->cut = FL2FXCONST_DBL(0.0f);
201
22.1k
  pParams->usrCut = FL2FXCONST_DBL(0.0f);
202
22.1k
  pParams->boost = FL2FXCONST_DBL(0.0f);
203
22.1k
  pParams->usrBoost = FL2FXCONST_DBL(0.0f);
204
22.1k
  pParams->targetRefLevel = 96;
205
22.1k
  pParams->expiryFrame = AACDEC_DRC_DFLT_EXPIRY_FRAMES;
206
22.1k
  pParams->applyHeavyCompression = OFF;
207
22.1k
  pParams->usrApplyHeavyCompression = OFF;
208
209
22.1k
  pParams->defaultPresentationMode = DISABLED_PARAMETER_HANDLING;
210
22.1k
  pParams->encoderTargetLevel = MAX_REFERENCE_LEVEL; /* worst case assumption */
211
212
22.1k
  self->update = 1;
213
22.1k
  self->numOutChannels = 0;
214
22.1k
  self->prevAacNumChannels = 0;
215
216
  /* initial program ref level = target ref level */
217
22.1k
  self->progRefLevel = pParams->targetRefLevel;
218
22.1k
  self->progRefLevelPresent = 0;
219
22.1k
  self->presMode = -1;
220
221
22.1k
  aacDecoder_drcReset(self);
222
22.1k
}
223
224
/*!
225
  \brief Initialize DRC control data for one channel
226
227
  \self Handle of DRC info
228
229
  \return none
230
*/
231
876k
void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
232
876k
  if (pDrcChData != NULL) {
233
876k
    pDrcChData->expiryCount = 0;
234
876k
    pDrcChData->numBands = 1;
235
876k
    pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
236
876k
    pDrcChData->drcValue[0] = 0;
237
876k
    pDrcChData->drcInterpolationScheme = 0;
238
876k
    pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
239
876k
  }
240
876k
}
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
576k
                                         AACDEC_DRC_PARAM param, INT value) {
253
576k
  AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
254
255
576k
  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
59.1k
    case DRC_BS_DELAY:
334
59.1k
      if (value < 0 || value > 1) {
335
0
        return AAC_DEC_SET_PARAM_FAIL;
336
0
      }
337
59.1k
      if (self == NULL) {
338
0
        return AAC_DEC_INVALID_HANDLE;
339
0
      }
340
59.1k
      self->params.bsDelayEnable = value;
341
59.1k
      break;
342
517k
    case DRC_DATA_EXPIRY_FRAME:
343
517k
      if (self == NULL) {
344
0
        return AAC_DEC_INVALID_HANDLE;
345
0
      }
346
517k
      self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
347
517k
      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
576k
  } /* switch(param) */
358
359
576k
  return ErrorStatus;
360
576k
}
361
362
static int parseExcludedChannels(UINT *excludedChnsMask,
363
22.4k
                                 HANDLE_FDK_BITSTREAM bs) {
364
22.4k
  UINT excludeMask = 0;
365
22.4k
  UINT i, j;
366
22.4k
  int bitCnt = 9;
367
368
179k
  for (i = 0, j = 1; i < 7; i++, j <<= 1) {
369
157k
    if (FDKreadBits(bs, 1)) {
370
130k
      excludeMask |= j;
371
130k
    }
372
157k
  }
373
374
  /* additional_excluded_chns */
375
47.8k
  while (FDKreadBits(bs, 1)) {
376
202k
    for (i = 0; i < 7; i++, j <<= 1) {
377
177k
      if (FDKreadBits(bs, 1)) {
378
125k
        excludeMask |= j;
379
125k
      }
380
177k
    }
381
25.3k
    bitCnt += 9;
382
25.3k
    FDK_ASSERT(j < (UINT)-1);
383
25.3k
  }
384
385
22.4k
  *excludedChnsMask = excludeMask;
386
387
22.4k
  return (bitCnt);
388
22.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
110k
                              AACDEC_DRC_PAYLOAD_TYPE type) {
400
110k
  UINT bsStartPos;
401
110k
  int i, numBands = 1, bitCnt = 0;
402
403
110k
  if (self == NULL) {
404
0
    return 0;
405
0
  }
406
407
110k
  bsStartPos = FDKgetValidBits(bs);
408
409
110k
  switch (type) {
410
100k
    case MPEG_DRC_EXT_DATA: {
411
100k
      bitCnt = 4;
412
413
100k
      if (FDKreadBits(bs, 1)) { /* pce_tag_present */
414
24.8k
        FDKreadBits(bs, 8);     /* pce_instance_tag + drc_tag_reserved_bits */
415
24.8k
        bitCnt += 8;
416
24.8k
      }
417
418
100k
      if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
419
94.2k
        FDKreadBits(bs, 7);     /* exclude mask [0..7] */
420
94.2k
        bitCnt += 8;
421
181k
        while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
422
87.6k
          FDKreadBits(bs, 7);        /* exclude mask [x..y] */
423
87.6k
          bitCnt += 8;
424
87.6k
        }
425
94.2k
      }
426
427
100k
      if (FDKreadBits(bs, 1)) {         /* drc_bands_present */
428
94.2k
        numBands += FDKreadBits(bs, 4); /* drc_band_incr */
429
94.2k
        FDKreadBits(bs, 4);             /* reserved */
430
94.2k
        bitCnt += 8;
431
761k
        for (i = 0; i < numBands; i++) {
432
667k
          FDKreadBits(bs, 8); /* drc_band_top[i] */
433
667k
          bitCnt += 8;
434
667k
        }
435
94.2k
      }
436
437
100k
      if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
438
93.4k
        FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
439
93.4k
        bitCnt += 8;
440
93.4k
      }
441
442
774k
      for (i = 0; i < numBands; i++) {
443
673k
        FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
444
673k
        bitCnt += 8;
445
673k
      }
446
447
100k
      if ((self->numPayloads < MAX_DRC_THREADS) &&
448
28.0k
          ((INT)FDKgetValidBits(bs) >= 0)) {
449
27.8k
        self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
450
27.8k
      }
451
100k
    } break;
452
453
9.52k
    case DVB_DRC_ANC_DATA:
454
9.52k
      bitCnt += 8;
455
      /* check sync word */
456
9.52k
      if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
457
3.86k
        int dmxLevelsPresent, compressionPresent;
458
3.86k
        int coarseGrainTcPresent, fineGrainTcPresent;
459
460
        /* bs_info field */
461
3.86k
        FDKreadBits(
462
3.86k
            bs,
463
3.86k
            8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
464
3.86k
        bitCnt += 8;
465
466
        /* Evaluate ancillary_data_status */
467
3.86k
        FDKreadBits(bs, 3); /* reserved, set to 0 */
468
3.86k
        dmxLevelsPresent =
469
3.86k
            FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
470
3.86k
        FDKreadBits(bs, 1);     /* reserved, set to 0 */
471
3.86k
        compressionPresent =
472
3.86k
            FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
473
3.86k
        coarseGrainTcPresent =
474
3.86k
            FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
475
3.86k
        fineGrainTcPresent =
476
3.86k
            FDKreadBits(bs, 1); /* fine_grain_timecode_status */
477
3.86k
        bitCnt += 8;
478
479
        /* MPEG4 downmixing levels */
480
3.86k
        if (dmxLevelsPresent) {
481
1.86k
          FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
482
1.86k
          bitCnt += 8;
483
1.86k
        }
484
        /* audio coding mode and compression status */
485
3.86k
        if (compressionPresent) {
486
2.02k
          FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
487
2.02k
          bitCnt += 16;
488
2.02k
        }
489
        /* coarse grain timecode */
490
3.86k
        if (coarseGrainTcPresent) {
491
2.34k
          FDKreadBits(bs, 16); /* coarse_grain_timecode */
492
2.34k
          bitCnt += 16;
493
2.34k
        }
494
        /* fine grain timecode */
495
3.86k
        if (fineGrainTcPresent) {
496
2.70k
          FDKreadBits(bs, 16); /* fine_grain_timecode */
497
2.70k
          bitCnt += 16;
498
2.70k
        }
499
3.86k
        if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
500
2.31k
          self->dvbAncDataPosition = bsStartPos;
501
2.31k
          self->dvbAncDataAvailable = 1;
502
2.31k
        }
503
3.86k
      }
504
9.52k
      break;
505
506
0
    default:
507
0
      break;
508
110k
  }
509
510
110k
  return (bitCnt);
511
110k
}
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
27.6k
                               UINT payloadPosition) {
524
27.6k
  int i, numBands;
525
526
  /* Move to the beginning of the DRC payload field */
527
27.6k
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
528
529
  /* pce_tag_present */
530
27.6k
  if (FDKreadBits(bs, 1)) {
531
8.02k
    pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
532
    /* only one program supported */
533
8.02k
    FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
534
19.6k
  } else {
535
19.6k
    pDrcBs->pceInstanceTag = -1; /* not present */
536
19.6k
  }
537
538
27.6k
  if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
539
    /* get excluded_chn_mask */
540
22.4k
    parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
541
22.4k
  } else {
542
5.18k
    pDrcBs->excludedChnsMask = 0;
543
5.18k
  }
544
545
27.6k
  numBands = 1;
546
27.6k
  if (FDKreadBits(bs, 1)) /* drc_bands_present */
547
21.9k
  {
548
    /* get band_incr */
549
21.9k
    numBands += FDKreadBits(bs, 4); /* drc_band_incr */
550
21.9k
    pDrcBs->channelData.drcInterpolationScheme =
551
21.9k
        FDKreadBits(bs, 4); /* drc_interpolation_scheme */
552
    /* band_top */
553
178k
    for (i = 0; i < numBands; i++) {
554
156k
      pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
555
156k
    }
556
21.9k
  } else {
557
5.65k
    pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
558
5.65k
                                     1; /* ... comprising the whole spectrum. */
559
5.65k
    ;
560
5.65k
  }
561
562
27.6k
  pDrcBs->channelData.numBands = numBands;
563
564
27.6k
  if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
565
21.8k
  {
566
21.8k
    pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
567
21.8k
    FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
568
21.8k
  } else {
569
5.77k
    pDrcBs->progRefLevel = -1;
570
5.77k
  }
571
572
190k
  for (i = 0; i < numBands; i++) {
573
162k
    pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
574
162k
                                      << 7; /* dyn_rng_sgn[i] */
575
162k
    pDrcBs->channelData.drcValue[i] |=
576
162k
        FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
577
162k
  }
578
579
  /* Set DRC payload type */
580
27.6k
  pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
581
582
27.6k
  return (1);
583
27.6k
}
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
3.24k
#define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */
596
597
static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
598
                                         CDrcPayload *pDrcBs,
599
2.25k
                                         UINT payloadPosition) {
600
2.25k
  int foundDrcData = 0;
601
2.25k
  int dmxLevelsPresent, compressionPresent;
602
603
  /* Move to the beginning of the DRC payload field */
604
2.25k
  FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
605
606
  /* Sanity checks */
607
2.25k
  if (FDKgetValidBits(bs) < 24) {
608
0
    return 0;
609
0
  }
610
611
  /* Check sync word */
612
2.25k
  if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
613
0
    return 0;
614
0
  }
615
616
  /* Evaluate bs_info field */
617
2.25k
  if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
618
    /* No MPEG-4 audio data */
619
88
    return 0;
620
88
  }
621
2.17k
  FDKreadBits(bs, 2);                    /* dolby_surround_mode */
622
2.17k
  pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
623
2.17k
  FDKreadBits(bs, 1);                    /* stereo_downmix_mode */
624
2.17k
  if (FDKreadBits(bs, 1) != 0) {         /* reserved, set to 0 */
625
663
    return 0;
626
663
  }
627
628
  /* Evaluate ancillary_data_status */
629
1.50k
  if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
630
39
    return 0;
631
39
  }
632
1.46k
  dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
633
1.46k
  /*extensionPresent =*/FDKreadBits(bs,
634
1.46k
                                    1); /* ancillary_data_extension_status; */
635
1.46k
  compressionPresent =
636
1.46k
      FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
637
1.46k
  /*coarseGrainTcPresent =*/FDKreadBits(bs,
638
1.46k
                                        1); /* coarse_grain_timecode_status */
639
1.46k
  /*fineGrainTcPresent   =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */
640
641
1.46k
  if (dmxLevelsPresent) {
642
207
    FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
643
207
  }
644
645
  /* audio_coding_mode_and_compression_status */
646
1.46k
  if (compressionPresent) {
647
1.39k
    UCHAR compressionOn, compressionValue;
648
649
    /* audio_coding_mode */
650
1.39k
    if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
651
327
      return 0;
652
327
    }
653
1.06k
    compressionOn = (UCHAR)FDKreadBits(bs, 1);    /* compression_on */
654
1.06k
    compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */
655
656
1.06k
    if (compressionOn) {
657
      /* A compression value is available so store the data just like MPEG DRC
658
       * data */
659
899
      pDrcBs->channelData.numBands = 1; /* One band ... */
660
899
      pDrcBs->channelData.drcValue[0] =
661
899
          compressionValue; /* ... with one value ... */
662
899
      pDrcBs->channelData.bandTop[0] =
663
899
          DRC_BLOCK_LEN_DIV_BAND_MULT -
664
899
          1; /* ... comprising the whole spectrum. */
665
899
      ;
666
899
      pDrcBs->pceInstanceTag = -1; /* Not present */
667
899
      pDrcBs->progRefLevel = -1;   /* Not present */
668
899
      pDrcBs->channelData.drcDataType =
669
899
          DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
670
899
      foundDrcData = 1;
671
899
    }
672
1.06k
  }
673
674
1.14k
  return (foundDrcData);
675
1.46k
}
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
342k
    int validChannels) {
691
342k
  CDrcPayload threadBs[MAX_DRC_THREADS];
692
342k
  CDrcPayload *validThreadBs[MAX_DRC_THREADS];
693
342k
  CDrcParams *pParams;
694
342k
  UINT backupBsPosition;
695
342k
  int result = 0;
696
342k
  int i, thread, validThreads = 0;
697
698
342k
  FDK_ASSERT(self != NULL);
699
342k
  FDK_ASSERT(hBs != NULL);
700
342k
  FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
701
702
342k
  pParams = &self->params;
703
704
342k
  self->numThreads = 0;
705
342k
  backupBsPosition = FDKgetValidBits(hBs);
706
707
369k
  for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
708
342k
       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
27.6k
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
713
27.6k
    threadBs[self->numThreads].channelData.bandTop[0] =
714
27.6k
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
715
716
    /* Extract payload */
717
27.6k
    self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
718
27.6k
                                            self->drcPayloadPosition[i]);
719
27.6k
  }
720
342k
  self->numPayloads = 0;
721
722
342k
  if (self->dvbAncDataAvailable &&
723
2.25k
      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
2.25k
    FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
730
2.25k
    threadBs[self->numThreads].channelData.bandTop[0] =
731
2.25k
        DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
732
733
    /* Extract payload */
734
2.25k
    self->numThreads += aacDecoder_drcReadCompression(
735
2.25k
        hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
736
2.25k
  }
737
342k
  self->dvbAncDataAvailable = 0;
738
739
  /* Reset the bitbufffer */
740
342k
  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
370k
  for (thread = 0; thread < self->numThreads; thread++) {
748
28.5k
    CDrcPayload *pThreadBs = &threadBs[thread];
749
28.5k
    int numExclChns = 0;
750
751
28.5k
    switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
752
0
      default:
753
0
        continue;
754
27.6k
      case MPEG_DRC_EXT_DATA:
755
28.5k
      case DVB_DRC_ANC_DATA:
756
28.5k
        break;
757
28.5k
    }
758
759
28.5k
    if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
760
8.02k
      if (pThreadBs->pceInstanceTag != pceInstanceTag) {
761
3.26k
        continue; /* don't accept */
762
3.26k
      }
763
8.02k
    }
764
765
    /* calculate number of excluded channels */
766
25.2k
    if (pThreadBs->excludedChnsMask > 0) {
767
19.7k
      INT exclMask = pThreadBs->excludedChnsMask;
768
19.7k
      int ch;
769
44.6k
      for (ch = 0; ch < validChannels; ch++) {
770
24.9k
        numExclChns += exclMask & 0x1;
771
24.9k
        exclMask >>= 1;
772
24.9k
      }
773
19.7k
    }
774
25.2k
    if (numExclChns < validChannels) {
775
9.47k
      validThreadBs[validThreads] = pThreadBs;
776
9.47k
      validThreads++;
777
9.47k
    }
778
25.2k
  }
779
780
  /* map DRC bitstream information onto DRC channel information */
781
351k
  for (thread = 0; thread < validThreads; thread++) {
782
9.47k
    CDrcPayload *pThreadBs = validThreadBs[thread];
783
9.47k
    INT exclMask = pThreadBs->excludedChnsMask;
784
9.47k
    AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
785
9.47k
        (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
786
9.47k
    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
9.47k
    if (pThreadBs->progRefLevel >= 0) {
792
3.92k
      self->progRefLevel = pThreadBs->progRefLevel;
793
3.92k
      self->progRefLevelPresent = 1;
794
3.92k
      self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
795
3.92k
    }
796
797
9.47k
    if (drcPayloadType == DVB_DRC_ANC_DATA) {
798
      /* Announce the presentation mode of this valid thread. */
799
899
      self->presMode = pThreadBs->presMode;
800
899
    }
801
802
    /* SCE, CPE and LFE */
803
32.5k
    for (ch = 0; ch < validChannels; ch++) {
804
23.0k
      AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
805
23.0k
      int mapedChannel = channelMapping[ch];
806
807
23.0k
      if ((mapedChannel >= validChannels) ||
808
22.9k
          ((exclMask & (1 << mapedChannel)) != 0))
809
2.42k
        continue;
810
811
20.6k
      if ((pParams->expiryFrame <= 0) ||
812
0
          (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
813
20.6k
           pParams->expiryFrame)) {
814
20.6k
        prvPayloadType =
815
20.6k
            (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
816
20.6k
                ->drcData.drcDataType;
817
20.6k
      }
818
20.6k
      if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
819
18.1k
           (prvPayloadType != DVB_DRC_ANC_DATA)) ||
820
2.67k
          ((drcPayloadType == DVB_DRC_ANC_DATA) &&
821
2.50k
           (pParams->applyHeavyCompression ==
822
19.9k
            ON))) { /* copy thread to channel */
823
19.9k
        pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
824
19.9k
        result = 1;
825
19.9k
      }
826
20.6k
    }
827
    /* CCEs not supported by now */
828
9.47k
  }
829
830
  /* Increment and check expiry counter for the program reference level: */
831
342k
  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
342k
  return result;
841
342k
}
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
566k
                         int aacFrameSize, int bSbrPresent) {
848
566k
  int band, bin, numBands;
849
566k
  int bottom = 0;
850
566k
  int modifyBins = 0;
851
852
566k
  FIXP_DBL max_mantissa;
853
566k
  INT max_exponent;
854
855
566k
  FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
856
566k
  INT norm_exponent = 1;
857
858
566k
  FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
859
566k
  INT fact_exponent[MAX_DRC_BANDS];
860
861
566k
  CDrcParams *pParams = &self->params;
862
863
566k
  FIXP_DBL *pSpectralCoefficient =
864
566k
      SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
865
566k
  CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
866
566k
  SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
867
868
566k
  int winSeq = pIcsInfo->WindowSequence;
869
870
  /* Increment and check expiry counter */
871
566k
  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
566k
  if (self->enable != ON) {
878
300k
    sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
879
300k
    if (extGain != NULL) {
880
300k
      INT gainScale = (INT)*extGain;
881
      /* The gain scaling must be passed to the function in the buffer pointed
882
       * on by extGain. */
883
300k
      if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
884
300k
        *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
885
300k
      } else {
886
0
        FDK_ASSERT(0);
887
0
      }
888
300k
    }
889
300k
    return;
890
300k
  }
891
892
265k
  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
265k
  if (pParams->targetRefLevel >= 0) {
902
    /* 0.5^((targetRefLevel - progRefLevel)/24) */
903
265k
    norm_mantissa =
904
265k
        fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
905
265k
               0,
906
265k
               (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
907
265k
                          (INT)(pParams->targetRefLevel - self->progRefLevel)),
908
265k
               3, &norm_exponent);
909
265k
  }
910
  /* Always export the normalization gain (if possible). */
911
265k
  if (extGain != NULL) {
912
265k
    INT gainScale = (INT)*extGain;
913
    /* The gain scaling must be passed to the function in the buffer pointed on
914
     * by extGain. */
915
265k
    if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
916
265k
      *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
917
265k
    } else {
918
0
      FDK_ASSERT(0);
919
0
    }
920
265k
  }
921
  /* Reset normalization gain since this module must not apply it */
922
265k
  norm_mantissa = FL2FXCONST_DBL(0.5f);
923
265k
  norm_exponent = 1;
924
925
  /* calc scale factors */
926
662k
  for (band = 0; band < numBands; band++) {
927
397k
    UCHAR drcVal = pDrcChData->drcValue[band];
928
929
397k
    fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
930
397k
    fact_exponent[band] = 1;
931
932
397k
    if ((pParams->applyHeavyCompression == ON) &&
933
4.63k
        ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
934
4.63k
         DVB_DRC_ANC_DATA)) {
935
3.28k
      INT compressionFactorVal_e;
936
3.28k
      int valX, valY;
937
938
3.28k
      valX = drcVal >> 4;
939
3.28k
      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
3.28k
      if (drcVal != 0x7F) {
945
3.24k
        fact_mantissa[band] = fPowInt(
946
3.24k
            FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
947
3.24k
            0, valY, &compressionFactorVal_e);
948
949
        /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
950
3.24k
        fact_mantissa[band] =
951
3.24k
            fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);
952
953
3.24k
        fact_exponent[band] =
954
3.24k
            DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
955
3.24k
      }
956
394k
    } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
957
394k
               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
179k
      if ((drcVal & 0x7F) > 0) {
969
126k
        FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;
970
971
126k
        fact_mantissa[band] = f2Pow(
972
126k
            (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
973
126k
                       (drcVal & 0x7F)),
974
126k
            3 + DRC_PARAM_SCALE, &fact_exponent[band]);
975
126k
      }
976
179k
    }
977
978
397k
    fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
979
397k
    fact_exponent[band] += norm_exponent;
980
981
397k
  } /* end loop over bands */
982
983
  /* normalizations */
984
265k
  {
985
265k
    int res;
986
987
265k
    max_mantissa = FL2FXCONST_DBL(0.0f);
988
265k
    max_exponent = 0;
989
662k
    for (band = 0; band < numBands; band++) {
990
397k
      max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
991
397k
      max_exponent = fixMax(max_exponent, fact_exponent[band]);
992
397k
    }
993
994
    /* left shift factors to gain accurancy */
995
265k
    res = CntLeadingZeros(max_mantissa) - 1;
996
997
    /* above topmost DRC band gain factor is 1 */
998
265k
    if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
999
16.7k
      res = 0;
1000
1001
265k
    if (res > 0) {
1002
248k
      res = fixMin(res, max_exponent);
1003
248k
      max_exponent -= res;
1004
1005
503k
      for (band = 0; band < numBands; band++) {
1006
255k
        fact_mantissa[band] <<= res;
1007
255k
        fact_exponent[band] -= res;
1008
255k
      }
1009
248k
    }
1010
1011
    /* normalize magnitudes to one scale factor */
1012
662k
    for (band = 0; band < numBands; band++) {
1013
397k
      if (fact_exponent[band] < max_exponent) {
1014
796
        fact_mantissa[band] >>= max_exponent - fact_exponent[band];
1015
796
      }
1016
397k
      if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
1017
145k
        modifyBins = 1;
1018
145k
      }
1019
397k
    }
1020
265k
    if (max_exponent != 1) {
1021
20.0k
      modifyBins = 1;
1022
20.0k
    }
1023
265k
  }
1024
1025
  /*  apply factor to spectral lines
1026
   *  short blocks must take care that bands fall on
1027
   *  block boundaries!
1028
   */
1029
265k
  if (!bSbrPresent) {
1030
122k
    bottom = 0;
1031
1032
122k
    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
113k
      max_exponent -= 1;
1037
113k
    } else {
1038
105k
      for (band = 0; band < numBands; band++) {
1039
96.5k
        int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
1040
96.5k
                         aacFrameSize); /* ... * DRC_BAND_MULT; */
1041
1042
6.09M
        for (bin = bottom; bin < top; bin++) {
1043
5.99M
          pSpectralCoefficient[bin] =
1044
5.99M
              fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
1045
5.99M
        }
1046
1047
96.5k
        bottom = top;
1048
96.5k
      }
1049
9.02k
    }
1050
1051
    /* above topmost DRC band gain factor is 1 */
1052
122k
    if (max_exponent > 0) {
1053
4.72M
      for (bin = bottom; bin < aacFrameSize; bin += 1) {
1054
4.71M
        pSpectralCoefficient[bin] >>= max_exponent;
1055
4.71M
      }
1056
9.01k
    }
1057
1058
    /* adjust scaling */
1059
122k
    pSpecScale[0] += max_exponent;
1060
1061
122k
    if (winSeq == BLOCK_SHORT) {
1062
26.2k
      int win;
1063
209k
      for (win = 1; win < 8; win++) {
1064
183k
        pSpecScale[win] += max_exponent;
1065
183k
      }
1066
26.2k
    }
1067
142k
  } else {
1068
142k
    HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
1069
142k
    numBands = pDrcChData->numBands;
1070
1071
    /* feed factors into SBR decoder for application in QMF domain. */
1072
142k
    sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
1073
142k
                              max_exponent, pDrcChData->drcInterpolationScheme,
1074
142k
                              winSeq, pDrcChData->bandTop);
1075
142k
  }
1076
1077
265k
  return;
1078
265k
}
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
342k
                                            SCHAR prevDrcPresMode) {
1087
342k
  int isDownmix, isMonoDownmix, isStereoDownmix;
1088
342k
  int dDmx, dHr;
1089
342k
  AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
1090
342k
  CDrcParams *p;
1091
1092
342k
  FDK_ASSERT(self != NULL);
1093
1094
342k
  p = &self->params;
1095
1096
342k
  if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;
1097
1098
342k
  if (self->presMode != prevDrcPresMode) self->update = 1;
1099
1100
342k
  if (self->prevAacNumChannels != aacNumChannels) self->update = 1;
1101
1102
  /* return if no relevant parameter has changed */
1103
342k
  if (!self->update) {
1104
325k
    return;
1105
325k
  }
1106
1107
  /* derive downmix property. aacNumChannels: number of channels in aac stream,
1108
   * numOutChannels: number of output channels */
1109
16.8k
  isDownmix = (aacNumChannels > self->numOutChannels);
1110
16.8k
  isDownmix = (isDownmix && (self->numOutChannels > 0));
1111
16.8k
  isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
1112
16.8k
  isStereoDownmix = (isDownmix && (self->numOutChannels == 2));
1113
1114
16.8k
  if ((self->presMode == 1) || (self->presMode == 2)) {
1115
907
    drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
1116
15.9k
  } else { /* no presentation mode -> use parameter handling specified by
1117
              AAC_DRC_DEFAULT_PRESENTATION_MODE */
1118
15.9k
    drcParameterHandling = p->defaultPresentationMode;
1119
15.9k
  }
1120
1121
  /* by default, do as desired */
1122
16.8k
  p->cut = p->usrCut;
1123
16.8k
  p->boost = p->usrBoost;
1124
16.8k
  p->applyHeavyCompression = p->usrApplyHeavyCompression;
1125
1126
16.8k
  switch (drcParameterHandling) {
1127
15.9k
    case DISABLED_PARAMETER_HANDLING:
1128
15.9k
    default:
1129
      /* use drc parameters as requested */
1130
15.9k
      break;
1131
1132
15.9k
    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
837
    case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
1210
837
      if ((p->targetRefLevel >= 0) &&
1211
837
          (p->targetRefLevel <
1212
837
           124)) { /* if target level is provided and > -31 dB */
1213
        /* playback up to -23 dB */
1214
837
        p->applyHeavyCompression = ON;
1215
837
      } 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
837
      break;
1222
1223
70
    case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
1224
70
      if ((p->targetRefLevel >= 0) &&
1225
70
          (p->targetRefLevel <
1226
70
           124)) { /* if target level is provided and > -31 dB */
1227
        /* playback up to -23 dB */
1228
70
        if (isMonoDownmix) { /* if mono downmix */
1229
0
          p->applyHeavyCompression = ON;
1230
70
        } else {
1231
70
          p->applyHeavyCompression = OFF;
1232
70
          p->cut = DRC_SCALING_MAX;
1233
70
        }
1234
70
      } 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
70
      break;
1242
16.8k
  } /*  switch (drcParameterHandling) */
1243
1244
  /* With heavy compression, there is no scaling.
1245
     Scaling factors are set for notification only. */
1246
16.8k
  if (p->applyHeavyCompression == ON) {
1247
837
    p->boost = DRC_SCALING_MAX;
1248
837
    p->cut = DRC_SCALING_MAX;
1249
837
  }
1250
1251
  /* switch on/off processing */
1252
16.8k
  self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
1253
15.9k
                  (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
1254
1255
16.8k
  self->prevAacNumChannels = aacNumChannels;
1256
16.8k
  self->update = 0;
1257
16.8k
}
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
342k
    int validChannels) {
1273
342k
  int result = 0;
1274
1275
342k
  if (self == NULL) {
1276
0
    return -1;
1277
0
  }
1278
1279
342k
  if (!self->params.bsDelayEnable) {
1280
    /* keep previous progRefLevel and presMode for update flag in
1281
     * drcParameterHandling */
1282
311k
    INT prevPRL, prevPM = 0;
1283
311k
    prevPRL = self->progRefLevel;
1284
311k
    prevPM = self->presMode;
1285
1286
311k
    result = aacDecoder_drcExtractAndMap(
1287
311k
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1288
311k
        validChannels);
1289
1290
311k
    if (result < 0) {
1291
0
      return result;
1292
0
    }
1293
1294
    /* Drc parameter handling */
1295
311k
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1296
311k
  }
1297
1298
342k
  return result;
1299
342k
}
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
341k
    int validChannels) {
1315
341k
  int result = 0;
1316
1317
341k
  if (self == NULL) {
1318
0
    return -1;
1319
0
  }
1320
1321
341k
  if (self->params.bsDelayEnable) {
1322
    /* keep previous progRefLevel and presMode for update flag in
1323
     * drcParameterHandling */
1324
30.8k
    INT prevPRL, prevPM = 0;
1325
30.8k
    prevPRL = self->progRefLevel;
1326
30.8k
    prevPM = self->presMode;
1327
1328
30.8k
    result = aacDecoder_drcExtractAndMap(
1329
30.8k
        self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1330
30.8k
        validChannels);
1331
1332
30.8k
    if (result < 0) {
1333
0
      return result;
1334
0
    }
1335
1336
    /* Drc parameter handling */
1337
30.8k
    aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1338
30.8k
  }
1339
1340
341k
  return result;
1341
341k
}
1342
1343
/*
1344
 * Export relevant metadata info from bitstream payload.
1345
 */
1346
void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
1347
341k
                           SCHAR *pProgRefLevel) {
1348
341k
  if (self != NULL) {
1349
341k
    if (pPresMode != NULL) {
1350
341k
      *pPresMode = self->presMode;
1351
341k
    }
1352
341k
    if (pProgRefLevel != NULL) {
1353
341k
      if (self->progRefLevelPresent) {
1354
15.8k
        *pProgRefLevel = self->progRefLevel;
1355
326k
      } else {
1356
326k
        *pProgRefLevel = -1;
1357
326k
      }
1358
341k
    }
1359
341k
  }
1360
341k
}
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
15.8k
                               const UINT stride, const UINT limiterEnabled) {
1402
15.8k
  UINT i;
1403
15.8k
  INT additionalGain_scaling;
1404
15.8k
  FIXP_DBL additionalGain;
1405
1406
15.8k
  FDK_ASSERT(gain_delay <= nSamples);
1407
1408
15.8k
  FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState;
1409
15.8k
  FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1;
1410
1411
15.8k
  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
15.8k
  } else {
1441
15.8k
    UINT inc;
1442
15.8k
    FIXP_DBL additionalGainUnfiltered;
1443
1444
15.8k
    inc = (stride == 1) ? channels : 1;
1445
1446
20.8M
    for (i = 0; i < nSamples; i++) {
1447
20.8M
      if (i < gain_delay) {
1448
12.5M
        additionalGainUnfiltered = hDrcInfo->additionalGainPrev;
1449
12.5M
      } else {
1450
8.31M
        additionalGainUnfiltered = pGain[0];
1451
8.31M
      }
1452
1453
      /* Smooth additionalGain */
1454
1455
      /* [b,a] = butter(1, 0.01) */
1456
20.8M
      static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
1457
20.8M
                                   FL2FXCONST_SGL(0.015466 * 2.0)};
1458
20.8M
      static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
1459
20.8M
                                   FL2FXCONST_SGL(-0.96907)};
1460
1461
20.8M
      additionalGain = -fMult(additionalGainSmoothState, a[1]) +
1462
20.8M
                       fMultDiv2(additionalGainUnfiltered, b[0]) +
1463
20.8M
                       fMultDiv2(additionalGainSmoothState1, b[1]);
1464
20.8M
      additionalGainSmoothState1 = additionalGainUnfiltered;
1465
20.8M
      additionalGainSmoothState = additionalGain;
1466
1467
      /* Apply the additional scaling gain_scale[0] that has no delay and no
1468
       * smoothing */
1469
20.8M
      additionalGain_scaling =
1470
20.8M
          fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
1471
20.8M
      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
20.8M
      additionalGain_scaling -= gain_scale;
1476
1477
20.8M
      if (limiterEnabled) {
1478
18.1M
        FDK_ASSERT(stride == 1);
1479
18.1M
        FDK_ASSERT(pGainPerSample != NULL);
1480
1481
18.1M
        if (additionalGain_scaling) {
1482
88.7k
          scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling);
1483
88.7k
        }
1484
1485
18.1M
        pGainPerSample[i] = additionalGain;
1486
18.1M
      } else {
1487
2.72M
        if (additionalGain_scaling) {
1488
42.4k
          for (UINT k = 0; k < channels; k++) {
1489
36.3k
            scaleValuesSaturate(&samplesIn[k * stride], 1,
1490
36.3k
                                -additionalGain_scaling);
1491
36.3k
          }
1492
6.06k
        }
1493
1494
9.28M
        for (UINT k = 0; k < channels; k++) {
1495
6.56M
          samplesIn[k * stride] =
1496
6.56M
              FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain));
1497
6.56M
        }
1498
2.72M
      }
1499
1500
20.8M
      samplesIn += inc;
1501
20.8M
    }
1502
15.8k
  }
1503
1504
15.8k
  hDrcInfo->additionalGainPrev = pGain[0];
1505
15.8k
  hDrcInfo->additionalGainFilterState = additionalGainSmoothState;
1506
15.8k
  hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1;
1507
1508
15.8k
  return (AACDEC_DRC_GAIN_SCALING);
1509
15.8k
}