• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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