• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /**********************  Fraunhofer IIS FDK AAC Encoder lib  ******************
85 
86    Author(s): M. Neusinger
87    Description: Compressor for AAC Metadata Generator
88 
89 ******************************************************************************/
90 
91 
92 #include "metadata_compressor.h"
93 #include "channel_map.h"
94 
95 
96 #define LOG2                                    0.69314718056f  /* natural logarithm of 2 */
97 #define ILOG2                                   1.442695041f    /* 1/LOG2 */
98 #define FIXP_ILOG2_DIV2                         (FL2FXCONST_DBL(ILOG2/2))
99 
100 /*----------------- defines ----------------------*/
101 
102 #define MAX_DRC_CHANNELS        (8)          /*!< Max number of audio input channels. */
103 #define DOWNMIX_SHIFT           (3)          /*!< Max 8 channel. */
104 #define WEIGHTING_FILTER_SHIFT  (2)          /*!< Scaling used in weighting filter. */
105 
106 #define METADATA_INT_BITS      10
107 #define METADATA_LINT_BITS     20
108 #define METADATA_INT_SCALE     (INT64(1)<<(METADATA_INT_BITS))
109 #define METADATA_FRACT_BITS    (DFRACT_BITS-1-METADATA_INT_BITS)
110 #define METADATA_FRACT_SCALE   (INT64(1)<<(METADATA_FRACT_BITS))
111 
112 /**
113  *  Enum for channel assignment.
114  */
115 enum {
116     L   = 0,
117     R   = 1,
118     C   = 2,
119     LFE = 3,
120     LS  = 4,
121     RS  = 5,
122     S   = 6,
123     LS2 = 7,
124     RS2 = 8
125 };
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 
144     FIXP_DBL     maxBoostThr[2];             /*!< Max boost threshold. */
145     FIXP_DBL     boostThr[2];                /*!< Boost threshold. */
146     FIXP_DBL     earlyCutThr[2];             /*!< Early cut threshold. */
147     FIXP_DBL     cutThr[2];                  /*!< Cut threshold. */
148     FIXP_DBL     maxCutThr[2];               /*!< Max cut threshold. */
149 
150     FIXP_DBL     boostFac[2];                /*!< Precalculated factor for boost compression. */
151     FIXP_DBL     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, Ls, Rs, S, Ls2, Rs2). */
177 
178     FIXP_DBL     smoothLevel[2];             /*!< level smoothing states */
179     FIXP_DBL     smoothGain[2];              /*!< gain smoothing states */
180     UINT         holdCnt[2];                 /*!< hold counter */
181 
182     FIXP_DBL     limGain[2];                 /*!< limiter gain */
183     FIXP_DBL     limDecay;                   /*!< limiter decay (linear) */
184     FIXP_DBL     prevPeak[2];                /*!< max peak of previous block (stereo/mono)*/
185 
186     WEIGHTING_STATES filter[MAX_DRC_CHANNELS]; /*!< array holds weighting filter states */
187 
188 };
189 
190 /*---------------- constants -----------------------*/
191 
192 /**
193  *  Profile tables.
194  */
195 static const FIXP_DBL tabMaxBoostThr[] = {
196     (FIXP_DBL)(-43<<METADATA_FRACT_BITS),
197     (FIXP_DBL)(-53<<METADATA_FRACT_BITS),
198     (FIXP_DBL)(-55<<METADATA_FRACT_BITS),
199     (FIXP_DBL)(-65<<METADATA_FRACT_BITS),
200     (FIXP_DBL)(-50<<METADATA_FRACT_BITS),
201     (FIXP_DBL)(-40<<METADATA_FRACT_BITS)
202 };
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 };
211 static const FIXP_DBL tabEarlyCutThr[] = {
212     (FIXP_DBL)(-26<<METADATA_FRACT_BITS),
213     (FIXP_DBL)(-21<<METADATA_FRACT_BITS),
214     (FIXP_DBL)(-26<<METADATA_FRACT_BITS),
215     (FIXP_DBL)(-21<<METADATA_FRACT_BITS),
216     (FIXP_DBL)(-26<<METADATA_FRACT_BITS),
217     (FIXP_DBL)(-20<<METADATA_FRACT_BITS)
218 };
219 static const FIXP_DBL tabCutThr[]      = {
220     (FIXP_DBL)(-16<<METADATA_FRACT_BITS),
221     (FIXP_DBL)(-11<<METADATA_FRACT_BITS),
222     (FIXP_DBL)(-16<<METADATA_FRACT_BITS),
223     (FIXP_DBL)(-21<<METADATA_FRACT_BITS),
224     (FIXP_DBL)(-16<<METADATA_FRACT_BITS),
225     (FIXP_DBL)(-10<<METADATA_FRACT_BITS)
226 };
227 static const FIXP_DBL tabMaxCutThr[]   = {
228     (FIXP_DBL)(4<<METADATA_FRACT_BITS),
229     (FIXP_DBL)(9<<METADATA_FRACT_BITS),
230     (FIXP_DBL)(4<<METADATA_FRACT_BITS),
231     (FIXP_DBL)(9<<METADATA_FRACT_BITS),
232     (FIXP_DBL)(4<<METADATA_FRACT_BITS),
233     (FIXP_DBL)(4<<METADATA_FRACT_BITS)
234 };
235 static const FIXP_DBL tabBoostRatio[] = {
236     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
237     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
238     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
239     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
240     FL2FXCONST_DBL( ((1.f/5.f) - 1.f) ),
241     FL2FXCONST_DBL( ((1.f/5.f) - 1.f) )
242 };
243 static const FIXP_DBL tabEarlyCutRatio[] = {
244     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
245     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
246     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
247     FL2FXCONST_DBL( ((1.f/1.f) - 1.f) ),
248     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) ),
249     FL2FXCONST_DBL( ((1.f/2.f) - 1.f) )
250 };
251 static const FIXP_DBL tabCutRatio[]      = {
252     FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ),
253     FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ),
254     FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ),
255     FL2FXCONST_DBL( ((1.f/ 2.f) - 1.f) ),
256     FL2FXCONST_DBL( ((1.f/20.f) - 1.f) ),
257     FL2FXCONST_DBL( ((1.f/20.f) - 1.f) )
258 };
259 static const FIXP_DBL tabMaxBoost[] = {
260     (FIXP_DBL)( 6<<METADATA_FRACT_BITS),
261     (FIXP_DBL)( 6<<METADATA_FRACT_BITS),
262     (FIXP_DBL)(12<<METADATA_FRACT_BITS),
263     (FIXP_DBL)(12<<METADATA_FRACT_BITS),
264     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
265     (FIXP_DBL)(15<<METADATA_FRACT_BITS)
266 };
267 static const FIXP_DBL tabMaxCut[]   = {
268     (FIXP_DBL)(24<<METADATA_FRACT_BITS),
269     (FIXP_DBL)(24<<METADATA_FRACT_BITS),
270     (FIXP_DBL)(24<<METADATA_FRACT_BITS),
271     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
272     (FIXP_DBL)(24<<METADATA_FRACT_BITS),
273     (FIXP_DBL)(24<<METADATA_FRACT_BITS)
274 };
275 static const FIXP_DBL tabFastAttack[] = {
276     FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE),
277     FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE),
278     FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE),
279     FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE),
280     FL2FXCONST_DBL((10.f/1000.f)/METADATA_INT_SCALE),
281     FL2FXCONST_DBL( (0.f/1000.f)/METADATA_INT_SCALE)
282 };
283 static const FIXP_DBL tabFastDecay[]  = {
284     FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE),
285     FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE),
286     FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE),
287     FL2FXCONST_DBL((1000.f/1000.f)/METADATA_INT_SCALE),
288     FL2FXCONST_DBL( (200.f/1000.f)/METADATA_INT_SCALE),
289     FL2FXCONST_DBL(   (0.f/1000.f)/METADATA_INT_SCALE)
290 };
291 static const FIXP_DBL tabSlowAttack[] = {
292     FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE),
293     FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE),
294     FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE),
295     FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE),
296     FL2FXCONST_DBL((100.f/1000.f)/METADATA_INT_SCALE),
297     FL2FXCONST_DBL(  (0.f/1000.f)/METADATA_INT_SCALE)
298 };
299 static const FIXP_DBL tabSlowDecay[]  = {
300     FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE),
301     FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE),
302     FL2FXCONST_DBL((10000.f/1000.f)/METADATA_INT_SCALE),
303     FL2FXCONST_DBL( (3000.f/1000.f)/METADATA_INT_SCALE),
304     FL2FXCONST_DBL( (1000.f/1000.f)/METADATA_INT_SCALE),
305     FL2FXCONST_DBL(    (0.f/1000.f)/METADATA_INT_SCALE)
306 };
307 
308 static const INT tabHoldOff[]    = { 10, 10, 10, 10, 10, 0 };
309 
310 static const FIXP_DBL tabAttackThr[] = {
311     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
312     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
313     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
314     (FIXP_DBL)(15<<METADATA_FRACT_BITS),
315     (FIXP_DBL)(10<<METADATA_FRACT_BITS),
316     (FIXP_DBL)(0<<METADATA_FRACT_BITS)
317 };
318 static const FIXP_DBL tabDecayThr[]  = {
319     (FIXP_DBL)(20<<METADATA_FRACT_BITS),
320     (FIXP_DBL)(20<<METADATA_FRACT_BITS),
321     (FIXP_DBL)(20<<METADATA_FRACT_BITS),
322     (FIXP_DBL)(20<<METADATA_FRACT_BITS),
323     (FIXP_DBL)(10<<METADATA_FRACT_BITS),
324     (FIXP_DBL)( 0<<METADATA_FRACT_BITS)
325 };
326 
327 /**
328  *  Weighting filter coefficients (biquad bandpass).
329  */
330 static const FIXP_DBL b0 = FL2FXCONST_DBL(0.53050662f);                                      /* b1 = 0, b2 = -b0 */
331 static const FIXP_DBL a1 = FL2FXCONST_DBL(-0.95237983f), a2 = FL2FXCONST_DBL(-0.02248836f);  /* a0 = 1 */
332 
333 
334 /*------------- function definitions ----------------*/
335 
336 /**
337  * \brief  Calculate scaling factor for denoted processing block.
338  *
339  * \param blockLength   Length of processing block.
340  *
341  * \return    shiftFactor
342  */
getShiftFactor(const UINT length)343 static UINT getShiftFactor(
344         const UINT                length
345         )
346 {
347     UINT ldN;
348     for(ldN=1;(((UINT)1)<<ldN) < length;ldN++);
349 
350     return ldN;
351 }
352 
353 /**
354  * \brief  Sum up fixpoint values with best possible accuracy.
355  *
356  * \param value1        First input value.
357  * \param q1            Scaling factor of first input value.
358  * \param pValue2       Pointer to second input value, will be modified on return.
359  * \param pQ2           Pointer to second scaling factor, will be modified on return.
360  *
361  * \return    void
362  */
fixpAdd(const FIXP_DBL value1,const int q1,FIXP_DBL * const pValue2,int * const pQ2)363 static void fixpAdd(
364         const FIXP_DBL                  value1,
365         const int                       q1,
366         FIXP_DBL *const                 pValue2,
367         int *const                      pQ2
368         )
369 {
370   const int headroom1 = fNormz(fixp_abs(value1))-1;
371   const int headroom2 = fNormz(fixp_abs(*pValue2))-1;
372   int resultScale = fixMax(q1-headroom1, (*pQ2)-headroom2);
373 
374   if ( (value1!=FL2FXCONST_DBL(0.f)) && (*pValue2!=FL2FXCONST_DBL(0.f)) ) {
375     resultScale++;
376   }
377 
378   *pValue2 = scaleValue(value1, q1-resultScale) + scaleValue(*pValue2, (*pQ2)-resultScale);
379   *pQ2 = (*pValue2!=(FIXP_DBL)0) ? resultScale : DFRACT_BITS-1;
380 }
381 
382 /**
383  * \brief  Function for converting time constant to filter coefficient.
384  *
385  * \param t             Time constant.
386  * \param sampleRate    Sampling rate in Hz.
387  * \param blockLength   Length of processing block in samples per channel.
388  *
389  * \return    result = 1.0 - exp(-1.0/((t) * (f)))
390  */
tc2Coeff(const FIXP_DBL t,const INT sampleRate,const INT blockLength)391 static FIXP_DBL tc2Coeff(
392         const FIXP_DBL            t,
393         const INT                 sampleRate,
394         const INT                 blockLength
395         )
396 {
397    FIXP_DBL sampleRateFract;
398    FIXP_DBL blockLengthFract;
399    FIXP_DBL f, product;
400    FIXP_DBL exponent, result;
401    INT e_res;
402 
403    /* f = sampleRate/blockLength */
404    sampleRateFract = (FIXP_DBL)(sampleRate<<(DFRACT_BITS-1-METADATA_LINT_BITS));
405    blockLengthFract = (FIXP_DBL)(blockLength<<(DFRACT_BITS-1-METADATA_LINT_BITS));
406    f = fDivNorm(sampleRateFract, blockLengthFract, &e_res);
407    f = scaleValue(f, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */
408 
409    /* product = t*f */
410    product = fMultNorm(t, f, &e_res);
411    product = scaleValue(product, e_res+METADATA_INT_BITS); /* convert to METADATA_FRACT */
412 
413    /* exponent = (-1.0/((t) * (f))) */
414    exponent = fDivNorm(METADATA_FRACT_SCALE, product, &e_res);
415    exponent = scaleValue(exponent, e_res-METADATA_INT_BITS); /* convert to METADATA_FRACT */
416 
417    /* exponent * ld(e) */
418    exponent = fMult(exponent,FIXP_ILOG2_DIV2)<<1; /* e^(x) = 2^(x*ld(e)) */
419 
420    /* exp(-1.0/((t) * (f))) */
421    result = f2Pow(-exponent, DFRACT_BITS-1-METADATA_FRACT_BITS, &e_res);
422 
423    /* result = 1.0 - exp(-1.0/((t) * (f))) */
424    result = (FIXP_DBL)MAXVAL_DBL - scaleValue(result, e_res);
425 
426    return result;
427 }
428 
FDK_DRC_Generator_Open(HDRC_COMP * phDrcComp)429 INT FDK_DRC_Generator_Open(
430         HDRC_COMP                      *phDrcComp
431         )
432 {
433     INT err = 0;
434     HDRC_COMP hDcComp = NULL;
435 
436     if (phDrcComp == NULL) {
437       err = -1;
438       goto bail;
439     }
440 
441     /* allocate memory */
442     hDcComp = (HDRC_COMP)FDKcalloc(1, sizeof(DRC_COMP));
443 
444     if (hDcComp == NULL) {
445       err = -1;
446       goto bail;
447     }
448 
449     FDKmemclear(hDcComp, sizeof(DRC_COMP));
450 
451     /* Return drc compressor instance */
452     *phDrcComp = hDcComp;
453     return err;
454 bail:
455     FDK_DRC_Generator_Close(&hDcComp);
456     return err;
457 }
458 
FDK_DRC_Generator_Close(HDRC_COMP * phDrcComp)459 INT FDK_DRC_Generator_Close(
460         HDRC_COMP                      *phDrcComp
461         )
462 {
463     if (phDrcComp == NULL) {
464       return -1;
465     }
466     if (*phDrcComp != NULL) {
467       FDKfree(*phDrcComp);
468       *phDrcComp = NULL;
469     }
470     return 0;
471 }
472 
473 
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)474 INT FDK_DRC_Generator_Initialize(
475         HDRC_COMP                       drcComp,
476         const DRC_PROFILE               profileLine,
477         const DRC_PROFILE               profileRF,
478         const INT                       blockLength,
479         const UINT                      sampleRate,
480         const CHANNEL_MODE              channelMode,
481         const CHANNEL_ORDER             channelOrder,
482         const UCHAR                     useWeighting
483         )
484 {
485     int i;
486     CHANNEL_MAPPING channelMapping;
487 
488     drcComp->limDecay = FL2FXCONST_DBL( ((0.006f / 256) * blockLength) / METADATA_INT_SCALE );
489 
490     /* Save parameters. */
491     drcComp->blockLength = blockLength;
492     drcComp->sampleRate  = sampleRate;
493     drcComp->chanConfig = channelMode;
494     drcComp->useWeighting = useWeighting;
495 
496     if (FDK_DRC_Generator_setDrcProfile(drcComp, profileLine, profileRF)!=0) { /* expects initialized blockLength and sampleRate */
497       return (-1);
498     }
499 
500     /* Set number of channels and channel offsets. */
501     if (FDKaacEnc_InitChannelMapping(channelMode, channelOrder, &channelMapping)!=AAC_ENC_OK) {
502       return (-2);
503     }
504 
505     for (i = 0; i < 9; i++) drcComp->channelIdx[i] = -1;
506 
507     switch (channelMode) {
508     case MODE_1: /* mono */
509         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
510         break;
511     case MODE_2: /* stereo */
512         drcComp->channelIdx[L]   = channelMapping.elInfo[0].ChannelIndex[0];
513         drcComp->channelIdx[R]   = channelMapping.elInfo[0].ChannelIndex[1];
514         break;
515     case MODE_1_2: /* 3ch */
516         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0];
517         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1];
518         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
519         break;
520     case MODE_1_2_1: /* 4ch */
521         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0];
522         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1];
523         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
524         drcComp->channelIdx[S]   = channelMapping.elInfo[2].ChannelIndex[0];
525         break;
526     case MODE_1_2_2: /* 5ch */
527         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0];
528         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1];
529         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
530         drcComp->channelIdx[LS]  = channelMapping.elInfo[2].ChannelIndex[0];
531         drcComp->channelIdx[RS]  = channelMapping.elInfo[2].ChannelIndex[1];
532         break;
533     case MODE_1_2_2_1:  /* 5.1 ch */
534         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0];
535         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1];
536         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
537         drcComp->channelIdx[LFE] = channelMapping.elInfo[3].ChannelIndex[0];
538         drcComp->channelIdx[LS]  = channelMapping.elInfo[2].ChannelIndex[0];
539         drcComp->channelIdx[RS]  = channelMapping.elInfo[2].ChannelIndex[1];
540         break;
541     case MODE_1_2_2_2_1: /* 7.1 ch */
542     case MODE_7_1_FRONT_CENTER:
543         drcComp->channelIdx[L]   = channelMapping.elInfo[2].ChannelIndex[0]; /* l */
544         drcComp->channelIdx[R]   = channelMapping.elInfo[2].ChannelIndex[1]; /* r */
545         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
546         drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
547         drcComp->channelIdx[LS]  = channelMapping.elInfo[3].ChannelIndex[0]; /* ls */
548         drcComp->channelIdx[RS]  = channelMapping.elInfo[3].ChannelIndex[1]; /* rs */
549         drcComp->channelIdx[LS2] = channelMapping.elInfo[1].ChannelIndex[0]; /* lc */
550         drcComp->channelIdx[RS2] = channelMapping.elInfo[1].ChannelIndex[1]; /* rc */
551         break;
552     case MODE_7_1_REAR_SURROUND:
553         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0]; /* l */
554         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1]; /* r */
555         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0]; /* c */
556         drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0]; /* lfe */
557         drcComp->channelIdx[LS]  = channelMapping.elInfo[3].ChannelIndex[0]; /* lrear */
558         drcComp->channelIdx[RS]  = channelMapping.elInfo[3].ChannelIndex[1]; /* rrear */
559         drcComp->channelIdx[LS2] = channelMapping.elInfo[2].ChannelIndex[0]; /* ls */
560         drcComp->channelIdx[RS2] = channelMapping.elInfo[2].ChannelIndex[1]; /* rs */
561         break;
562     case MODE_1_1:
563     case MODE_1_1_1_1:
564     case MODE_1_1_1_1_1_1:
565     case MODE_1_1_1_1_1_1_1_1:
566     case MODE_1_1_1_1_1_1_1_1_1_1_1_1:
567     case MODE_2_2:
568     case MODE_2_2_2:
569     case MODE_2_2_2_2:
570     case MODE_2_2_2_2_2_2:
571     default:
572         return (-1);
573     }
574 
575     drcComp->fullChannels = channelMapping.nChannelsEff;
576     drcComp->channels     = channelMapping.nChannels;
577 
578     /* Init states. */
579     drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS);
580 
581     FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
582     FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
583     FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
584     FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
585     FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
586 
587     return (0);
588 }
589 
590 
FDK_DRC_Generator_setDrcProfile(HDRC_COMP drcComp,const DRC_PROFILE profileLine,const DRC_PROFILE profileRF)591 INT FDK_DRC_Generator_setDrcProfile(
592         HDRC_COMP                       drcComp,
593         const DRC_PROFILE               profileLine,
594         const DRC_PROFILE               profileRF
595         )
596 {
597     int profileIdx, i;
598 
599     drcComp->profile[0] = profileLine;
600     drcComp->profile[1] = profileRF;
601 
602     for (i = 0; i < 2; i++) {
603         /* get profile index */
604         switch (drcComp->profile[i]) {
605             case DRC_NONE:
606             case DRC_FILMSTANDARD:  profileIdx = 0; break;
607             case DRC_FILMLIGHT:     profileIdx = 1; break;
608             case DRC_MUSICSTANDARD: profileIdx = 2; break;
609             case DRC_MUSICLIGHT:    profileIdx = 3; break;
610             case DRC_SPEECH:        profileIdx = 4; break;
611             case DRC_DELAY_TEST:    profileIdx = 5; break;
612             default: return (-1);
613         }
614 
615         /* get parameters for selected profile */
616         if (profileIdx >= 0) {
617             drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
618             drcComp->boostThr[i]    = tabBoostThr[profileIdx];
619             drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
620             drcComp->cutThr[i]      = tabCutThr[profileIdx];
621             drcComp->maxCutThr[i]   = tabMaxCutThr[profileIdx];
622 
623             drcComp->boostFac[i]    = tabBoostRatio[profileIdx];
624             drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
625             drcComp->cutFac[i]      = tabCutRatio[profileIdx];
626 
627             drcComp->maxBoost[i]    = tabMaxBoost[profileIdx];
628             drcComp->maxCut[i]      = tabMaxCut[profileIdx];
629             drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */
630 
631             drcComp->fastAttack[i]  = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
632             drcComp->fastDecay[i]   = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
633             drcComp->slowAttack[i]  = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
634             drcComp->slowDecay[i]   = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
635             drcComp->holdOff[i]     = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
636 
637             drcComp->attackThr[i]   = tabAttackThr[profileIdx];
638             drcComp->decayThr[i]    = tabDecayThr[profileIdx];
639         }
640 
641         drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
642     }
643     return (0);
644 }
645 
646 
FDK_DRC_Generator_Calc(HDRC_COMP drcComp,const INT_PCM * const inSamples,const INT dialnorm,const INT drc_TargetRefLevel,const INT comp_TargetRefLevel,FIXP_DBL clev,FIXP_DBL slev,INT * const pDynrng,INT * const pCompr)647 INT FDK_DRC_Generator_Calc(
648         HDRC_COMP                       drcComp,
649         const INT_PCM * const           inSamples,
650         const INT                       dialnorm,
651         const INT                       drc_TargetRefLevel,
652         const INT                       comp_TargetRefLevel,
653         FIXP_DBL                        clev,
654         FIXP_DBL                        slev,
655         INT * const                     pDynrng,
656         INT * const                     pCompr
657         )
658 {
659     int i, c;
660     FIXP_DBL peak[2];
661 
662 
663     /**************************************************************************
664     * compressor
665     **************************************************************************/
666       if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
667         /* Calc loudness level */
668         FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
669         int      level_e = DFRACT_BITS-1;
670 
671         /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */
672         const int granuleLength = fixMin(32, drcComp->blockLength);
673 
674         if (drcComp->useWeighting) {
675             FIXP_DBL x1, x2, y, y1, y2;
676             /* sum of filter coefficients about 2.5 -> squared value is 6.25
677                WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1.
678              */
679             const int granuleShift = getShiftFactor(granuleLength)-1;
680 
681             for (c = 0; c < (int)drcComp->channels; c++) {
682                 const INT_PCM* pSamples = &inSamples[c];
683 
684                 if (c == drcComp->channelIdx[LFE]) {
685                   continue;  /* skip LFE */
686                 }
687 
688                 /* get filter states */
689                 x1 = drcComp->filter[c].x1;
690                 x2 = drcComp->filter[c].x2;
691                 y1 = drcComp->filter[c].y1;
692                 y2 = drcComp->filter[c].y2;
693 
694                 i = 0;
695 
696                 do {
697 
698                   int offset = i;
699                   FIXP_DBL accu = FL2FXCONST_DBL(0.f);
700 
701                   for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
702                     /* apply weighting filter */
703                     FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT;
704 
705                     /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
706                     y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2);
707 
708                     x2 = x1;
709                     x1 = x;
710                     y2 = y1;
711                     y1 = y;
712 
713                     accu += fPow2Div2(y)>>(granuleShift-1);     /* partial energy */
714                   } /* i */
715 
716                   fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */
717 
718                 } while ( i < drcComp->blockLength );
719 
720 
721                 /* save filter states */
722                 drcComp->filter[c].x1 = x1;
723                 drcComp->filter[c].x2 = x2;
724                 drcComp->filter[c].y1 = y1;
725                 drcComp->filter[c].y2 = y2;
726             } /* c */
727         } /* weighting */
728         else {
729             const int granuleShift = getShiftFactor(granuleLength);
730 
731             for (c = 0; c < (int)drcComp->channels; c++) {
732                 const INT_PCM* pSamples = &inSamples[c];
733 
734                 if ((int)c == drcComp->channelIdx[LFE]) {
735                   continue;  /* skip LFE */
736                 }
737 
738                 i = 0;
739 
740                 do {
741                   int offset = i;
742                   FIXP_DBL accu = FL2FXCONST_DBL(0.f);
743 
744                   for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
745                     /* partial energy */
746                     accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1);
747                   } /* i */
748 
749                   fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */
750 
751                 } while ( i < drcComp->blockLength );
752             }
753         } /* weighting */
754 
755         /*
756          * Convert to dBFS, apply dialnorm
757          */
758         /* level scaling */
759 
760         /* descaled level in ld64 representation */
761         FIXP_DBL ldLevel = CalcLdData(level_b) + (FIXP_DBL)((level_e-12)<<(DFRACT_BITS-1-LD_DATA_SHIFT)) - CalcLdData((FIXP_DBL)(drcComp->blockLength<<(DFRACT_BITS-1-12)));
762 
763         /* if (level < 1e-10) level = 1e-10f; */
764         ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
765 
766         /* level = 10 * log(level)/log(10) + 3;
767          *       = 10*log(2)/log(10) * ld(level) + 3;
768          *       = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
769          *       = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
770          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64
771          *
772          *    additional scaling with METADATA_FRACT_BITS:
773          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS)
774          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT)
775          *       = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
776          * */
777         FIXP_DBL level = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FXCONST_DBL(0.30102999566398119521373889472449f), ldLevel) + (FIXP_DBL)(FL2FXCONST_DBL(0.3f)>>LD_DATA_SHIFT) );
778 
779         /* level -= dialnorm + 31 */   /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */
780         level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16))  + (FIXP_DBL)(31<<METADATA_FRACT_BITS));
781 
782         for (i = 0; i < 2; i++) {
783             if (drcComp->profile[i] == DRC_NONE) {
784                 /* no compression */
785                 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
786             }
787             else {
788                 FIXP_DBL gain, alpha, lvl2smthlvl;
789 
790                 /* calc static gain */
791                 if (level <= drcComp->maxBoostThr[i]) {
792                     /* max boost */
793                     gain = drcComp->maxBoost[i];
794                 }
795                 else if (level < drcComp->boostThr[i]) {
796                     /* boost range */
797                     gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]);
798                 }
799                 else if (level <= drcComp->earlyCutThr[i]) {
800                     /* null band */
801                     gain = FL2FXCONST_DBL(0.f);
802                 }
803                 else if (level <= drcComp->cutThr[i]) {
804                     /* early cut range */
805                     gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
806                 }
807                 else if (level < drcComp->maxCutThr[i]) {
808                     /* cut range */
809                     gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i];
810                 }
811                 else {
812                     /* max cut */
813                     gain = -drcComp->maxCut[i];
814                 }
815 
816                 /* choose time constant */
817                 lvl2smthlvl = level - drcComp->smoothLevel[i];
818                 if (gain < drcComp->smoothGain[i]) {
819                     /* attack */
820                     if (lvl2smthlvl > drcComp->attackThr[i]) {
821                         /* fast attack */
822                         alpha = drcComp->fastAttack[i];
823                     }
824                     else {
825                         /* slow attack */
826                         alpha = drcComp->slowAttack[i];
827                     }
828                 }
829                 else {
830                     /* release */
831                     if (lvl2smthlvl < -drcComp->decayThr[i]) {
832                         /* fast release */
833                         alpha = drcComp->fastDecay[i];
834                     }
835                     else {
836                         /* slow release */
837                         alpha = drcComp->slowDecay[i];
838                     }
839                 }
840 
841                 /* smooth gain & level */
842                 if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */
843                     FIXP_DBL accu;
844 
845                     /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */
846                     accu =  fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothLevel[i]);
847                     accu += fMult(alpha,level);
848                     drcComp->smoothLevel[i] = accu;
849 
850                     /* drcComp->smoothGain[i]  = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */
851                     accu =  fMult(((FIXP_DBL)MAXVAL_DBL-alpha), drcComp->smoothGain[i]);
852                     accu += fMult(alpha,gain);
853                     drcComp->smoothGain[i] = accu;
854                 }
855 
856                 /* hold counter */
857                 if (drcComp->holdCnt[i]) {
858                   drcComp->holdCnt[i]--;
859                 }
860                 if (gain < drcComp->smoothGain[i]) {
861                   drcComp->holdCnt[i] = drcComp->holdOff[i];
862                 }
863             } /* profile != DRC_NONE */
864         } /* for i=1..2 */
865       } else {
866         /* no compression */
867         drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
868         drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
869       }
870 
871     /**************************************************************************
872     * limiter
873     **************************************************************************/
874 
875     /* find peak level */
876     peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
877     for (i = 0; i < drcComp->blockLength; i++) {
878         FIXP_DBL tmp;
879         const INT_PCM* pSamples = &inSamples[i*drcComp->channels];
880         INT_PCM maxSample = 0;
881 
882         /* single channels */
883         for (c = 0; c < (int)drcComp->channels; c++) {
884             maxSample = FDKmax(maxSample, fAbs(pSamples[c]));
885         }
886         peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT);
887 
888         /* Lt/Rt downmix */
889         if (drcComp->fullChannels > 2) {
890             /* Lt */
891             tmp = FL2FXCONST_DBL(0.f);
892 
893             if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);          /* Ls */
894             if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);        /* Ls2 */
895             if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);          /* Rs */
896             if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);        /* Rs2 */
897             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
898             if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1);            /* S */
899             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);            /* C */
900             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
901 
902             peak[0] = fixMax(peak[0], fixp_abs(tmp));
903 
904             /* Rt */
905             tmp = FL2FXCONST_DBL(0.f);
906             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);          /* Ls */
907             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);        /* Ls2 */
908             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);          /* Rs */
909             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);        /* Rs2 */
910             if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
911             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1);            /* S */
912             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);            /* C */
913             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
914 
915             peak[0] = fixMax(peak[0], fixp_abs(tmp));
916         }
917 
918         /* Lo/Ro downmix */
919         if (drcComp->fullChannels > 2) {
920             /* Lo */
921             tmp = FL2FXCONST_DBL(0.f);
922             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);                            /* Ls */
923             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);                          /* Ls2 */
924             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
925             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
926             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);                              /* C */
927             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
928 
929             peak[0] = fixMax(peak[0], fixp_abs(tmp));
930 
931             /* Ro */
932             tmp = FL2FXCONST_DBL(0.f);
933             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);                            /* Rs */
934             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);                          /* Rs2 */
935             if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
936             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
937             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);                              /* C */
938             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
939 
940             peak[0] = fixMax(peak[0], fixp_abs(tmp));
941         }
942 
943         peak[1] = fixMax(peak[0], peak[1]);
944 
945         /* Mono Downmix - for comp_val only */
946         if (drcComp->fullChannels > 1) {
947             tmp = FL2FXCONST_DBL(0.f);
948             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);                            /* Ls */
949             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);                          /* Ls2 */
950             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);                            /* Rs */
951             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);                          /* Rs2 */
952             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
953             /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/                                                             /* 7.1ch */
954             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
955             if (drcComp->channelIdx[C] >= 0) tmp += fMult(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);                                  /* C (2*clev) */
956             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
957             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
958 
959             peak[1] = fixMax(peak[1], fixp_abs(tmp));
960         }
961     }
962 
963     for (i=0; i<2; i++) {
964       FIXP_DBL tmp = drcComp->prevPeak[i];
965       drcComp->prevPeak[i] = peak[i];
966       peak[i] = fixMax(peak[i], tmp);
967 
968       /*
969        * Convert to dBFS, apply dialnorm
970        */
971       /* descaled peak in ld64 representation */
972       FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT));
973 
974       /* if (peak < 1e-6) level = 1e-6f; */
975       ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
976 
977       /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
978        * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
979        * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
980        *
981        *    additional scaling with METADATA_FRACT_BITS:
982        * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
983        * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i])
984        *         + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
985        */
986       peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak));
987       peak[i] += (FL2FX_DBL(0.5f)>>METADATA_INT_BITS);           /* add a little bit headroom */
988       peak[i] +=  drcComp->smoothGain[i];
989     }
990 
991     /* peak -= dialnorm + 31; */  /* this is Dolby style only */
992     peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
993 
994     /* peak += 11; */   /* this is Dolby style only */      /* RF mode output is 11dB higher */
995     /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
996     peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
997 
998     /* limiter gain */
999     drcComp->limGain[0] += drcComp->limDecay;               /* linear limiter release */
1000     drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
1001 
1002     drcComp->limGain[1] += 2*drcComp->limDecay;             /* linear limiter release */
1003     drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
1004 
1005     /*************************************************************************/
1006 
1007     /* apply limiting, return DRC gains*/
1008     {
1009         FIXP_DBL tmp;
1010 
1011         tmp = drcComp->smoothGain[0];
1012         if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
1013           tmp += drcComp->limGain[0];
1014         }
1015         *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1016 
1017         tmp = drcComp->smoothGain[1];
1018         if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
1019           tmp += drcComp->limGain[1];
1020         }
1021         *pCompr  = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
1022     }
1023 
1024     return 0;
1025 }
1026 
1027 
FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)1028 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)
1029 {
1030     return drcComp->profile[0];
1031 }
1032 
FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)1033 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)
1034 {
1035     return drcComp->profile[1];
1036 }
1037 
1038 
1039