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