• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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 
221   aacDecoder_drcReset(self);
222 }
223 
224 /*!
225   \brief Initialize DRC control data for one channel
226 
227   \self Handle of DRC info
228 
229   \return none
230 */
aacDecoder_drcInitChannelData(CDrcChannelData * pDrcChData)231 void aacDecoder_drcInitChannelData(CDrcChannelData *pDrcChData) {
232   if (pDrcChData != NULL) {
233     pDrcChData->expiryCount = 0;
234     pDrcChData->numBands = 1;
235     pDrcChData->bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
236     pDrcChData->drcValue[0] = 0;
237     pDrcChData->drcInterpolationScheme = 0;
238     pDrcChData->drcDataType = UNKNOWN_PAYLOAD;
239   }
240 }
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 */
aacDecoder_drcSetParam(HANDLE_AAC_DRC self,AACDEC_DRC_PARAM param,INT value)251 AAC_DECODER_ERROR aacDecoder_drcSetParam(HANDLE_AAC_DRC self,
252                                          AACDEC_DRC_PARAM param, INT value) {
253   AAC_DECODER_ERROR ErrorStatus = AAC_DEC_OK;
254 
255   switch (param) {
256     case DRC_CUT_SCALE:
257       /* set attenuation scale factor */
258       if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
259         return AAC_DEC_SET_PARAM_FAIL;
260       }
261       if (self == NULL) {
262         return AAC_DEC_INVALID_HANDLE;
263       }
264       self->params.usrCut = (FIXP_DBL)(
265           (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
266       self->update = 1;
267       break;
268     case DRC_BOOST_SCALE:
269       /* set boost factor */
270       if ((value < 0) || (value > DRC_MAX_QUANT_FACTOR)) {
271         return AAC_DEC_SET_PARAM_FAIL;
272       }
273       if (self == NULL) {
274         return AAC_DEC_INVALID_HANDLE;
275       }
276       self->params.usrBoost = (FIXP_DBL)(
277           (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * (INT)value);
278       self->update = 1;
279       break;
280     case TARGET_REF_LEVEL:
281       if (value > MAX_REFERENCE_LEVEL || value < -MAX_REFERENCE_LEVEL) {
282         return AAC_DEC_SET_PARAM_FAIL;
283       }
284       if (self == NULL) {
285         return AAC_DEC_INVALID_HANDLE;
286       }
287       if (value < 0) {
288         self->params.targetRefLevel = -1;
289       } else {
290         if (self->params.targetRefLevel != (SCHAR)value) {
291           self->params.targetRefLevel = (SCHAR)value;
292           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         }
297         self->update = 1;
298       }
299       break;
300     case APPLY_HEAVY_COMPRESSION:
301       if ((value != OFF) && (value != ON)) {
302         return AAC_DEC_SET_PARAM_FAIL;
303       }
304       if (self == NULL) {
305         return AAC_DEC_INVALID_HANDLE;
306       }
307       /* Store new parameter value */
308       self->params.usrApplyHeavyCompression = (UCHAR)value;
309       self->update = 1;
310       break;
311     case DEFAULT_PRESENTATION_MODE:
312       if (value < AAC_DRC_PARAMETER_HANDLING_DISABLED ||
313           value > AAC_DRC_PRESENTATION_MODE_2_DEFAULT) {
314         return AAC_DEC_SET_PARAM_FAIL;
315       }
316       if (self == NULL) {
317         return AAC_DEC_INVALID_HANDLE;
318       }
319       self->params.defaultPresentationMode =
320           (AACDEC_DRC_PARAMETER_HANDLING)value;
321       self->update = 1;
322       break;
323     case ENCODER_TARGET_LEVEL:
324       if (value > MAX_REFERENCE_LEVEL || value < 0) {
325         return AAC_DEC_SET_PARAM_FAIL;
326       }
327       if (self == NULL) {
328         return AAC_DEC_INVALID_HANDLE;
329       }
330       self->params.encoderTargetLevel = (UCHAR)value;
331       self->update = 1;
332       break;
333     case DRC_BS_DELAY:
334       if (value < 0 || value > 1) {
335         return AAC_DEC_SET_PARAM_FAIL;
336       }
337       if (self == NULL) {
338         return AAC_DEC_INVALID_HANDLE;
339       }
340       self->params.bsDelayEnable = value;
341       break;
342     case DRC_DATA_EXPIRY_FRAME:
343       if (self == NULL) {
344         return AAC_DEC_INVALID_HANDLE;
345       }
346       self->params.expiryFrame = (value > 0) ? (UINT)value : 0;
347       break;
348     case MAX_OUTPUT_CHANNELS:
349       if (self == NULL) {
350         return AAC_DEC_INVALID_HANDLE;
351       }
352       self->numOutChannels = (INT)value;
353       self->update = 1;
354       break;
355     default:
356       return AAC_DEC_SET_PARAM_FAIL;
357   } /* switch(param) */
358 
359   return ErrorStatus;
360 }
361 
parseExcludedChannels(UINT * excludedChnsMask,HANDLE_FDK_BITSTREAM bs)362 static int parseExcludedChannels(UINT *excludedChnsMask,
363                                  HANDLE_FDK_BITSTREAM bs) {
364   UINT excludeMask = 0;
365   UINT i, j;
366   int bitCnt = 9;
367 
368   for (i = 0, j = 1; i < 7; i++, j <<= 1) {
369     if (FDKreadBits(bs, 1)) {
370       excludeMask |= j;
371     }
372   }
373 
374   /* additional_excluded_chns */
375   while (FDKreadBits(bs, 1)) {
376     for (i = 0; i < 7; i++, j <<= 1) {
377       if (FDKreadBits(bs, 1)) {
378         excludeMask |= j;
379       }
380     }
381     bitCnt += 9;
382     FDK_ASSERT(j < (UINT)-1);
383   }
384 
385   *excludedChnsMask = excludeMask;
386 
387   return (bitCnt);
388 }
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 */
aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self,HANDLE_FDK_BITSTREAM bs,AACDEC_DRC_PAYLOAD_TYPE type)398 int aacDecoder_drcMarkPayload(HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM bs,
399                               AACDEC_DRC_PAYLOAD_TYPE type) {
400   UINT bsStartPos;
401   int i, numBands = 1, bitCnt = 0;
402 
403   if (self == NULL) {
404     return 0;
405   }
406 
407   bsStartPos = FDKgetValidBits(bs);
408 
409   switch (type) {
410     case MPEG_DRC_EXT_DATA: {
411       bitCnt = 4;
412 
413       if (FDKreadBits(bs, 1)) { /* pce_tag_present */
414         FDKreadBits(bs, 8);     /* pce_instance_tag + drc_tag_reserved_bits */
415         bitCnt += 8;
416       }
417 
418       if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
419         FDKreadBits(bs, 7);     /* exclude mask [0..7] */
420         bitCnt += 8;
421         while (FDKreadBits(bs, 1)) { /* additional_excluded_chns */
422           FDKreadBits(bs, 7);        /* exclude mask [x..y] */
423           bitCnt += 8;
424         }
425       }
426 
427       if (FDKreadBits(bs, 1)) {         /* drc_bands_present */
428         numBands += FDKreadBits(bs, 4); /* drc_band_incr */
429         FDKreadBits(bs, 4);             /* reserved */
430         bitCnt += 8;
431         for (i = 0; i < numBands; i++) {
432           FDKreadBits(bs, 8); /* drc_band_top[i] */
433           bitCnt += 8;
434         }
435       }
436 
437       if (FDKreadBits(bs, 1)) { /* prog_ref_level_present */
438         FDKreadBits(bs, 8); /* prog_ref_level + prog_ref_level_reserved_bits */
439         bitCnt += 8;
440       }
441 
442       for (i = 0; i < numBands; i++) {
443         FDKreadBits(bs, 8); /* dyn_rng_sgn[i] + dyn_rng_ctl[i] */
444         bitCnt += 8;
445       }
446 
447       if ((self->numPayloads < MAX_DRC_THREADS) &&
448           ((INT)FDKgetValidBits(bs) >= 0)) {
449         self->drcPayloadPosition[self->numPayloads++] = bsStartPos;
450       }
451     } break;
452 
453     case DVB_DRC_ANC_DATA:
454       bitCnt += 8;
455       /* check sync word */
456       if (FDKreadBits(bs, 8) == DVB_ANC_DATA_SYNC_BYTE) {
457         int dmxLevelsPresent, compressionPresent;
458         int coarseGrainTcPresent, fineGrainTcPresent;
459 
460         /* bs_info field */
461         FDKreadBits(
462             bs,
463             8); /* mpeg_audio_type, dolby_surround_mode, presentation_mode */
464         bitCnt += 8;
465 
466         /* Evaluate ancillary_data_status */
467         FDKreadBits(bs, 3); /* reserved, set to 0 */
468         dmxLevelsPresent =
469             FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
470         FDKreadBits(bs, 1);     /* reserved, set to 0 */
471         compressionPresent =
472             FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
473         coarseGrainTcPresent =
474             FDKreadBits(bs, 1); /* coarse_grain_timecode_status */
475         fineGrainTcPresent =
476             FDKreadBits(bs, 1); /* fine_grain_timecode_status */
477         bitCnt += 8;
478 
479         /* MPEG4 downmixing levels */
480         if (dmxLevelsPresent) {
481           FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
482           bitCnt += 8;
483         }
484         /* audio coding mode and compression status */
485         if (compressionPresent) {
486           FDKreadBits(bs, 16); /* audio_coding_mode, Compression_value */
487           bitCnt += 16;
488         }
489         /* coarse grain timecode */
490         if (coarseGrainTcPresent) {
491           FDKreadBits(bs, 16); /* coarse_grain_timecode */
492           bitCnt += 16;
493         }
494         /* fine grain timecode */
495         if (fineGrainTcPresent) {
496           FDKreadBits(bs, 16); /* fine_grain_timecode */
497           bitCnt += 16;
498         }
499         if (!self->dvbAncDataAvailable && ((INT)FDKgetValidBits(bs) >= 0)) {
500           self->dvbAncDataPosition = bsStartPos;
501           self->dvbAncDataAvailable = 1;
502         }
503       }
504       break;
505 
506     default:
507       break;
508   }
509 
510   return (bitCnt);
511 }
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 */
aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs,CDrcPayload * pDrcBs,UINT payloadPosition)522 static int aacDecoder_drcParse(HANDLE_FDK_BITSTREAM bs, CDrcPayload *pDrcBs,
523                                UINT payloadPosition) {
524   int i, numBands;
525 
526   /* Move to the beginning of the DRC payload field */
527   FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
528 
529   /* pce_tag_present */
530   if (FDKreadBits(bs, 1)) {
531     pDrcBs->pceInstanceTag = FDKreadBits(bs, 4); /* pce_instance_tag */
532     /* only one program supported */
533     FDKreadBits(bs, 4); /* drc_tag_reserved_bits */
534   } else {
535     pDrcBs->pceInstanceTag = -1; /* not present */
536   }
537 
538   if (FDKreadBits(bs, 1)) { /* excluded_chns_present */
539     /* get excluded_chn_mask */
540     parseExcludedChannels(&pDrcBs->excludedChnsMask, bs);
541   } else {
542     pDrcBs->excludedChnsMask = 0;
543   }
544 
545   numBands = 1;
546   if (FDKreadBits(bs, 1)) /* drc_bands_present */
547   {
548     /* get band_incr */
549     numBands += FDKreadBits(bs, 4); /* drc_band_incr */
550     pDrcBs->channelData.drcInterpolationScheme =
551         FDKreadBits(bs, 4); /* drc_interpolation_scheme */
552     /* band_top */
553     for (i = 0; i < numBands; i++) {
554       pDrcBs->channelData.bandTop[i] = FDKreadBits(bs, 8); /* drc_band_top[i] */
555     }
556   } else {
557     pDrcBs->channelData.bandTop[0] = DRC_BLOCK_LEN_DIV_BAND_MULT -
558                                      1; /* ... comprising the whole spectrum. */
559     ;
560   }
561 
562   pDrcBs->channelData.numBands = numBands;
563 
564   if (FDKreadBits(bs, 1)) /* prog_ref_level_present */
565   {
566     pDrcBs->progRefLevel = FDKreadBits(bs, 7); /* prog_ref_level */
567     FDKreadBits(bs, 1); /* prog_ref_level_reserved_bits */
568   } else {
569     pDrcBs->progRefLevel = -1;
570   }
571 
572   for (i = 0; i < numBands; i++) {
573     pDrcBs->channelData.drcValue[i] = FDKreadBits(bs, 1)
574                                       << 7; /* dyn_rng_sgn[i] */
575     pDrcBs->channelData.drcValue[i] |=
576         FDKreadBits(bs, 7) & 0x7F; /* dyn_rng_ctl[i] */
577   }
578 
579   /* Set DRC payload type */
580   pDrcBs->channelData.drcDataType = MPEG_DRC_EXT_DATA;
581 
582   return (1);
583 }
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 #define DVB_COMPRESSION_SCALE (8) /* 48,164 dB */
596 
aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,CDrcPayload * pDrcBs,UINT payloadPosition)597 static int aacDecoder_drcReadCompression(HANDLE_FDK_BITSTREAM bs,
598                                          CDrcPayload *pDrcBs,
599                                          UINT payloadPosition) {
600   int foundDrcData = 0;
601   int dmxLevelsPresent, compressionPresent;
602 
603   /* Move to the beginning of the DRC payload field */
604   FDKpushBiDirectional(bs, (INT)FDKgetValidBits(bs) - (INT)payloadPosition);
605 
606   /* Sanity checks */
607   if (FDKgetValidBits(bs) < 24) {
608     return 0;
609   }
610 
611   /* Check sync word */
612   if (FDKreadBits(bs, 8) != DVB_ANC_DATA_SYNC_BYTE) {
613     return 0;
614   }
615 
616   /* Evaluate bs_info field */
617   if (FDKreadBits(bs, 2) != 3) { /* mpeg_audio_type */
618     /* No MPEG-4 audio data */
619     return 0;
620   }
621   FDKreadBits(bs, 2);                    /* dolby_surround_mode */
622   pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */
623   FDKreadBits(bs, 1);                    /* stereo_downmix_mode */
624   if (FDKreadBits(bs, 1) != 0) {         /* reserved, set to 0 */
625     return 0;
626   }
627 
628   /* Evaluate ancillary_data_status */
629   if (FDKreadBits(bs, 3) != 0) { /* reserved, set to 0 */
630     return 0;
631   }
632   dmxLevelsPresent = FDKreadBits(bs, 1); /* downmixing_levels_MPEG4_status */
633   /*extensionPresent =*/FDKreadBits(bs,
634                                     1); /* ancillary_data_extension_status; */
635   compressionPresent =
636       FDKreadBits(bs, 1); /* audio_coding_mode_and_compression status */
637   /*coarseGrainTcPresent =*/FDKreadBits(bs,
638                                         1); /* coarse_grain_timecode_status */
639   /*fineGrainTcPresent   =*/FDKreadBits(bs, 1); /* fine_grain_timecode_status */
640 
641   if (dmxLevelsPresent) {
642     FDKreadBits(bs, 8); /* downmixing_levels_MPEG4 */
643   }
644 
645   /* audio_coding_mode_and_compression_status */
646   if (compressionPresent) {
647     UCHAR compressionOn, compressionValue;
648 
649     /* audio_coding_mode */
650     if (FDKreadBits(bs, 7) != 0) { /* The reserved bits shall be set to "0". */
651       return 0;
652     }
653     compressionOn = (UCHAR)FDKreadBits(bs, 1);    /* compression_on */
654     compressionValue = (UCHAR)FDKreadBits(bs, 8); /* Compression_value */
655 
656     if (compressionOn) {
657       /* A compression value is available so store the data just like MPEG DRC
658        * data */
659       pDrcBs->channelData.numBands = 1; /* One band ... */
660       pDrcBs->channelData.drcValue[0] =
661           compressionValue; /* ... with one value ... */
662       pDrcBs->channelData.bandTop[0] =
663           DRC_BLOCK_LEN_DIV_BAND_MULT -
664           1; /* ... comprising the whole spectrum. */
665       ;
666       pDrcBs->pceInstanceTag = -1; /* Not present */
667       pDrcBs->progRefLevel = -1;   /* Not present */
668       pDrcBs->channelData.drcDataType =
669           DVB_DRC_ANC_DATA; /* Set DRC payload type to DVB. */
670       foundDrcData = 1;
671     }
672   }
673 
674   return (foundDrcData);
675 }
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  */
aacDecoder_drcExtractAndMap(HANDLE_AAC_DRC self,HANDLE_FDK_BITSTREAM hBs,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo[],UCHAR pceInstanceTag,UCHAR channelMapping[],int validChannels)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     int validChannels) {
691   CDrcPayload threadBs[MAX_DRC_THREADS];
692   CDrcPayload *validThreadBs[MAX_DRC_THREADS];
693   CDrcParams *pParams;
694   UINT backupBsPosition;
695   int result = 0;
696   int i, thread, validThreads = 0;
697 
698   FDK_ASSERT(self != NULL);
699   FDK_ASSERT(hBs != NULL);
700   FDK_ASSERT(pAacDecoderStaticChannelInfo != NULL);
701 
702   pParams = &self->params;
703 
704   self->numThreads = 0;
705   backupBsPosition = FDKgetValidBits(hBs);
706 
707   for (i = 0; i < self->numPayloads && self->numThreads < MAX_DRC_THREADS;
708        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     FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
713     threadBs[self->numThreads].channelData.bandTop[0] =
714         DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
715 
716     /* Extract payload */
717     self->numThreads += aacDecoder_drcParse(hBs, &threadBs[self->numThreads],
718                                             self->drcPayloadPosition[i]);
719   }
720   self->numPayloads = 0;
721 
722   if (self->dvbAncDataAvailable &&
723       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     FDKmemclear(&threadBs[self->numThreads], sizeof(CDrcPayload));
730     threadBs[self->numThreads].channelData.bandTop[0] =
731         DRC_BLOCK_LEN_DIV_BAND_MULT - 1;
732 
733     /* Extract payload */
734     self->numThreads += aacDecoder_drcReadCompression(
735         hBs, &threadBs[self->numThreads], self->dvbAncDataPosition);
736   }
737   self->dvbAncDataAvailable = 0;
738 
739   /* Reset the bitbufffer */
740   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   for (thread = 0; thread < self->numThreads; thread++) {
748     CDrcPayload *pThreadBs = &threadBs[thread];
749     int numExclChns = 0;
750 
751     switch ((AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType) {
752       default:
753         continue;
754       case MPEG_DRC_EXT_DATA:
755       case DVB_DRC_ANC_DATA:
756         break;
757     }
758 
759     if (pThreadBs->pceInstanceTag >= 0) { /* if PCE tag present */
760       if (pThreadBs->pceInstanceTag != pceInstanceTag) {
761         continue; /* don't accept */
762       }
763     }
764 
765     /* calculate number of excluded channels */
766     if (pThreadBs->excludedChnsMask > 0) {
767       INT exclMask = pThreadBs->excludedChnsMask;
768       int ch;
769       for (ch = 0; ch < validChannels; ch++) {
770         numExclChns += exclMask & 0x1;
771         exclMask >>= 1;
772       }
773     }
774     if (numExclChns < validChannels) {
775       validThreadBs[validThreads] = pThreadBs;
776       validThreads++;
777     }
778   }
779 
780   /* map DRC bitstream information onto DRC channel information */
781   for (thread = 0; thread < validThreads; thread++) {
782     CDrcPayload *pThreadBs = validThreadBs[thread];
783     INT exclMask = pThreadBs->excludedChnsMask;
784     AACDEC_DRC_PAYLOAD_TYPE drcPayloadType =
785         (AACDEC_DRC_PAYLOAD_TYPE)pThreadBs->channelData.drcDataType;
786     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     if (pThreadBs->progRefLevel >= 0) {
792       self->progRefLevel = pThreadBs->progRefLevel;
793       self->progRefLevelPresent = 1;
794       self->prlExpiryCount = 0; /* Got a new value -> Reset counter */
795     }
796 
797     if (drcPayloadType == DVB_DRC_ANC_DATA) {
798       /* Announce the presentation mode of this valid thread. */
799       self->presMode = pThreadBs->presMode;
800     }
801 
802     /* SCE, CPE and LFE */
803     for (ch = 0; ch < validChannels; ch++) {
804       AACDEC_DRC_PAYLOAD_TYPE prvPayloadType = UNKNOWN_PAYLOAD;
805       int mapedChannel = channelMapping[ch];
806 
807       if ((mapedChannel >= validChannels) ||
808           ((exclMask & (1 << mapedChannel)) != 0))
809         continue;
810 
811       if ((pParams->expiryFrame <= 0) ||
812           (pAacDecoderStaticChannelInfo[ch]->drcData.expiryCount <
813            pParams->expiryFrame)) {
814         prvPayloadType =
815             (AACDEC_DRC_PAYLOAD_TYPE)pAacDecoderStaticChannelInfo[ch]
816                 ->drcData.drcDataType;
817       }
818       if (((drcPayloadType == MPEG_DRC_EXT_DATA) &&
819            (prvPayloadType != DVB_DRC_ANC_DATA)) ||
820           ((drcPayloadType == DVB_DRC_ANC_DATA) &&
821            (pParams->applyHeavyCompression ==
822             ON))) { /* copy thread to channel */
823         pAacDecoderStaticChannelInfo[ch]->drcData = pThreadBs->channelData;
824         result = 1;
825       }
826     }
827     /* CCEs not supported by now */
828   }
829 
830   /* Increment and check expiry counter for the program reference level: */
831   if ((pParams->expiryFrame > 0) &&
832       (self->prlExpiryCount++ >
833        pParams->expiryFrame)) { /* The program reference level is too old, so
834                                    set it back to the target level. */
835     self->progRefLevelPresent = 0;
836     self->progRefLevel = pParams->targetRefLevel;
837     self->prlExpiryCount = 0;
838   }
839 
840   return result;
841 }
842 
aacDecoder_drcApply(HANDLE_AAC_DRC self,void * pSbrDec,CAacDecoderChannelInfo * pAacDecoderChannelInfo,CDrcChannelData * pDrcChData,FIXP_DBL * extGain,int ch,int aacFrameSize,int bSbrPresent)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                          int aacFrameSize, int bSbrPresent) {
848   int band, bin, numBands;
849   int bottom = 0;
850   int modifyBins = 0;
851 
852   FIXP_DBL max_mantissa;
853   INT max_exponent;
854 
855   FIXP_DBL norm_mantissa = FL2FXCONST_DBL(0.5f);
856   INT norm_exponent = 1;
857 
858   FIXP_DBL fact_mantissa[MAX_DRC_BANDS];
859   INT fact_exponent[MAX_DRC_BANDS];
860 
861   CDrcParams *pParams = &self->params;
862 
863   FIXP_DBL *pSpectralCoefficient =
864       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
865   CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
866   SHORT *pSpecScale = pAacDecoderChannelInfo->specScale;
867 
868   int winSeq = pIcsInfo->WindowSequence;
869 
870   /* Increment and check expiry counter */
871   if ((pParams->expiryFrame > 0) &&
872       (++pDrcChData->expiryCount >
873        pParams->expiryFrame)) { /* The DRC data is too old, so delete it. */
874     aacDecoder_drcInitChannelData(pDrcChData);
875   }
876 
877   if (self->enable != ON) {
878     sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch);
879     if (extGain != NULL) {
880       INT gainScale = (INT)*extGain;
881       /* The gain scaling must be passed to the function in the buffer pointed
882        * on by extGain. */
883       if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
884         *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
885       } else {
886         FDK_ASSERT(0);
887       }
888     }
889     return;
890   }
891 
892   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   if (pParams->targetRefLevel >= 0) {
902     /* 0.5^((targetRefLevel - progRefLevel)/24) */
903     norm_mantissa =
904         fLdPow(FL2FXCONST_DBL(-1.0), /* log2(0.5) */
905                0,
906                (FIXP_DBL)((INT)(FL2FXCONST_DBL(1.0f / 24.0) >> 3) *
907                           (INT)(pParams->targetRefLevel - self->progRefLevel)),
908                3, &norm_exponent);
909   }
910   /* Always export the normalization gain (if possible). */
911   if (extGain != NULL) {
912     INT gainScale = (INT)*extGain;
913     /* The gain scaling must be passed to the function in the buffer pointed on
914      * by extGain. */
915     if (gainScale >= 0 && gainScale <= DFRACT_BITS) {
916       *extGain = scaleValue(norm_mantissa, norm_exponent - gainScale);
917     } else {
918       FDK_ASSERT(0);
919     }
920   }
921   /* Reset normalization gain since this module must not apply it */
922   norm_mantissa = FL2FXCONST_DBL(0.5f);
923   norm_exponent = 1;
924 
925   /* calc scale factors */
926   for (band = 0; band < numBands; band++) {
927     UCHAR drcVal = pDrcChData->drcValue[band];
928 
929     fact_mantissa[band] = FL2FXCONST_DBL(0.5f);
930     fact_exponent[band] = 1;
931 
932     if ((pParams->applyHeavyCompression == ON) &&
933         ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
934          DVB_DRC_ANC_DATA)) {
935       INT compressionFactorVal_e;
936       int valX, valY;
937 
938       valX = drcVal >> 4;
939       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       if (drcVal != 0x7F) {
945         fact_mantissa[band] = fPowInt(
946             FL2FXCONST_DBL(0.95483867181), /* -0.4014dB = 0.95483867181 */
947             0, valY, &compressionFactorVal_e);
948 
949         /* -0.0008dB (48.164 - 6.0206*8 = -0.0008) */
950         fact_mantissa[band] =
951             fMult(FL2FXCONST_DBL(0.99990790084), fact_mantissa[band]);
952 
953         fact_exponent[band] =
954             DVB_COMPRESSION_SCALE - valX + compressionFactorVal_e;
955       }
956     } else if ((AACDEC_DRC_PAYLOAD_TYPE)pDrcChData->drcDataType ==
957                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       if ((drcVal & 0x7F) > 0) {
969         FIXP_DBL tParamVal = (drcVal & 0x80) ? -pParams->cut : pParams->boost;
970 
971         fact_mantissa[band] = f2Pow(
972             (FIXP_DBL)((INT)fMult(FL2FXCONST_DBL(1.0f / 192.0f), tParamVal) *
973                        (drcVal & 0x7F)),
974             3 + DRC_PARAM_SCALE, &fact_exponent[band]);
975       }
976     }
977 
978     fact_mantissa[band] = fMult(fact_mantissa[band], norm_mantissa);
979     fact_exponent[band] += norm_exponent;
980 
981   } /* end loop over bands */
982 
983   /* normalizations */
984   {
985     int res;
986 
987     max_mantissa = FL2FXCONST_DBL(0.0f);
988     max_exponent = 0;
989     for (band = 0; band < numBands; band++) {
990       max_mantissa = fixMax(max_mantissa, fact_mantissa[band]);
991       max_exponent = fixMax(max_exponent, fact_exponent[band]);
992     }
993 
994     /* left shift factors to gain accurancy */
995     res = CntLeadingZeros(max_mantissa) - 1;
996 
997     /* above topmost DRC band gain factor is 1 */
998     if (((pDrcChData->bandTop[fMax(0, numBands - 1)] + 1) << 2) < aacFrameSize)
999       res = 0;
1000 
1001     if (res > 0) {
1002       res = fixMin(res, max_exponent);
1003       max_exponent -= res;
1004 
1005       for (band = 0; band < numBands; band++) {
1006         fact_mantissa[band] <<= res;
1007         fact_exponent[band] -= res;
1008       }
1009     }
1010 
1011     /* normalize magnitudes to one scale factor */
1012     for (band = 0; band < numBands; band++) {
1013       if (fact_exponent[band] < max_exponent) {
1014         fact_mantissa[band] >>= max_exponent - fact_exponent[band];
1015       }
1016       if (fact_mantissa[band] != FL2FXCONST_DBL(0.5f)) {
1017         modifyBins = 1;
1018       }
1019     }
1020     if (max_exponent != 1) {
1021       modifyBins = 1;
1022     }
1023   }
1024 
1025   /*  apply factor to spectral lines
1026    *  short blocks must take care that bands fall on
1027    *  block boundaries!
1028    */
1029   if (!bSbrPresent) {
1030     bottom = 0;
1031 
1032     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       max_exponent -= 1;
1037     } else {
1038       for (band = 0; band < numBands; band++) {
1039         int top = fixMin((int)((pDrcChData->bandTop[band] + 1) << 2),
1040                          aacFrameSize); /* ... * DRC_BAND_MULT; */
1041 
1042         for (bin = bottom; bin < top; bin++) {
1043           pSpectralCoefficient[bin] =
1044               fMult(pSpectralCoefficient[bin], fact_mantissa[band]);
1045         }
1046 
1047         bottom = top;
1048       }
1049     }
1050 
1051     /* above topmost DRC band gain factor is 1 */
1052     if (max_exponent > 0) {
1053       for (bin = bottom; bin < aacFrameSize; bin += 1) {
1054         pSpectralCoefficient[bin] >>= max_exponent;
1055       }
1056     }
1057 
1058     /* adjust scaling */
1059     pSpecScale[0] += max_exponent;
1060 
1061     if (winSeq == BLOCK_SHORT) {
1062       int win;
1063       for (win = 1; win < 8; win++) {
1064         pSpecScale[win] += max_exponent;
1065       }
1066     }
1067   } else {
1068     HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec;
1069     numBands = pDrcChData->numBands;
1070 
1071     /* feed factors into SBR decoder for application in QMF domain. */
1072     sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa,
1073                               max_exponent, pDrcChData->drcInterpolationScheme,
1074                               winSeq, pDrcChData->bandTop);
1075   }
1076 
1077   return;
1078 }
1079 
1080 /*
1081  * DRC parameter and presentation mode handling
1082  */
aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,INT aacNumChannels,SCHAR prevDrcProgRefLevel,SCHAR prevDrcPresMode)1083 static void aacDecoder_drcParameterHandling(HANDLE_AAC_DRC self,
1084                                             INT aacNumChannels,
1085                                             SCHAR prevDrcProgRefLevel,
1086                                             SCHAR prevDrcPresMode) {
1087   int isDownmix, isMonoDownmix, isStereoDownmix;
1088   int dDmx, dHr;
1089   AACDEC_DRC_PARAMETER_HANDLING drcParameterHandling;
1090   CDrcParams *p;
1091 
1092   FDK_ASSERT(self != NULL);
1093 
1094   p = &self->params;
1095 
1096   if (self->progRefLevel != prevDrcProgRefLevel) self->update = 1;
1097 
1098   if (self->presMode != prevDrcPresMode) self->update = 1;
1099 
1100   if (self->prevAacNumChannels != aacNumChannels) self->update = 1;
1101 
1102   /* return if no relevant parameter has changed */
1103   if (!self->update) {
1104     return;
1105   }
1106 
1107   /* derive downmix property. aacNumChannels: number of channels in aac stream,
1108    * numOutChannels: number of output channels */
1109   isDownmix = (aacNumChannels > self->numOutChannels);
1110   isDownmix = (isDownmix && (self->numOutChannels > 0));
1111   isMonoDownmix = (isDownmix && (self->numOutChannels == 1));
1112   isStereoDownmix = (isDownmix && (self->numOutChannels == 2));
1113 
1114   if ((self->presMode == 1) || (self->presMode == 2)) {
1115     drcParameterHandling = (AACDEC_DRC_PARAMETER_HANDLING)self->presMode;
1116   } else { /* no presentation mode -> use parameter handling specified by
1117               AAC_DRC_DEFAULT_PRESENTATION_MODE */
1118     drcParameterHandling = p->defaultPresentationMode;
1119   }
1120 
1121   /* by default, do as desired */
1122   p->cut = p->usrCut;
1123   p->boost = p->usrBoost;
1124   p->applyHeavyCompression = p->usrApplyHeavyCompression;
1125 
1126   switch (drcParameterHandling) {
1127     case DISABLED_PARAMETER_HANDLING:
1128     default:
1129       /* use drc parameters as requested */
1130       break;
1131 
1132     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       if (isDownmix) {
1136         FIXP_DBL dmxTmp;
1137         int e_log, e_mult;
1138         dmxTmp = fDivNorm(self->numOutChannels,
1139                           aacNumChannels); /* inverse division ->
1140                                               negative sign after
1141                                               logarithm */
1142         dmxTmp = fLog2(dmxTmp, 0, &e_log);
1143         dmxTmp = fMultNorm(
1144             dmxTmp, FL2FXCONST_DBL(4.0f * 20.0f * 0.30103f / (float)(1 << 5)),
1145             &e_mult); /* e = e_log + e_mult + 5 */
1146         dDmx = (int)scaleValue(dmxTmp, e_log + e_mult + 5 - (DFRACT_BITS - 1));
1147       } else {
1148         dDmx = 0;
1149       }
1150 
1151       /* dHr: Full estimated (decoder) headroom reduction due to loudness
1152        * normalisation (DTL - PRL) and downmix. Format: -1/4*dB */
1153       if (p->targetRefLevel >= 0) { /* if target level is provided */
1154         dHr = p->targetRefLevel + dDmx - self->progRefLevel;
1155       } else {
1156         dHr = dDmx;
1157       }
1158 
1159       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         int eHr = fixMin(p->encoderTargetLevel - self->progRefLevel, 0);
1163         if (eHr <
1164             dHr) { /* if encoder provides more headroom than decoder needs */
1165           /* derive scaling of light DRC */
1166           FIXP_DBL calcFactor_norm;
1167           INT calcFactor; /* fraction of DRC gains that is minimally needed for
1168                              clipping prevention */
1169           calcFactor_norm =
1170               fDivNorm(-dHr, -eHr); /* 0.0 < calcFactor_norm < 1.0 */
1171           calcFactor_norm = calcFactor_norm >> DRC_PARAM_SCALE;
1172           /* quantize to 128 steps */
1173           calcFactor = convert_drcParam(
1174               calcFactor_norm); /* convert to integer value between 0 and 127 */
1175           calcFactor_norm = (FIXP_DBL)(
1176               (INT)(DRC_PARAM_QUANT_STEP >> DRC_PARAM_SCALE) * calcFactor);
1177           p->cut = (calcFactor_norm > p->cut)
1178                        ? calcFactor_norm
1179                        : p->cut; /* use calcFactor_norm as lower limit */
1180         } 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           p->cut = DRC_SCALING_MAX;
1185           if ((dHr - eHr) <=
1186               -4 * DRC_HEAVY_THRESHOLD_DB) { /* use heavy compression if
1187                                                 headroom deficit is equal or
1188                                                 higher than
1189                                                 DRC_HEAVY_THRESHOLD_DB */
1190             p->applyHeavyCompression = ON;
1191           }
1192         }
1193       } else { /* dHr >= 0 */
1194         /* no restrictions required, as headroom is not reduced. */
1195         /* p->cut = p->usrCut; */
1196       }
1197       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     case DRC_PRESENTATION_MODE_1: /* presentation mode 1, Light:-31/Heavy:-23 */
1210       if ((p->targetRefLevel >= 0) &&
1211           (p->targetRefLevel <
1212            124)) { /* if target level is provided and > -31 dB */
1213         /* playback up to -23 dB */
1214         p->applyHeavyCompression = ON;
1215       } else { /* target level <= -31 dB or not provided */
1216         /* playback -31 dB */
1217         if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
1218           p->cut = DRC_SCALING_MAX;
1219         }
1220       }
1221       break;
1222 
1223     case DRC_PRESENTATION_MODE_2: /* presentation mode 2, Light:-23/Heavy:-23 */
1224       if ((p->targetRefLevel >= 0) &&
1225           (p->targetRefLevel <
1226            124)) { /* if target level is provided and > -31 dB */
1227         /* playback up to -23 dB */
1228         if (isMonoDownmix) { /* if mono downmix */
1229           p->applyHeavyCompression = ON;
1230         } else {
1231           p->applyHeavyCompression = OFF;
1232           p->cut = DRC_SCALING_MAX;
1233         }
1234       } else { /* target level <= -31 dB or not provided */
1235         /* playback -31 dB */
1236         p->applyHeavyCompression = OFF;
1237         if (isMonoDownmix || isStereoDownmix) { /* stereo or mono downmixing */
1238           p->cut = DRC_SCALING_MAX;
1239         }
1240       }
1241       break;
1242   } /*  switch (drcParameterHandling) */
1243 
1244   /* With heavy compression, there is no scaling.
1245      Scaling factors are set for notification only. */
1246   if (p->applyHeavyCompression == ON) {
1247     p->boost = DRC_SCALING_MAX;
1248     p->cut = DRC_SCALING_MAX;
1249   }
1250 
1251   /* switch on/off processing */
1252   self->enable = ((p->boost > (FIXP_DBL)0) || (p->cut > (FIXP_DBL)0) ||
1253                   (p->applyHeavyCompression == ON) || (p->targetRefLevel >= 0));
1254 
1255   self->prevAacNumChannels = aacNumChannels;
1256   self->update = 0;
1257 }
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  */
aacDecoder_drcProlog(HANDLE_AAC_DRC self,HANDLE_FDK_BITSTREAM hBs,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo[],UCHAR pceInstanceTag,UCHAR channelMapping[],int validChannels)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     int validChannels) {
1273   int result = 0;
1274 
1275   if (self == NULL) {
1276     return -1;
1277   }
1278 
1279   if (!self->params.bsDelayEnable) {
1280     /* keep previous progRefLevel and presMode for update flag in
1281      * drcParameterHandling */
1282     INT prevPRL, prevPM = 0;
1283     prevPRL = self->progRefLevel;
1284     prevPM = self->presMode;
1285 
1286     result = aacDecoder_drcExtractAndMap(
1287         self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1288         validChannels);
1289 
1290     if (result < 0) {
1291       return result;
1292     }
1293 
1294     /* Drc parameter handling */
1295     aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1296   }
1297 
1298   return result;
1299 }
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  */
aacDecoder_drcEpilog(HANDLE_AAC_DRC self,HANDLE_FDK_BITSTREAM hBs,CAacDecoderStaticChannelInfo * pAacDecoderStaticChannelInfo[],UCHAR pceInstanceTag,UCHAR channelMapping[],int validChannels)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     int validChannels) {
1315   int result = 0;
1316 
1317   if (self == NULL) {
1318     return -1;
1319   }
1320 
1321   if (self->params.bsDelayEnable) {
1322     /* keep previous progRefLevel and presMode for update flag in
1323      * drcParameterHandling */
1324     INT prevPRL, prevPM = 0;
1325     prevPRL = self->progRefLevel;
1326     prevPM = self->presMode;
1327 
1328     result = aacDecoder_drcExtractAndMap(
1329         self, hBs, pAacDecoderStaticChannelInfo, pceInstanceTag, channelMapping,
1330         validChannels);
1331 
1332     if (result < 0) {
1333       return result;
1334     }
1335 
1336     /* Drc parameter handling */
1337     aacDecoder_drcParameterHandling(self, validChannels, prevPRL, prevPM);
1338   }
1339 
1340   return result;
1341 }
1342 
1343 /*
1344  * Export relevant metadata info from bitstream payload.
1345  */
aacDecoder_drcGetInfo(HANDLE_AAC_DRC self,SCHAR * pPresMode,SCHAR * pProgRefLevel)1346 void aacDecoder_drcGetInfo(HANDLE_AAC_DRC self, SCHAR *pPresMode,
1347                            SCHAR *pProgRefLevel) {
1348   if (self != NULL) {
1349     if (pPresMode != NULL) {
1350       *pPresMode = self->presMode;
1351     }
1352     if (pProgRefLevel != NULL) {
1353       if (self->progRefLevelPresent) {
1354         *pProgRefLevel = self->progRefLevel;
1355       } else {
1356         *pProgRefLevel = -1;
1357       }
1358     }
1359   }
1360 }
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  */
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)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                                const UINT stride, const UINT limiterEnabled) {
1402   UINT i;
1403   INT additionalGain_scaling;
1404   FIXP_DBL additionalGain;
1405 
1406   FDK_ASSERT(gain_delay <= nSamples);
1407 
1408   FIXP_DBL additionalGainSmoothState = hDrcInfo->additionalGainFilterState;
1409   FIXP_DBL additionalGainSmoothState1 = hDrcInfo->additionalGainFilterState1;
1410 
1411   if (!gain_delay) {
1412     additionalGain = pGain[0];
1413 
1414     /* Apply the additional scaling gain_scale[0] that has no delay and no
1415      * smoothing */
1416     additionalGain_scaling =
1417         fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
1418     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     additionalGain_scaling -= gain_scale;
1423 
1424     if (additionalGain_scaling) {
1425       scaleValuesSaturate(samplesIn, channels * nSamples,
1426                           -additionalGain_scaling);
1427     }
1428 
1429     if (limiterEnabled) {
1430       FDK_ASSERT(pGainPerSample != NULL);
1431 
1432       for (i = 0; i < nSamples; i++) {
1433         pGainPerSample[i] = additionalGain;
1434       }
1435     } else {
1436       for (i = 0; i < channels * nSamples; i++) {
1437         samplesIn[i] = FIXP_DBL2PCM_DEC(fMult(samplesIn[i], additionalGain));
1438       }
1439     }
1440   } else {
1441     UINT inc;
1442     FIXP_DBL additionalGainUnfiltered;
1443 
1444     inc = (stride == 1) ? channels : 1;
1445 
1446     for (i = 0; i < nSamples; i++) {
1447       if (i < gain_delay) {
1448         additionalGainUnfiltered = hDrcInfo->additionalGainPrev;
1449       } else {
1450         additionalGainUnfiltered = pGain[0];
1451       }
1452 
1453       /* Smooth additionalGain */
1454 
1455       /* [b,a] = butter(1, 0.01) */
1456       static const FIXP_SGL b[] = {FL2FXCONST_SGL(0.015466 * 2.0),
1457                                    FL2FXCONST_SGL(0.015466 * 2.0)};
1458       static const FIXP_SGL a[] = {(FIXP_SGL)MAXVAL_SGL,
1459                                    FL2FXCONST_SGL(-0.96907)};
1460 
1461       additionalGain = -fMult(additionalGainSmoothState, a[1]) +
1462                        fMultDiv2(additionalGainUnfiltered, b[0]) +
1463                        fMultDiv2(additionalGainSmoothState1, b[1]);
1464       additionalGainSmoothState1 = additionalGainUnfiltered;
1465       additionalGainSmoothState = additionalGain;
1466 
1467       /* Apply the additional scaling gain_scale[0] that has no delay and no
1468        * smoothing */
1469       additionalGain_scaling =
1470           fMin(gain_scale, CntLeadingZeros(additionalGain) - 1);
1471       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       additionalGain_scaling -= gain_scale;
1476 
1477       if (limiterEnabled) {
1478         FDK_ASSERT(stride == 1);
1479         FDK_ASSERT(pGainPerSample != NULL);
1480 
1481         if (additionalGain_scaling) {
1482           scaleValuesSaturate(samplesIn, channels, -additionalGain_scaling);
1483         }
1484 
1485         pGainPerSample[i] = additionalGain;
1486       } else {
1487         if (additionalGain_scaling) {
1488           for (UINT k = 0; k < channels; k++) {
1489             scaleValuesSaturate(&samplesIn[k * stride], 1,
1490                                 -additionalGain_scaling);
1491           }
1492         }
1493 
1494         for (UINT k = 0; k < channels; k++) {
1495           samplesIn[k * stride] =
1496               FIXP_DBL2PCM_DEC(fMult(samplesIn[k * stride], additionalGain));
1497         }
1498       }
1499 
1500       samplesIn += inc;
1501     }
1502   }
1503 
1504   hDrcInfo->additionalGainPrev = pGain[0];
1505   hDrcInfo->additionalGainFilterState = additionalGainSmoothState;
1506   hDrcInfo->additionalGainFilterState1 = additionalGainSmoothState1;
1507 
1508   return (AACDEC_DRC_GAIN_SCALING);
1509 }
1510