1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 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 encoder library ******************************
96 
97    Author(s):   M. Neusinger
98 
99    Description: Compressor for AAC Metadata Generator
100 
101 *******************************************************************************/
102 
103 #include "metadata_compressor.h"
104 #include "channel_map.h"
105 
106 #define LOG2 0.69314718056f /* natural logarithm of 2 */
107 #define ILOG2 1.442695041f  /* 1/LOG2 */
108 #define FIXP_ILOG2_DIV2 (FL2FXCONST_DBL(ILOG2 / 2))
109 
110 /*----------------- defines ----------------------*/
111 
112 #define MAX_DRC_CHANNELS (8)       /*!< Max number of audio input channels. */
113 #define DOWNMIX_SHIFT (3)          /*!< Max 8 channel. */
114 #define WEIGHTING_FILTER_SHIFT (2) /*!< Scaling used in weighting filter. */
115 
116 #define METADATA_INT_BITS 10
117 #define METADATA_LINT_BITS 20
118 #define METADATA_INT_SCALE (INT64(1) << (METADATA_INT_BITS))
119 #define METADATA_FRACT_BITS (DFRACT_BITS - 1 - METADATA_INT_BITS)
120 #define METADATA_FRACT_SCALE (INT64(1) << (METADATA_FRACT_BITS))
121 
122 /**
123  *  Enum for channel assignment.
124  */
125 enum { L = 0, R = 1, C = 2, LFE = 3, LS = 4, RS = 5, S = 6, LS2 = 7, RS2 = 8 };
126 
127 /*--------------- structure definitions --------------------*/
128 
129 /**
130  *  Structure holds weighting filter filter states.
131  */
132 struct WEIGHTING_STATES {
133   FIXP_DBL x1;
134   FIXP_DBL x2;
135   FIXP_DBL y1;
136   FIXP_DBL y2;
137 };
138 
139 /**
140  *  Dynamic Range Control compressor structure.
141  */
142 struct DRC_COMP {
143   FIXP_DBL maxBoostThr[2]; /*!< Max boost threshold. */
144   FIXP_DBL boostThr[2];    /*!< Boost threshold. */
145   FIXP_DBL earlyCutThr[2]; /*!< Early cut threshold. */
146   FIXP_DBL cutThr[2];      /*!< Cut threshold. */
147   FIXP_DBL maxCutThr[2];   /*!< Max cut threshold. */
148 
149   FIXP_DBL boostFac[2]; /*!< Precalculated factor for boost compression. */
150   FIXP_DBL
151   earlyCutFac[2];     /*!< Precalculated factor for early cut compression. */
152   FIXP_DBL cutFac[2]; /*!< Precalculated factor for cut compression. */
153 
154   FIXP_DBL maxBoost[2];    /*!< Maximum boost. */
155   FIXP_DBL maxCut[2];      /*!< Maximum cut. */
156   FIXP_DBL maxEarlyCut[2]; /*!< Maximum early cut. */
157 
158   FIXP_DBL fastAttack[2]; /*!< Fast attack coefficient. */
159   FIXP_DBL fastDecay[2];  /*!< Fast release coefficient. */
160   FIXP_DBL slowAttack[2]; /*!< Slow attack coefficient. */
161   FIXP_DBL slowDecay[2];  /*!< Slow release coefficient. */
162   UINT holdOff[2];        /*!< Hold time in blocks. */
163 
164   FIXP_DBL attackThr[2]; /*!< Slow/fast attack threshold. */
165   FIXP_DBL decayThr[2];  /*!< Slow/fast release threshold. */
166 
167   DRC_PROFILE profile[2];  /*!< DRC profile. */
168   INT blockLength;         /*!< Block length in samples. */
169   UINT sampleRate;         /*!< Sample rate. */
170   CHANNEL_MODE chanConfig; /*!< Channel configuration. */
171 
172   UCHAR useWeighting; /*!< Use weighting filter. */
173 
174   UINT channels;     /*!< Number of channels. */
175   UINT fullChannels; /*!< Number of full range channels. */
176   INT channelIdx[9]; /*!< Offsets of interleaved channel samples (L, R, C, LFE,
177                         Ls, Rs, S, Ls2, Rs2). */
178 
179   FIXP_DBL smoothLevel[2]; /*!< level smoothing states */
180   FIXP_DBL smoothGain[2];  /*!< gain smoothing states */
181   UINT holdCnt[2];         /*!< hold counter */
182 
183   FIXP_DBL limGain[2];  /*!< limiter gain */
184   FIXP_DBL limDecay;    /*!< limiter decay (linear) */
185   FIXP_DBL prevPeak[2]; /*!< max peak of previous block (stereo/mono)*/
186 
187   WEIGHTING_STATES
188   filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
189 };
190 
191 /*---------------- constants -----------------------*/
192 
193 /**
194  *  Profile tables.
195  */
196 static const FIXP_DBL tabMaxBoostThr[] = {
197     (FIXP_DBL)(-(43 << METADATA_FRACT_BITS)),
198     (FIXP_DBL)(-(53 << METADATA_FRACT_BITS)),
199     (FIXP_DBL)(-(55 << METADATA_FRACT_BITS)),
200     (FIXP_DBL)(-(65 << METADATA_FRACT_BITS)),
201     (FIXP_DBL)(-(50 << METADATA_FRACT_BITS)),
202     (FIXP_DBL)(-(40 << METADATA_FRACT_BITS))};
203 static const FIXP_DBL tabBoostThr[] = {
204     (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
205     (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
206     (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
207     (FIXP_DBL)(-(41 << METADATA_FRACT_BITS)),
208     (FIXP_DBL)(-(31 << METADATA_FRACT_BITS)),
209     (FIXP_DBL)(-(31 << METADATA_FRACT_BITS))};
210 static const FIXP_DBL tabEarlyCutThr[] = {
211     (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
212     (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
213     (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
214     (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
215     (FIXP_DBL)(-(26 << METADATA_FRACT_BITS)),
216     (FIXP_DBL)(-(20 << METADATA_FRACT_BITS))};
217 static const FIXP_DBL tabCutThr[] = {(FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
218                                      (FIXP_DBL)(-(11 << METADATA_FRACT_BITS)),
219                                      (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
220                                      (FIXP_DBL)(-(21 << METADATA_FRACT_BITS)),
221                                      (FIXP_DBL)(-(16 << METADATA_FRACT_BITS)),
222                                      (FIXP_DBL)(-(10 << METADATA_FRACT_BITS))};
223 static const FIXP_DBL tabMaxCutThr[] = {
224     (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
225     (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(9 << METADATA_FRACT_BITS),
226     (FIXP_DBL)(4 << METADATA_FRACT_BITS), (FIXP_DBL)(4 << METADATA_FRACT_BITS)};
227 static const FIXP_DBL tabBoostRatio[] = {
228     FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
229     FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
230     FL2FXCONST_DBL(((1.f / 5.f) - 1.f)), FL2FXCONST_DBL(((1.f / 5.f) - 1.f))};
231 static const FIXP_DBL tabEarlyCutRatio[] = {
232     FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
233     FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 1.f) - 1.f)),
234     FL2FXCONST_DBL(((1.f / 2.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f))};
235 static const FIXP_DBL tabCutRatio[] = {
236     FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f)),
237     FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 2.f) - 1.f)),
238     FL2FXCONST_DBL(((1.f / 20.f) - 1.f)), FL2FXCONST_DBL(((1.f / 20.f) - 1.f))};
239 static const FIXP_DBL tabMaxBoost[] = {(FIXP_DBL)(6 << METADATA_FRACT_BITS),
240                                        (FIXP_DBL)(6 << METADATA_FRACT_BITS),
241                                        (FIXP_DBL)(12 << METADATA_FRACT_BITS),
242                                        (FIXP_DBL)(12 << METADATA_FRACT_BITS),
243                                        (FIXP_DBL)(15 << METADATA_FRACT_BITS),
244                                        (FIXP_DBL)(15 << METADATA_FRACT_BITS)};
245 static const FIXP_DBL tabMaxCut[] = {(FIXP_DBL)(24 << METADATA_FRACT_BITS),
246                                      (FIXP_DBL)(24 << METADATA_FRACT_BITS),
247                                      (FIXP_DBL)(24 << METADATA_FRACT_BITS),
248                                      (FIXP_DBL)(15 << METADATA_FRACT_BITS),
249                                      (FIXP_DBL)(24 << METADATA_FRACT_BITS),
250                                      (FIXP_DBL)(24 << METADATA_FRACT_BITS)};
251 static const FIXP_DBL tabFastAttack[] = {
252     FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
253     FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
254     FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
255     FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
256     FL2FXCONST_DBL((10.f / 1000.f) / METADATA_INT_SCALE),
257     FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
258 static const FIXP_DBL tabFastDecay[] = {
259     FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
260     FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
261     FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
262     FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
263     FL2FXCONST_DBL((200.f / 1000.f) / METADATA_INT_SCALE),
264     FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
265 static const FIXP_DBL tabSlowAttack[] = {
266     FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
267     FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
268     FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
269     FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
270     FL2FXCONST_DBL((100.f / 1000.f) / METADATA_INT_SCALE),
271     FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
272 static const FIXP_DBL tabSlowDecay[] = {
273     FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
274     FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
275     FL2FXCONST_DBL((10000.f / 1000.f) / METADATA_INT_SCALE),
276     FL2FXCONST_DBL((3000.f / 1000.f) / METADATA_INT_SCALE),
277     FL2FXCONST_DBL((1000.f / 1000.f) / METADATA_INT_SCALE),
278     FL2FXCONST_DBL((0.f / 1000.f) / METADATA_INT_SCALE)};
279 
280 static const INT tabHoldOff[] = {10, 10, 10, 10, 10, 0};
281 
282 static const FIXP_DBL tabAttackThr[] = {(FIXP_DBL)(15 << METADATA_FRACT_BITS),
283                                         (FIXP_DBL)(15 << METADATA_FRACT_BITS),
284                                         (FIXP_DBL)(15 << METADATA_FRACT_BITS),
285                                         (FIXP_DBL)(15 << METADATA_FRACT_BITS),
286                                         (FIXP_DBL)(10 << METADATA_FRACT_BITS),
287                                         (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
288 static const FIXP_DBL tabDecayThr[] = {(FIXP_DBL)(20 << METADATA_FRACT_BITS),
289                                        (FIXP_DBL)(20 << METADATA_FRACT_BITS),
290                                        (FIXP_DBL)(20 << METADATA_FRACT_BITS),
291                                        (FIXP_DBL)(20 << METADATA_FRACT_BITS),
292                                        (FIXP_DBL)(10 << METADATA_FRACT_BITS),
293                                        (FIXP_DBL)(0 << METADATA_FRACT_BITS)};
294 
295 /**
296  *  Weighting filter coefficients (biquad bandpass).
297  */
298 static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f); /* b1 = 0, b2 = -b0 */
299 static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f),
300                       a2 = FL2FXCONST_DBL(-0.02248836f); /* a0 = 1 */
301 
302 /*------------- function definitions ----------------*/
303 
304 /**
305  * \brief  Calculate scaling factor for denoted processing block.
306  *
307  * \param blockLength   Length of processing block.
308  *
309  * \return    shiftFactor
310  */
getShiftFactor(const UINT length)311 static UINT getShiftFactor(const UINT length) {
312   UINT ldN;
313   for (ldN = 1; (((UINT)1) << ldN) < length; ldN++)
314     ;
315 
316   return ldN;
317 }
318 
319 /**
320  * \brief  Sum up fixpoint values with best possible accuracy.
321  *
322  * \param value1        First input value.
323  * \param q1            Scaling factor of first input value.
324  * \param pValue2       Pointer to second input value, will be modified on
325  * return.
326  * \param pQ2           Pointer to second scaling factor, will be modified on
327  * return.
328  *
329  * \return    void
330  */
fixpAdd(const FIXP_DBL value1,const int q1,FIXP_DBL * const pValue2,int * const pQ2)331 static void fixpAdd(const FIXP_DBL value1, const int q1,
332                     FIXP_DBL* const pValue2, int* const pQ2) {
333   const int headroom1 = fNormz(fixp_abs(value1)) - 1;
334   const int headroom2 = fNormz(fixp_abs(*pValue2)) - 1;
335   int resultScale = fixMax(q1 - headroom1, (*pQ2) - headroom2);
336 
337   if ((value1 != FL2FXCONST_DBL(0.f)) && (*pValue2 != FL2FXCONST_DBL(0.f))) {
338     resultScale++;
339   }
340 
341   *pValue2 = scaleValue(value1, q1 - resultScale) +
342              scaleValue(*pValue2, (*pQ2) - resultScale);
343   *pQ2 = (*pValue2 != (FIXP_DBL)0) ? resultScale : DFRACT_BITS - 1;
344 }
345 
346 /**
347  * \brief  Function for converting time constant to filter coefficient.
348  *
349  * \param t             Time constant.
350  * \param sampleRate    Sampling rate in Hz.
351  * \param blockLength   Length of processing block in samples per channel.
352  *
353  * \return    result = 1.0 - exp(-1.0/((t) * (f)))
354  */
tc2Coeff(const FIXP_DBL t,const INT sampleRate,const INT blockLength)355 static FIXP_DBL tc2Coeff(const FIXP_DBL t, const INT sampleRate,
356                          const INT blockLength) {
357   FIXP_DBL sampleRateFract;
358   FIXP_DBL blockLengthFract;
359   FIXP_DBL f, product;
360   FIXP_DBL exponent, result;
361   INT e_res;
362 
363   /* f = sampleRate/blockLength */
364   sampleRateFract =
365       (FIXP_DBL)(sampleRate << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
366   blockLengthFract =
367       (FIXP_DBL)(blockLength << (DFRACT_BITS - 1 - METADATA_LINT_BITS));
368   f = fDivNorm(sampleRateFract, blockLengthFract, &e_res);
369   f = scaleValue(f, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
370 
371   /* product = t*f */
372   product = fMultNorm(t, f, &e_res);
373   product = scaleValue(
374       product, e_res + METADATA_INT_BITS); /* convert to METADATA_FRACT */
375 
376   /* exponent = (-1.0/((t) * (f))) */
377   exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res);
378   exponent = scaleValue(
379       exponent, e_res - METADATA_INT_BITS); /* convert to METADATA_FRACT */
380 
381   /* exponent * ld(e) */
382   exponent = fMult(exponent, FIXP_ILOG2_DIV2) << 1; /* e^(x) = 2^(x*ld(e)) */
383 
384   /* exp(-1.0/((t) * (f))) */
385   result = f2Pow(-exponent, DFRACT_BITS - 1 - METADATA_FRACT_BITS, &e_res);
386 
387   /* result = 1.0 - exp(-1.0/((t) * (f))) */
388   result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
389 
390   return result;
391 }
392 
findPeakLevels(HDRC_COMP drcComp,const INT_PCM * const inSamples,const FIXP_DBL clev,const FIXP_DBL slev,const FIXP_DBL ext_leva,const FIXP_DBL ext_levb,const FIXP_DBL lfe_lev,const FIXP_DBL dmxGain5,const FIXP_DBL dmxGain2,FIXP_DBL peak[2])393 static void findPeakLevels(HDRC_COMP drcComp, const INT_PCM* const inSamples,
394                            const FIXP_DBL clev, const FIXP_DBL slev,
395                            const FIXP_DBL ext_leva, const FIXP_DBL ext_levb,
396                            const FIXP_DBL lfe_lev, const FIXP_DBL dmxGain5,
397                            const FIXP_DBL dmxGain2, FIXP_DBL peak[2]) {
398   int i, c;
399   FIXP_DBL tmp = FL2FXCONST_DBL(0.f);
400   INT_PCM maxSample = 0;
401 
402   /* find peak level */
403   peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
404   for (i = 0; i < drcComp->blockLength; i++) {
405     const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
406 
407     /* single channels */
408     for (c = 0; c < (int)drcComp->channels; c++) {
409       maxSample = fMax(maxSample, (INT_PCM)fAbs(pSamples[c]));
410     }
411   }
412   peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample) >> DOWNMIX_SHIFT);
413 
414   /* 7.1/6.1 to 5.1 downmixes */
415   if (drcComp->fullChannels > 5) {
416     for (i = 0; i < drcComp->blockLength; i++) {
417       const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
418 
419       /* channel 1 (L, Ls,...) */
420       tmp = FL2FXCONST_DBL(0.f);
421       switch (drcComp->chanConfig) {
422         case MODE_6_1:
423           tmp +=
424               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
425               (DOWNMIX_SHIFT - 1); /* Ls */
426           tmp +=
427               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
428               (DOWNMIX_SHIFT - 1); /* Cs */
429           break;
430         case MODE_7_1_BACK:
431         case MODE_7_1_REAR_SURROUND:
432           tmp +=
433               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
434               (DOWNMIX_SHIFT - 1); /* Ls */
435           tmp +=
436               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
437               (DOWNMIX_SHIFT - 1); /* Lrs / Lss */
438           break;
439         case MODE_1_2_2_2_1:
440         case MODE_7_1_FRONT_CENTER:
441           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
442                   DOWNMIX_SHIFT); /* L */
443           tmp +=
444               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
445               (DOWNMIX_SHIFT - 1); /* Lc */
446           break;
447         case MODE_7_1_TOP_FRONT:
448           tmp +=
449               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
450               (DOWNMIX_SHIFT - 1); /* L */
451           tmp +=
452               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
453               (DOWNMIX_SHIFT - 1); /* Lvh */
454           break;
455         default:
456           break;
457       }
458       peak[0] = fixMax(peak[0], fixp_abs(tmp));
459 
460       /* channel 2 (R, Rs,...) */
461       tmp = FL2FXCONST_DBL(0.f);
462       switch (drcComp->chanConfig) {
463         case MODE_6_1:
464           tmp +=
465               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
466               (DOWNMIX_SHIFT - 1); /* Rs */
467           tmp +=
468               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
469               (DOWNMIX_SHIFT - 1); /* Cs */
470           break;
471         case MODE_7_1_BACK:
472         case MODE_7_1_REAR_SURROUND:
473           tmp +=
474               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
475               (DOWNMIX_SHIFT - 1); /* Rs */
476           tmp +=
477               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
478               (DOWNMIX_SHIFT - 1); /* Rrs / Rss */
479           break;
480         case MODE_1_2_2_2_1:
481         case MODE_7_1_FRONT_CENTER:
482           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
483                   DOWNMIX_SHIFT); /* R */
484           tmp +=
485               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
486               (DOWNMIX_SHIFT - 1); /* Rc */
487           break;
488         case MODE_7_1_TOP_FRONT:
489           tmp +=
490               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
491               (DOWNMIX_SHIFT - 1); /* R */
492           tmp +=
493               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
494               (DOWNMIX_SHIFT - 1); /* Rvh */
495           break;
496         default:
497           break;
498       }
499       peak[0] = fixMax(peak[0], fixp_abs(tmp));
500 
501       /* channel 3 (C) */
502       tmp = FL2FXCONST_DBL(0.f);
503       switch (drcComp->chanConfig) {
504         case MODE_1_2_2_2_1:
505         case MODE_7_1_FRONT_CENTER:
506           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
507                   DOWNMIX_SHIFT); /* C */
508           tmp +=
509               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
510               (DOWNMIX_SHIFT - 1); /* Lc */
511           tmp +=
512               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
513               (DOWNMIX_SHIFT - 1); /* Rc */
514           break;
515         default:
516           break;
517       }
518       peak[0] = fixMax(peak[0], fixp_abs(tmp));
519 
520     } /* for (blocklength) */
521 
522     /* take downmix gain into accout */
523     peak[0] = fMult(dmxGain5, peak[0])
524               << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
525   }
526 
527   /* 7.1 / 5.1 to stereo downmixes */
528   if (drcComp->fullChannels > 2) {
529     /* Lt/Rt downmix */
530     for (i = 0; i < drcComp->blockLength; i++) {
531       const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
532 
533       /* Lt */
534       tmp = FL2FXCONST_DBL(0.f);
535       if (drcComp->channelIdx[LS] >= 0)
536         tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
537                          (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
538                (DOWNMIX_SHIFT - 1); /* Ls */
539       if (drcComp->channelIdx[LS2] >= 0)
540         tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
541                          (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
542                (DOWNMIX_SHIFT - 1); /* Ls2 */
543       if (drcComp->channelIdx[RS] >= 0)
544         tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
545                          (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
546                (DOWNMIX_SHIFT - 1); /* Rs */
547       if (drcComp->channelIdx[RS2] >= 0)
548         tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
549                          (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
550                (DOWNMIX_SHIFT - 1); /* Rs2 */
551       if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
552         tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
553       if (drcComp->channelIdx[S] >= 0)
554         tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f),
555                          (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
556                (DOWNMIX_SHIFT - 1); /* S */
557       if (drcComp->channelIdx[C] >= 0)
558         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
559                          (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
560                (DOWNMIX_SHIFT - 1); /* C */
561       tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
562               DOWNMIX_SHIFT); /* L */
563 
564       /* apply scaling of downmix gains */
565       /* only for positive values only, as legacy decoders might not know this
566        * parameter */
567       if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
568         if (drcComp->fullChannels > 5) {
569           tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
570         }
571         tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
572       }
573       peak[0] = fixMax(peak[0], fixp_abs(tmp));
574 
575       /* Rt */
576       tmp = FL2FXCONST_DBL(0.f);
577       if (drcComp->channelIdx[LS] >= 0)
578         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
579                          (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
580                (DOWNMIX_SHIFT - 1); /* Ls */
581       if (drcComp->channelIdx[LS2] >= 0)
582         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
583                          (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
584                (DOWNMIX_SHIFT - 1); /* Ls2 */
585       if (drcComp->channelIdx[RS] >= 0)
586         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
587                          (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
588                (DOWNMIX_SHIFT - 1); /* Rs */
589       if (drcComp->channelIdx[RS2] >= 0)
590         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
591                          (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
592                (DOWNMIX_SHIFT - 1); /* Rs2 */
593       if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
594         tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
595       if (drcComp->channelIdx[S] >= 0)
596         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
597                          (FIXP_PCM)pSamples[drcComp->channelIdx[S]]) >>
598                (DOWNMIX_SHIFT - 1); /* S */
599       if (drcComp->channelIdx[C] >= 0)
600         tmp += fMultDiv2(FL2FXCONST_DBL(0.707f),
601                          (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
602                (DOWNMIX_SHIFT - 1); /* C */
603       tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
604               DOWNMIX_SHIFT); /* R */
605 
606       /* apply scaling of downmix gains */
607       /* only for positive values only, as legacy decoders might not know this
608        * parameter */
609       if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
610         if (drcComp->fullChannels > 5) {
611           tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
612         }
613         tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
614       }
615       peak[0] = fixMax(peak[0], fixp_abs(tmp));
616     }
617 
618     /* Lo/Ro downmix */
619     for (i = 0; i < drcComp->blockLength; i++) {
620       const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
621 
622       /* Lo */
623       tmp = FL2FXCONST_DBL(0.f);
624       switch (drcComp->chanConfig) {
625         case MODE_6_1:
626           tmp += fMultDiv2(fMult(slev, ext_leva),
627                            (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
628                  (DOWNMIX_SHIFT - 1); /* Ls */
629           tmp += fMultDiv2(fMult(slev, ext_levb),
630                            (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
631                  (DOWNMIX_SHIFT - 1); /* Cs */
632           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
633                  (DOWNMIX_SHIFT - 1); /* C */
634           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
635                   DOWNMIX_SHIFT); /* L */
636           tmp +=
637               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
638               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
639           break;
640         case MODE_7_1_BACK:
641         case MODE_7_1_REAR_SURROUND:
642           tmp += fMultDiv2(fMult(slev, ext_leva),
643                            (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
644                  (DOWNMIX_SHIFT - 1); /* Ls */
645           tmp += fMultDiv2(fMult(slev, ext_levb),
646                            (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
647                  (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
648           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
649                  (DOWNMIX_SHIFT - 1); /* C */
650           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
651                   DOWNMIX_SHIFT); /* L */
652           tmp +=
653               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
654               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
655           break;
656         case MODE_1_2_2_2_1:
657         case MODE_7_1_FRONT_CENTER:
658           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
659                   DOWNMIX_SHIFT); /* L */
660           tmp +=
661               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
662               (DOWNMIX_SHIFT - 1); /* Lc */
663           tmp += fMultDiv2(fMult(ext_leva, clev),
664                            (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
665                  (DOWNMIX_SHIFT - 1); /* Lc - second path*/
666           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
667                  (DOWNMIX_SHIFT - 1); /* C */
668           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
669                  (DOWNMIX_SHIFT - 1); /* Ls */
670           tmp +=
671               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
672               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
673           break;
674         case MODE_7_1_TOP_FRONT:
675           tmp +=
676               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
677               (DOWNMIX_SHIFT - 1); /* L */
678           tmp +=
679               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
680               (DOWNMIX_SHIFT - 1); /* Lvh */
681           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
682                  (DOWNMIX_SHIFT - 1); /* C */
683           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
684                  (DOWNMIX_SHIFT - 1); /* Ls */
685           tmp +=
686               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
687               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
688           break;
689         default:
690           if (drcComp->channelIdx[LS] >= 0)
691             tmp +=
692                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
693                 (DOWNMIX_SHIFT - 1); /* Ls */
694           if (drcComp->channelIdx[LS2] >= 0)
695             tmp +=
696                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
697                 (DOWNMIX_SHIFT - 1); /* Ls2 */
698           if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
699             tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
700           if (drcComp->channelIdx[S] >= 0)
701             tmp +=
702                 fMultDiv2(slev,
703                           fMult(FL2FXCONST_DBL(0.7f),
704                                 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
705                 (DOWNMIX_SHIFT - 1); /* S */
706           if (drcComp->channelIdx[C] >= 0)
707             tmp +=
708                 fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
709                 (DOWNMIX_SHIFT - 1); /* C */
710           if (drcComp->channelIdx[3] >= 0)
711             tmp += fMultDiv2(lfe_lev,
712                              (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
713                    (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
714           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
715                   DOWNMIX_SHIFT); /* L */
716           break;
717       }
718 
719       /* apply scaling of downmix gains */
720       /* only for positive values only, as legacy decoders might not know this
721        * parameter */
722       if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
723         if (drcComp->fullChannels > 5) {
724           tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
725         }
726         tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
727       }
728       peak[0] = fixMax(peak[0], fixp_abs(tmp));
729 
730       /* Ro */
731       tmp = FL2FXCONST_DBL(0.f);
732       switch (drcComp->chanConfig) {
733         case MODE_6_1:
734           tmp += fMultDiv2(fMult(slev, ext_leva),
735                            (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
736                  (DOWNMIX_SHIFT - 1); /* Rs */
737           tmp += fMultDiv2(fMult(slev, ext_levb),
738                            (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
739                  (DOWNMIX_SHIFT - 1); /* Cs */
740           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
741                  (DOWNMIX_SHIFT - 1); /* C */
742           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
743                   DOWNMIX_SHIFT); /* R */
744           tmp +=
745               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
746               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
747           break;
748         case MODE_7_1_BACK:
749         case MODE_7_1_REAR_SURROUND:
750           tmp += fMultDiv2(fMult(slev, ext_leva),
751                            (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
752                  (DOWNMIX_SHIFT - 1); /* Rs */
753           tmp += fMultDiv2(fMult(slev, ext_levb),
754                            (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
755                  (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
756           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
757                  (DOWNMIX_SHIFT - 1); /* C */
758           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
759                   DOWNMIX_SHIFT); /* R */
760           tmp +=
761               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
762               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
763           break;
764         case MODE_1_2_2_2_1:
765         case MODE_7_1_FRONT_CENTER:
766           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
767                   DOWNMIX_SHIFT); /* R */
768           tmp +=
769               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
770               (DOWNMIX_SHIFT - 1); /* Rc */
771           tmp += fMultDiv2(fMult(ext_leva, clev),
772                            (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
773                  (DOWNMIX_SHIFT - 1); /* Rc - second path*/
774           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
775                  (DOWNMIX_SHIFT - 1); /* C */
776           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
777                  (DOWNMIX_SHIFT - 1); /* Rs */
778           tmp +=
779               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
780               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
781           break;
782         case MODE_7_1_TOP_FRONT:
783           tmp +=
784               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
785               (DOWNMIX_SHIFT - 1); /* R */
786           tmp +=
787               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
788               (DOWNMIX_SHIFT - 1); /* Rvh */
789           tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
790                  (DOWNMIX_SHIFT - 1); /* C */
791           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
792                  (DOWNMIX_SHIFT - 1); /* Rs */
793           tmp +=
794               fMultDiv2(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
795               (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
796           break;
797         default:
798           if (drcComp->channelIdx[RS] >= 0)
799             tmp +=
800                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
801                 (DOWNMIX_SHIFT - 1); /* Rs */
802           if (drcComp->channelIdx[RS2] >= 0)
803             tmp +=
804                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
805                 (DOWNMIX_SHIFT - 1); /* Rs2 */
806           if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0))
807             tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
808           if (drcComp->channelIdx[S] >= 0)
809             tmp +=
810                 fMultDiv2(slev,
811                           fMult(FL2FXCONST_DBL(0.7f),
812                                 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
813                 (DOWNMIX_SHIFT - 1); /* S */
814           if (drcComp->channelIdx[C] >= 0)
815             tmp +=
816                 fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
817                 (DOWNMIX_SHIFT - 1); /* C */
818           if (drcComp->channelIdx[3] >= 0)
819             tmp += fMultDiv2(lfe_lev,
820                              (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
821                    (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
822           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
823                   DOWNMIX_SHIFT); /* R */
824       }
825 
826       /* apply scaling of downmix gains */
827       /* only for positive values only, as legacy decoders might not know this
828        * parameter */
829       if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
830         if (drcComp->fullChannels > 5) {
831           tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
832         }
833         tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
834       }
835       peak[0] = fixMax(peak[0], fixp_abs(tmp));
836     }
837   }
838 
839   peak[1] = fixMax(peak[0], peak[1]);
840 
841   /* Mono Downmix - for comp_val only */
842   if (drcComp->fullChannels > 1) {
843     for (i = 0; i < drcComp->blockLength; i++) {
844       const INT_PCM* pSamples = &inSamples[i * drcComp->channels];
845 
846       tmp = FL2FXCONST_DBL(0.f);
847       switch (drcComp->chanConfig) {
848         case MODE_6_1:
849           tmp += fMultDiv2(fMult(slev, ext_leva),
850                            (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
851                  (DOWNMIX_SHIFT - 1); /* Ls */
852           tmp += fMultDiv2(fMult(slev, ext_leva),
853                            (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
854                  (DOWNMIX_SHIFT - 1); /* Rs */
855           tmp += fMult(fMult(slev, ext_levb),
856                        (FIXP_PCM)pSamples[drcComp->channelIdx[6]]) >>
857                  (DOWNMIX_SHIFT - 1); /* Cs */
858           tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
859                  (DOWNMIX_SHIFT - 1); /* C */
860           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
861                   DOWNMIX_SHIFT); /* L */
862           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
863                   DOWNMIX_SHIFT); /* R */
864           tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
865                  (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
866           break;
867         case MODE_7_1_BACK:
868         case MODE_7_1_REAR_SURROUND:
869           tmp += fMultDiv2(fMult(slev, ext_leva),
870                            (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
871                  (DOWNMIX_SHIFT - 1); /* Ls */
872           tmp += fMultDiv2(fMult(slev, ext_leva),
873                            (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
874                  (DOWNMIX_SHIFT - 1); /* Rs */
875           tmp += fMultDiv2(fMult(slev, ext_levb),
876                            (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
877                  (DOWNMIX_SHIFT - 1); /* Lrs / Lss*/
878           tmp += fMultDiv2(fMult(slev, ext_levb),
879                            (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
880                  (DOWNMIX_SHIFT - 1); /* Rrs / Rss*/
881           tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
882                  (DOWNMIX_SHIFT - 1); /* C */
883           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
884                   DOWNMIX_SHIFT); /* L */
885           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
886                   DOWNMIX_SHIFT); /* R */
887           tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
888                  (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
889           break;
890         case MODE_1_2_2_2_1:
891         case MODE_7_1_FRONT_CENTER:
892           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
893                   DOWNMIX_SHIFT); /* L */
894           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
895                   DOWNMIX_SHIFT); /* R */
896           tmp +=
897               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
898               (DOWNMIX_SHIFT - 1); /* Lc */
899           tmp +=
900               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
901               (DOWNMIX_SHIFT - 1); /* Rc */
902           tmp += fMultDiv2(fMult(ext_leva, clev),
903                            (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
904                  (DOWNMIX_SHIFT - 1); /* Lc - second path*/
905           tmp += fMultDiv2(fMult(ext_leva, clev),
906                            (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
907                  (DOWNMIX_SHIFT - 1); /* Rc - second path*/
908           tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
909                  (DOWNMIX_SHIFT - 1); /* C */
910           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
911                  (DOWNMIX_SHIFT - 1); /* Ls */
912           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
913                  (DOWNMIX_SHIFT - 1); /* Rs */
914           tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
915                  (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
916           break;
917         case MODE_7_1_TOP_FRONT:
918           tmp +=
919               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[0]]) >>
920               (DOWNMIX_SHIFT - 1); /* L */
921           tmp +=
922               fMultDiv2(ext_leva, (FIXP_PCM)pSamples[drcComp->channelIdx[1]]) >>
923               (DOWNMIX_SHIFT - 1); /* R */
924           tmp +=
925               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[7]]) >>
926               (DOWNMIX_SHIFT - 1); /* Lvh */
927           tmp +=
928               fMultDiv2(ext_levb, (FIXP_PCM)pSamples[drcComp->channelIdx[8]]) >>
929               (DOWNMIX_SHIFT - 1); /* Rvh */
930           tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[2]]) >>
931                  (DOWNMIX_SHIFT - 1); /* C */
932           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[4]]) >>
933                  (DOWNMIX_SHIFT - 1); /* Ls */
934           tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[5]]) >>
935                  (DOWNMIX_SHIFT - 1); /* Rs */
936           tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
937                  (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
938           break;
939         default:
940           if (drcComp->channelIdx[LS] >= 0)
941             tmp +=
942                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]]) >>
943                 (DOWNMIX_SHIFT - 1); /* Ls */
944           if (drcComp->channelIdx[LS2] >= 0)
945             tmp +=
946                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]]) >>
947                 (DOWNMIX_SHIFT - 1); /* Ls2 */
948           if (drcComp->channelIdx[RS] >= 0)
949             tmp +=
950                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]]) >>
951                 (DOWNMIX_SHIFT - 1); /* Rs */
952           if (drcComp->channelIdx[RS2] >= 0)
953             tmp +=
954                 fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]]) >>
955                 (DOWNMIX_SHIFT - 1); /* Rs2 */
956           if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0))
957             tmp = fMult(FL2FXCONST_DBL(0.707f), tmp); /* 7.1ch */
958           /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/ /* 7.1ch */
959           if (drcComp->channelIdx[S] >= 0)
960             tmp +=
961                 fMultDiv2(slev,
962                           fMult(FL2FXCONST_DBL(0.7f),
963                                 (FIXP_PCM)pSamples[drcComp->channelIdx[S]])) >>
964                 (DOWNMIX_SHIFT - 1); /* S */
965           if (drcComp->channelIdx[C] >= 0)
966             tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]]) >>
967                    (DOWNMIX_SHIFT - 1); /* C (2*clev) */
968           if (drcComp->channelIdx[3] >= 0)
969             tmp += fMult(lfe_lev, (FIXP_PCM)pSamples[drcComp->channelIdx[3]]) >>
970                    (DOWNMIX_SHIFT - 1 - LFE_LEV_SCALE); /* LFE */
971           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]]) >>
972                   DOWNMIX_SHIFT); /* L */
973           tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]]) >>
974                   DOWNMIX_SHIFT); /* R */
975       }
976 
977       /* apply scaling of downmix gains */
978       /* only for positive values only, as legacy decoders might not know this
979        * parameter */
980       if (dmxGain2 > FL2FXCONST_DBL(0.f)) {
981         if (drcComp->fullChannels > 5) {
982           tmp = fMult(dmxGain5, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
983         }
984         tmp = fMult(dmxGain2, tmp) << (DFRACT_BITS - 1 - METADATA_FRACT_BITS);
985       }
986       peak[1] = fixMax(peak[1], fixp_abs(tmp));
987     }
988   }
989 }
990 
FDK_DRC_Generator_Open(HDRC_COMP * phDrcComp)991 INT FDK_DRC_Generator_Open(HDRC_COMP* phDrcComp) {
992   INT err = 0;
993   HDRC_COMP hDcComp = NULL;
994 
995   if (phDrcComp == NULL) {
996     err = -1;
997     goto bail;
998   }
999 
1000   /* allocate memory */
1001   hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
1002 
1003   if (hDcComp == NULL) {
1004     err = -1;
1005     goto bail;
1006   }
1007 
1008   FDKmemclear(hDcComp, sizeof(DRC_COMP));
1009 
1010   /* Return drc compressor instance */
1011   *phDrcComp = hDcComp;
1012   return err;
1013 bail:
1014   FDK_DRC_Generator_Close(&hDcComp);
1015   return err;
1016 }
1017 
FDK_DRC_Generator_Close(HDRC_COMP * phDrcComp)1018 INT FDK_DRC_Generator_Close(HDRC_COMP* phDrcComp) {
1019   if (phDrcComp == NULL) {
1020     return -1;
1021   }
1022   if (*phDrcComp != NULL) {
1023     FDKfree(*phDrcComp);
1024     *phDrcComp = NULL;
1025   }
1026   return 0;
1027 }
1028 
FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF,const INT blockLength,const UINT sampleRate,const CHANNEL_MODE channelMode,const CHANNEL_ORDER channelOrder,const UCHAR useWeighting)1029 INT FDK_DRC_Generator_Initialize(HDRC_COMP drcComp,
1030                                  const DRC_PROFILE profileLine,
1031                                  const DRC_PROFILE profileRF,
1032                                  const INT blockLength, const UINT sampleRate,
1033                                  const CHANNEL_MODE channelMode,
1034                                  const CHANNEL_ORDER channelOrder,
1035                                  const UCHAR useWeighting) {
1036   int i;
1037   CHANNEL_MAPPING channelMapping;
1038 
1039   drcComp->limDecay =
1040       FL2FXCONST_DBL(((0.006f / 256) * blockLength) / METADATA_INT_SCALE);
1041 
1042   /* Save parameters. */
1043   drcComp->blockLength = blockLength;
1044   drcComp->sampleRate = sampleRate;
1045   drcComp->chanConfig = channelMode;
1046   drcComp->useWeighting = useWeighting;
1047 
1048   if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF) !=
1049       0) { /* expects initialized blockLength and sampleRate */
1050     return (-1);
1051   }
1052 
1053   /* Set number of channels and channel offsets. */
1054   if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder,
1055                                    &channelMapping) != AAC_ENC_OK) {
1056     return (-2);
1057   }
1058 
1059   for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
1060 
1061   switch (channelMode) {
1062     case MODE_1: /* mono */
1063       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1064       break;
1065     case MODE_2: /* stereo */
1066       drcComp->channelIdx[L] = channelMapping.elInfo[0].ChannelIndex[0];
1067       drcComp->channelIdx[R] = channelMapping.elInfo[0].ChannelIndex[1];
1068       break;
1069     case MODE_1_2: /* 3ch */
1070       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1071       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1072       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1073       break;
1074     case MODE_1_2_1: /* 4ch */
1075       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1076       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1077       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1078       drcComp->channelIdx[S] = channelMapping.elInfo[2].ChannelIndex[0];
1079       break;
1080     case MODE_1_2_2: /* 5ch */
1081       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1082       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1083       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1084       drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
1085       drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
1086       break;
1087     case MODE_1_2_2_1: /* 5.1 ch */
1088       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0];
1089       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1];
1090       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0];
1091       drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0];
1092       drcComp->channelIdx[LS] = channelMapping.elInfo[2].ChannelIndex[0];
1093       drcComp->channelIdx[RS] = channelMapping.elInfo[2].ChannelIndex[1];
1094       break;
1095     case MODE_1_2_2_2_1: /* 7.1 ch */
1096     case MODE_7_1_FRONT_CENTER:
1097       drcComp->channelIdx[L] = channelMapping.elInfo[2].ChannelIndex[0]; /* l */
1098       drcComp->channelIdx[R] = channelMapping.elInfo[2].ChannelIndex[1]; /* r */
1099       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1100       drcComp->channelIdx[LFE] =
1101           channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1102       drcComp->channelIdx[LS] =
1103           channelMapping.elInfo[3].ChannelIndex[0]; /* ls */
1104       drcComp->channelIdx[RS] =
1105           channelMapping.elInfo[3].ChannelIndex[1]; /* rs */
1106       drcComp->channelIdx[LS2] =
1107           channelMapping.elInfo[1].ChannelIndex[0]; /* lc */
1108       drcComp->channelIdx[RS2] =
1109           channelMapping.elInfo[1].ChannelIndex[1]; /* rc */
1110       break;
1111     case MODE_7_1_BACK:
1112     case MODE_7_1_REAR_SURROUND:
1113       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1114       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1115       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1116       drcComp->channelIdx[LFE] =
1117           channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1118       drcComp->channelIdx[LS] =
1119           channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */
1120       drcComp->channelIdx[RS] =
1121           channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */
1122       drcComp->channelIdx[LS2] =
1123           channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1124       drcComp->channelIdx[RS2] =
1125           channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1126       break;
1127     case MODE_6_1:
1128       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1129       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1130       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1131       drcComp->channelIdx[LFE] =
1132           channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
1133       drcComp->channelIdx[LS] =
1134           channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1135       drcComp->channelIdx[RS] =
1136           channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1137       drcComp->channelIdx[S] = channelMapping.elInfo[3].ChannelIndex[0]; /* s */
1138       break;
1139     case MODE_7_1_TOP_FRONT:
1140       drcComp->channelIdx[L] = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
1141       drcComp->channelIdx[R] = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
1142       drcComp->channelIdx[C] = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
1143       drcComp->channelIdx[LFE] =
1144           channelMapping.elInfo[3].ChannelIndex[0]; /* lfe */
1145       drcComp->channelIdx[LS] =
1146           channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
1147       drcComp->channelIdx[RS] =
1148           channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
1149       drcComp->channelIdx[LS2] =
1150           channelMapping.elInfo[4].ChannelIndex[0]; /* lvh2 */
1151       drcComp->channelIdx[RS2] =
1152           channelMapping.elInfo[4].ChannelIndex[1]; /* rvh2 */
1153       break;
1154     default:
1155       return (-1);
1156   }
1157 
1158   drcComp->fullChannels = channelMapping.nChannelsEff;
1159   drcComp->channels = channelMapping.nChannels;
1160 
1161   /* Init states. */
1162   drcComp->smoothLevel[0] = drcComp->smoothLevel[1] =
1163       (FIXP_DBL)(-(135 << METADATA_FRACT_BITS));
1164 
1165   FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
1166   FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
1167   FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
1168   FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
1169   FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
1170 
1171   return (0);
1172 }
1173 
FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF)1174 INT FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,
1175                                     const DRC_PROFILE profileLine,
1176                                     const DRC_PROFILE profileRF) {
1177   int profileIdx, i;
1178 
1179   drcComp->profile[0] = profileLine;
1180   drcComp->profile[1] = profileRF;
1181 
1182   for (i = 0; i < 2; i++) {
1183     /* get profile index */
1184     switch (drcComp->profile[i]) {
1185       case DRC_NONE:
1186       case DRC_NOT_PRESENT:
1187       case DRC_FILMSTANDARD:
1188         profileIdx = 0;
1189         break;
1190       case DRC_FILMLIGHT:
1191         profileIdx = 1;
1192         break;
1193       case DRC_MUSICSTANDARD:
1194         profileIdx = 2;
1195         break;
1196       case DRC_MUSICLIGHT:
1197         profileIdx = 3;
1198         break;
1199       case DRC_SPEECH:
1200         profileIdx = 4;
1201         break;
1202       case DRC_DELAY_TEST:
1203         profileIdx = 5;
1204         break;
1205       default:
1206         return (-1);
1207     }
1208 
1209     /* get parameters for selected profile */
1210     if (profileIdx >= 0) {
1211       drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
1212       drcComp->boostThr[i] = tabBoostThr[profileIdx];
1213       drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
1214       drcComp->cutThr[i] = tabCutThr[profileIdx];
1215       drcComp->maxCutThr[i] = tabMaxCutThr[profileIdx];
1216 
1217       drcComp->boostFac[i] = tabBoostRatio[profileIdx];
1218       drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
1219       drcComp->cutFac[i] = tabCutRatio[profileIdx];
1220 
1221       drcComp->maxBoost[i] = tabMaxBoost[profileIdx];
1222       drcComp->maxCut[i] = tabMaxCut[profileIdx];
1223       drcComp->maxEarlyCut[i] =
1224           -fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]),
1225                  drcComp->earlyCutFac[i]); /* no scaling after mult needed,
1226                                               earlyCutFac is in FIXP_DBL */
1227 
1228       drcComp->fastAttack[i] = tc2Coeff(
1229           tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1230       drcComp->fastDecay[i] = tc2Coeff(
1231           tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1232       drcComp->slowAttack[i] = tc2Coeff(
1233           tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1234       drcComp->slowDecay[i] = tc2Coeff(
1235           tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
1236       drcComp->holdOff[i] = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
1237 
1238       drcComp->attackThr[i] = tabAttackThr[profileIdx];
1239       drcComp->decayThr[i] = tabDecayThr[profileIdx];
1240     }
1241 
1242     drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
1243   }
1244   return (0);
1245 }
1246 
FDK_DRC_Generator_Calc(HDRC_COMP drcComp,const INT_PCM * const inSamples,const UINT inSamplesBufSize,const INT dialnorm,const INT drc_TargetRefLevel,const INT comp_TargetRefLevel,const FIXP_DBL clev,const FIXP_DBL slev,const FIXP_DBL ext_leva,const FIXP_DBL ext_levb,const FIXP_DBL lfe_lev,const INT dmxGain5,const INT dmxGain2,INT * const pDynrng,INT * const pCompr)1247 INT FDK_DRC_Generator_Calc(HDRC_COMP drcComp, const INT_PCM* const inSamples,
1248                            const UINT inSamplesBufSize, const INT dialnorm,
1249                            const INT drc_TargetRefLevel,
1250                            const INT comp_TargetRefLevel, const FIXP_DBL clev,
1251                            const FIXP_DBL slev, const FIXP_DBL ext_leva,
1252                            const FIXP_DBL ext_levb, const FIXP_DBL lfe_lev,
1253                            const INT dmxGain5, const INT dmxGain2,
1254                            INT* const pDynrng, INT* const pCompr) {
1255   int i, c;
1256   FIXP_DBL peak[2];
1257 
1258   /**************************************************************************
1259    * compressor
1260    **************************************************************************/
1261   if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
1262     /* Calc loudness level */
1263     FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
1264     int level_e = DFRACT_BITS - 1;
1265 
1266     /* Increase energy time resolution with shorter processing blocks. 16 is an
1267      * empiric value. */
1268     const int granuleLength = fixMin(16, drcComp->blockLength);
1269 
1270     if (drcComp->useWeighting) {
1271       FIXP_DBL x1, x2, y, y1, y2;
1272       /* sum of filter coefficients about 2.5 -> squared value is 6.25
1273          WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce
1274          granuleShift by 1.
1275        */
1276       const int granuleShift = getShiftFactor(granuleLength) - 1;
1277 
1278       for (c = 0; c < (int)drcComp->channels; c++) {
1279         const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
1280 
1281         if (c == drcComp->channelIdx[LFE]) {
1282           continue; /* skip LFE */
1283         }
1284 
1285         /* get filter states */
1286         x1 = drcComp->filter[c].x1;
1287         x2 = drcComp->filter[c].x2;
1288         y1 = drcComp->filter[c].y1;
1289         y2 = drcComp->filter[c].y2;
1290 
1291         i = 0;
1292 
1293         do {
1294           int offset = i;
1295           FIXP_DBL accu = FL2FXCONST_DBL(0.f);
1296 
1297           for (i = offset;
1298                i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
1299             /* apply weighting filter */
1300             FIXP_DBL x =
1301                 FX_PCM2FX_DBL((FIXP_PCM)pSamples[i]) >> WEIGHTING_FILTER_SHIFT;
1302 
1303             /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
1304             y = fMult(b0, x - x2) - fMult(a1, y1) - fMult(a2, y2);
1305 
1306             x2 = x1;
1307             x1 = x;
1308             y2 = y1;
1309             y1 = y;
1310 
1311             accu += fPow2Div2(y) >> (granuleShift - 1); /* partial energy */
1312           }                                             /* i */
1313 
1314           fixpAdd(accu, granuleShift + 2 * WEIGHTING_FILTER_SHIFT, &level_b,
1315                   &level_e); /* sup up partial energies */
1316 
1317         } while (i < drcComp->blockLength);
1318 
1319         /* save filter states */
1320         drcComp->filter[c].x1 = x1;
1321         drcComp->filter[c].x2 = x2;
1322         drcComp->filter[c].y1 = y1;
1323         drcComp->filter[c].y2 = y2;
1324       } /* c */
1325     }   /* weighting */
1326     else {
1327       const int granuleShift = getShiftFactor(granuleLength);
1328 
1329       for (c = 0; c < (int)drcComp->channels; c++) {
1330         const INT_PCM* pSamples = inSamples + c * inSamplesBufSize;
1331 
1332         if ((int)c == drcComp->channelIdx[LFE]) {
1333           continue; /* skip LFE */
1334         }
1335 
1336         i = 0;
1337 
1338         do {
1339           int offset = i;
1340           FIXP_DBL accu = FL2FXCONST_DBL(0.f);
1341 
1342           for (i = offset;
1343                i < fixMin(offset + granuleLength, drcComp->blockLength); i++) {
1344             /* partial energy */
1345             accu += fPow2Div2((FIXP_PCM)pSamples[i]) >> (granuleShift - 1);
1346           } /* i */
1347 
1348           fixpAdd(accu, granuleShift, &level_b,
1349                   &level_e); /* sup up partial energies */
1350 
1351         } while (i < drcComp->blockLength);
1352       }
1353     } /* weighting */
1354 
1355     /*
1356      * Convert to dBFS, apply dialnorm
1357      */
1358     /* level scaling */
1359 
1360     /* descaled level in ld64 representation */
1361     FIXP_DBL ldLevel =
1362         CalcLdData(level_b) +
1363         (FIXP_DBL)((level_e - 12) << (DFRACT_BITS - 1 - LD_DATA_SHIFT)) -
1364         CalcLdData((FIXP_DBL)(drcComp->blockLength << (DFRACT_BITS - 1 - 12)));
1365 
1366     /* if (level < 1e-10) level = 1e-10f; */
1367     ldLevel =
1368         fMax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
1369 
1370     /* level = 10 * log(level)/log(10) + 3;
1371      *       = 10*log(2)/log(10) * ld(level) + 3;
1372      *       = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
1373      *       = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
1374      *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
1375      * * 64
1376      *
1377      *    additional scaling with METADATA_FRACT_BITS:
1378      *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64)
1379      * * 64 * 2^(METADATA_FRACT_BITS) = 10 * (0.30102999566398119521373889472449
1380      * * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) =
1381      * 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * (
1382      * 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
1383      * */
1384     FIXP_DBL level = fMult(
1385         (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
1386         fMult(FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) +
1387             (FIXP_DBL)(FL2FXCONST_DBL(0.3f) >> LD_DATA_SHIFT));
1388 
1389     /* level -= dialnorm + 31 */ /* this is fixed to Dolby-ReferenceLevel as
1390                                     compressor profiles are defined relative to
1391                                     this */
1392     level -= ((FIXP_DBL)(dialnorm << (METADATA_FRACT_BITS - 16)) +
1393               (FIXP_DBL)(31 << METADATA_FRACT_BITS));
1394 
1395     for (i = 0; i < 2; i++) {
1396       if (drcComp->profile[i] == DRC_NONE) {
1397         /* no compression */
1398         drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
1399       } else {
1400         FIXP_DBL gain, alpha, lvl2smthlvl;
1401 
1402         /* calc static gain */
1403         if (level <= drcComp->maxBoostThr[i]) {
1404           /* max boost */
1405           gain = drcComp->maxBoost[i];
1406         } else if (level < drcComp->boostThr[i]) {
1407           /* boost range */
1408           gain = fMult((level - drcComp->boostThr[i]), drcComp->boostFac[i]);
1409         } else if (level <= drcComp->earlyCutThr[i]) {
1410           /* null band */
1411           gain = FL2FXCONST_DBL(0.f);
1412         } else if (level <= drcComp->cutThr[i]) {
1413           /* early cut range */
1414           gain =
1415               fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
1416         } else if (level < drcComp->maxCutThr[i]) {
1417           /* cut range */
1418           gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) -
1419                  drcComp->maxEarlyCut[i];
1420         } else {
1421           /* max cut */
1422           gain = -drcComp->maxCut[i];
1423         }
1424 
1425         /* choose time constant */
1426         lvl2smthlvl = level - drcComp->smoothLevel[i];
1427         if (gain < drcComp->smoothGain[i]) {
1428           /* attack */
1429           if (lvl2smthlvl > drcComp->attackThr[i]) {
1430             /* fast attack */
1431             alpha = drcComp->fastAttack[i];
1432           } else {
1433             /* slow attack */
1434             alpha = drcComp->slowAttack[i];
1435           }
1436         } else {
1437           /* release */
1438           if (lvl2smthlvl < -drcComp->decayThr[i]) {
1439             /* fast release */
1440             alpha = drcComp->fastDecay[i];
1441           } else {
1442             /* slow release */
1443             alpha = drcComp->slowDecay[i];
1444           }
1445         }
1446 
1447         /* smooth gain & level */
1448         if ((gain < drcComp->smoothGain[i]) ||
1449             (drcComp->holdCnt[i] ==
1450              0)) { /* hold gain unless we have an attack or hold
1451                       period is over */
1452           FIXP_DBL accu;
1453 
1454           /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] +
1455            * alpha * level; */
1456           accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothLevel[i]);
1457           accu += fMult(alpha, level);
1458           drcComp->smoothLevel[i] = accu;
1459 
1460           /* drcComp->smoothGain[i]  = (1-alpha) * drcComp->smoothGain[i] +
1461            * alpha * gain; */
1462           accu = fMult(((FIXP_DBL)MAXVAL_DBL - alpha), drcComp->smoothGain[i]);
1463           accu += fMult(alpha, gain);
1464           drcComp->smoothGain[i] = accu;
1465         }
1466 
1467         /* hold counter */
1468         if (drcComp->holdCnt[i]) {
1469           drcComp->holdCnt[i]--;
1470         }
1471         if (gain < drcComp->smoothGain[i]) {
1472           drcComp->holdCnt[i] = drcComp->holdOff[i];
1473         }
1474       } /* profile != DRC_NONE */
1475     }   /* for i=1..2 */
1476   } else {
1477     /* no compression */
1478     drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
1479     drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
1480   }
1481 
1482   /**************************************************************************
1483    * limiter
1484    **************************************************************************/
1485 
1486   findPeakLevels(drcComp, inSamples, clev, slev, ext_leva, ext_levb, lfe_lev,
1487                  (FIXP_DBL)((LONG)(dmxGain5) << (METADATA_FRACT_BITS - 16)),
1488                  (FIXP_DBL)((LONG)(dmxGain2) << (METADATA_FRACT_BITS - 16)),
1489                  peak);
1490 
1491   for (i = 0; i < 2; i++) {
1492     FIXP_DBL tmp = drcComp->prevPeak[i];
1493     drcComp->prevPeak[i] = peak[i];
1494     peak[i] = fixMax(peak[i], tmp);
1495 
1496     /*
1497      * Convert to dBFS, apply dialnorm
1498      */
1499     /* descaled peak in ld64 representation */
1500     FIXP_DBL ld_peak =
1501         CalcLdData(peak[i]) +
1502         (FIXP_DBL)((LONG)DOWNMIX_SHIFT << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
1503 
1504     /* if (peak < 1e-6) level = 1e-6f; */
1505     ld_peak =
1506         fMax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
1507 
1508     /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f +
1509      * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 20 *
1510      * log(2)/log(10) * ld(peak[i]) + 0.2f +
1511      * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS) peak[i] = 10 *
1512      * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f +
1513      * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
1514      *
1515      *    additional scaling with METADATA_FRACT_BITS:
1516      * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64
1517      * + 0.2f +
1518      * (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
1519      * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) *
1520      * 2*0.30102999566398119521373889472449 * ld64(peak[i])
1521      *         + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
1522      */
1523     peak[i] = fMult(
1524         (FIXP_DBL)(10 << (METADATA_FRACT_BITS + LD_DATA_SHIFT)),
1525         fMult(FL2FX_DBL(2 * 0.30102999566398119521373889472449f), ld_peak));
1526     peak[i] +=
1527         (FL2FX_DBL(0.5f) >> METADATA_INT_BITS); /* add a little bit headroom */
1528     peak[i] += drcComp->smoothGain[i];
1529   }
1530 
1531   /* peak -= dialnorm + 31; */ /* this is Dolby style only */
1532   peak[0] -= (FIXP_DBL)((dialnorm - drc_TargetRefLevel)
1533                         << (METADATA_FRACT_BITS -
1534                             16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
1535 
1536   /* peak += 11; */
1537   /* this is Dolby style only */ /* RF mode output is 11dB higher */
1538   /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
1539   peak[1] -=
1540       (FIXP_DBL)((dialnorm - comp_TargetRefLevel)
1541                  << (METADATA_FRACT_BITS -
1542                      16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
1543 
1544   /* limiter gain */
1545   drcComp->limGain[0] += drcComp->limDecay; /* linear limiter release */
1546   drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
1547 
1548   drcComp->limGain[1] += 2 * drcComp->limDecay; /* linear limiter release */
1549   drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
1550 
1551   /*************************************************************************/
1552 
1553   /* apply limiting, return DRC gains*/
1554   {
1555     FIXP_DBL tmp;
1556 
1557     tmp = drcComp->smoothGain[0];
1558     if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
1559       tmp += drcComp->limGain[0];
1560     }
1561     *pDynrng = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
1562 
1563     tmp = drcComp->smoothGain[1];
1564     if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
1565       tmp += drcComp->limGain[1];
1566     }
1567     *pCompr = (LONG)scaleValue(tmp, -(METADATA_FRACT_BITS - 16));
1568   }
1569 
1570   return 0;
1571 }
1572 
FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)1573 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp) {
1574   return drcComp->profile[0];
1575 }
1576 
FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)1577 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp) {
1578   return drcComp->profile[1];
1579 }
1580