Coverage Report

Created: 2025-07-18 06:04

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