Home | History | Annotate | Download | only in src
      1 
      2 /* -----------------------------------------------------------------------------------------------------------
      3 Software License for The Fraunhofer FDK AAC Codec Library for Android
      4 
      5  Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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  */
    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  */
    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  */
    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 
    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 
    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 
    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 
    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 
    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 
   1028 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)
   1029 {
   1030     return drcComp->profile[0];
   1031 }
   1032 
   1033 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)
   1034 {
   1035     return drcComp->profile[1];
   1036 }
   1037 
   1038 
   1039