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 - 2012 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 = FL2FXCONST_DBL(1.0f) - 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         drcComp->channelIdx[L]   = channelMapping.elInfo[1].ChannelIndex[0];
    543         drcComp->channelIdx[R]   = channelMapping.elInfo[1].ChannelIndex[1];
    544         drcComp->channelIdx[C]   = channelMapping.elInfo[0].ChannelIndex[0];
    545         drcComp->channelIdx[LFE] = channelMapping.elInfo[4].ChannelIndex[0];
    546         drcComp->channelIdx[LS]  = channelMapping.elInfo[2].ChannelIndex[0];
    547         drcComp->channelIdx[RS]  = channelMapping.elInfo[2].ChannelIndex[1];
    548         drcComp->channelIdx[LS2] = channelMapping.elInfo[3].ChannelIndex[0];
    549         drcComp->channelIdx[RS2] = channelMapping.elInfo[3].ChannelIndex[1];
    550         break;
    551     case MODE_1_1:
    552     case MODE_1_1_1_1:
    553     case MODE_1_1_1_1_1_1:
    554     case MODE_1_1_1_1_1_1_1_1:
    555     case MODE_1_1_1_1_1_1_1_1_1_1_1_1:
    556     case MODE_2_2:
    557     case MODE_2_2_2:
    558     case MODE_2_2_2_2:
    559     case MODE_2_2_2_2_2_2:
    560     default:
    561         return (-1);
    562     }
    563 
    564     drcComp->fullChannels = channelMapping.nChannelsEff;
    565     drcComp->channels     = channelMapping.nChannels;
    566 
    567     /* Init states. */
    568     drcComp->smoothLevel[0] = drcComp->smoothLevel[1] = (FIXP_DBL)(-135<<METADATA_FRACT_BITS);
    569 
    570     FDKmemclear(drcComp->smoothGain, sizeof(drcComp->smoothGain));
    571     FDKmemclear(drcComp->holdCnt, sizeof(drcComp->holdCnt));
    572     FDKmemclear(drcComp->limGain, sizeof(drcComp->limGain));
    573     FDKmemclear(drcComp->prevPeak, sizeof(drcComp->prevPeak));
    574     FDKmemclear(drcComp->filter, sizeof(drcComp->filter));
    575 
    576     return (0);
    577 }
    578 
    579 
    580 INT FDK_DRC_Generator_setDrcProfile(
    581         HDRC_COMP                       drcComp,
    582         const DRC_PROFILE               profileLine,
    583         const DRC_PROFILE               profileRF
    584         )
    585 {
    586     int profileIdx, i;
    587 
    588     drcComp->profile[0] = profileLine;
    589     drcComp->profile[1] = profileRF;
    590 
    591     for (i = 0; i < 2; i++) {
    592         /* get profile index */
    593         switch (drcComp->profile[i]) {
    594             case DRC_NONE:
    595             case DRC_FILMSTANDARD:  profileIdx = 0; break;
    596             case DRC_FILMLIGHT:     profileIdx = 1; break;
    597             case DRC_MUSICSTANDARD: profileIdx = 2; break;
    598             case DRC_MUSICLIGHT:    profileIdx = 3; break;
    599             case DRC_SPEECH:        profileIdx = 4; break;
    600             case DRC_DELAY_TEST:    profileIdx = 5; break;
    601             default: return (-1);
    602         }
    603 
    604         /* get parameters for selected profile */
    605         if (profileIdx >= 0) {
    606             drcComp->maxBoostThr[i] = tabMaxBoostThr[profileIdx];
    607             drcComp->boostThr[i]    = tabBoostThr[profileIdx];
    608             drcComp->earlyCutThr[i] = tabEarlyCutThr[profileIdx];
    609             drcComp->cutThr[i]      = tabCutThr[profileIdx];
    610             drcComp->maxCutThr[i]   = tabMaxCutThr[profileIdx];
    611 
    612             drcComp->boostFac[i]    = tabBoostRatio[profileIdx];
    613             drcComp->earlyCutFac[i] = tabEarlyCutRatio[profileIdx];
    614             drcComp->cutFac[i]      = tabCutRatio[profileIdx];
    615 
    616             drcComp->maxBoost[i]    = tabMaxBoost[profileIdx];
    617             drcComp->maxCut[i]      = tabMaxCut[profileIdx];
    618             drcComp->maxEarlyCut[i] = - fMult((drcComp->cutThr[i] - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]); /* no scaling after mult needed, earlyCutFac is in FIXP_DBL */
    619 
    620             drcComp->fastAttack[i]  = tc2Coeff(tabFastAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
    621             drcComp->fastDecay[i]   = tc2Coeff(tabFastDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
    622             drcComp->slowAttack[i]  = tc2Coeff(tabSlowAttack[profileIdx], drcComp->sampleRate, drcComp->blockLength);
    623             drcComp->slowDecay[i]   = tc2Coeff(tabSlowDecay[profileIdx], drcComp->sampleRate, drcComp->blockLength);
    624             drcComp->holdOff[i]     = tabHoldOff[profileIdx] * 256 / drcComp->blockLength;
    625 
    626             drcComp->attackThr[i]   = tabAttackThr[profileIdx];
    627             drcComp->decayThr[i]    = tabDecayThr[profileIdx];
    628         }
    629 
    630         drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
    631     }
    632     return (0);
    633 }
    634 
    635 
    636 INT FDK_DRC_Generator_Calc(
    637         HDRC_COMP                       drcComp,
    638         const INT_PCM * const           inSamples,
    639         const INT                       dialnorm,
    640         const INT                       drc_TargetRefLevel,
    641         const INT                       comp_TargetRefLevel,
    642         FIXP_DBL                        clev,
    643         FIXP_DBL                        slev,
    644         INT * const                     pDynrng,
    645         INT * const                     pCompr
    646         )
    647 {
    648     int i, c;
    649     FIXP_DBL peak[2];
    650 
    651 
    652     /**************************************************************************
    653     * compressor
    654     **************************************************************************/
    655       if ((drcComp->profile[0] != DRC_NONE) || (drcComp->profile[1] != DRC_NONE)) {
    656         /* Calc loudness level */
    657         FIXP_DBL level_b = FL2FXCONST_DBL(0.f);
    658         int      level_e = DFRACT_BITS-1;
    659 
    660         /* Increase energy time resolution with shorter processing blocks. 32 is an empiric value. */
    661         const int granuleLength = fixMin(32, drcComp->blockLength);
    662 
    663         if (drcComp->useWeighting) {
    664             FIXP_DBL x1, x2, y, y1, y2;
    665             /* sum of filter coefficients about 2.5 -> squared value is 6.25
    666                WEIGHTING_FILTER_SHIFT is 2 -> scaling about 16, therefore reduce granuleShift by 1.
    667              */
    668             const int granuleShift = getShiftFactor(granuleLength)-1;
    669 
    670             for (c = 0; c < (int)drcComp->channels; c++) {
    671                 const INT_PCM* pSamples = &inSamples[c];
    672 
    673                 if (c == drcComp->channelIdx[LFE]) {
    674                   continue;  /* skip LFE */
    675                 }
    676 
    677                 /* get filter states */
    678                 x1 = drcComp->filter[c].x1;
    679                 x2 = drcComp->filter[c].x2;
    680                 y1 = drcComp->filter[c].y1;
    681                 y2 = drcComp->filter[c].y2;
    682 
    683                 i = 0;
    684 
    685                 do {
    686 
    687                   int offset = i;
    688                   FIXP_DBL accu = FL2FXCONST_DBL(0.f);
    689 
    690                   for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
    691                     /* apply weighting filter */
    692                     FIXP_DBL x = FX_PCM2FX_DBL((FIXP_PCM)pSamples[i*drcComp->channels]) >> WEIGHTING_FILTER_SHIFT;
    693 
    694                     /* y = b0 * (x - x2) - a1 * y1 - a2 * y2; */
    695                     y = fMult(b0,x-x2) - fMult(a1,y1) - fMult(a2,y2);
    696 
    697                     x2 = x1;
    698                     x1 = x;
    699                     y2 = y1;
    700                     y1 = y;
    701 
    702                     accu += fPow2Div2(y)>>(granuleShift-1);     /* partial energy */
    703                   } /* i */
    704 
    705                   fixpAdd(accu, granuleShift+2*WEIGHTING_FILTER_SHIFT, &level_b, &level_e); /* sup up partial energies */
    706 
    707                 } while ( i < drcComp->blockLength );
    708 
    709 
    710                 /* save filter states */
    711                 drcComp->filter[c].x1 = x1;
    712                 drcComp->filter[c].x2 = x2;
    713                 drcComp->filter[c].y1 = y1;
    714                 drcComp->filter[c].y2 = y2;
    715             } /* c */
    716         } /* weighting */
    717         else {
    718             const int granuleShift = getShiftFactor(granuleLength);
    719 
    720             for (c = 0; c < (int)drcComp->channels; c++) {
    721                 const INT_PCM* pSamples = &inSamples[c];
    722 
    723                 if ((int)c == drcComp->channelIdx[LFE]) {
    724                   continue;  /* skip LFE */
    725                 }
    726 
    727                 i = 0;
    728 
    729                 do {
    730                   int offset = i;
    731                   FIXP_DBL accu = FL2FXCONST_DBL(0.f);
    732 
    733                   for (i=offset; i < fixMin(offset+granuleLength,drcComp->blockLength); i++) {
    734                     /* partial energy */
    735                     accu += fPow2Div2((FIXP_PCM)pSamples[i*drcComp->channels])>>(granuleShift-1);
    736                   } /* i */
    737 
    738                   fixpAdd(accu, granuleShift, &level_b, &level_e); /* sup up partial energies */
    739 
    740                 } while ( i < drcComp->blockLength );
    741             }
    742         } /* weighting */
    743 
    744         /*
    745          * Convert to dBFS, apply dialnorm
    746          */
    747         /* level scaling */
    748 
    749         /* descaled level in ld64 representation */
    750         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)));
    751 
    752         /* if (level < 1e-10) level = 1e-10f; */
    753         ldLevel = FDKmax(ldLevel, FL2FXCONST_DBL(-0.51905126482615036685473741085772f));
    754 
    755         /* level = 10 * log(level)/log(10) + 3;
    756          *       = 10*log(2)/log(10) * ld(level) + 3;
    757          *       = 10 * 0.30102999566398119521373889472449 * ld(level) + 3
    758          *       = 10 * (0.30102999566398119521373889472449 * ld(level) + 0.3)
    759          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64
    760          *
    761          *    additional scaling with METADATA_FRACT_BITS:
    762          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 64 * 2^(METADATA_FRACT_BITS)
    763          *       = 10 * (0.30102999566398119521373889472449 * ld64(level) + 0.3/64) * 2^(METADATA_FRACT_BITS+LD_DATA_SHIFT)
    764          *       = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * ( 0.30102999566398119521373889472449 * ld64(level) + 0.3/64 )
    765          * */
    766         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) );
    767 
    768         /* level -= dialnorm + 31 */   /* this is fixed to Dolby-ReferenceLevel as compressor profiles are defined relative to this */
    769         level -= ((FIXP_DBL)(dialnorm<<(METADATA_FRACT_BITS-16))  + (FIXP_DBL)(31<<METADATA_FRACT_BITS));
    770 
    771         for (i = 0; i < 2; i++) {
    772             if (drcComp->profile[i] == DRC_NONE) {
    773                 /* no compression */
    774                 drcComp->smoothGain[i] = FL2FXCONST_DBL(0.f);
    775             }
    776             else {
    777                 FIXP_DBL gain, alpha, lvl2smthlvl;
    778 
    779                 /* calc static gain */
    780                 if (level <= drcComp->maxBoostThr[i]) {
    781                     /* max boost */
    782                     gain = drcComp->maxBoost[i];
    783                 }
    784                 else if (level < drcComp->boostThr[i]) {
    785                     /* boost range */
    786                     gain = fMult((level - drcComp->boostThr[i]),drcComp->boostFac[i]);
    787                 }
    788                 else if (level <= drcComp->earlyCutThr[i]) {
    789                     /* null band */
    790                     gain = FL2FXCONST_DBL(0.f);
    791                 }
    792                 else if (level <= drcComp->cutThr[i]) {
    793                     /* early cut range */
    794                     gain = fMult((level - drcComp->earlyCutThr[i]), drcComp->earlyCutFac[i]);
    795                 }
    796                 else if (level < drcComp->maxCutThr[i]) {
    797                     /* cut range */
    798                     gain = fMult((level - drcComp->cutThr[i]), drcComp->cutFac[i]) - drcComp->maxEarlyCut[i];
    799                 }
    800                 else {
    801                     /* max cut */
    802                     gain = -drcComp->maxCut[i];
    803                 }
    804 
    805                 /* choose time constant */
    806                 lvl2smthlvl = level - drcComp->smoothLevel[i];
    807                 if (gain < drcComp->smoothGain[i]) {
    808                     /* attack */
    809                     if (lvl2smthlvl > drcComp->attackThr[i]) {
    810                         /* fast attack */
    811                         alpha = drcComp->fastAttack[i];
    812                     }
    813                     else {
    814                         /* slow attack */
    815                         alpha = drcComp->slowAttack[i];
    816                     }
    817                 }
    818                 else {
    819                     /* release */
    820                     if (lvl2smthlvl < -drcComp->decayThr[i]) {
    821                         /* fast release */
    822                         alpha = drcComp->fastDecay[i];
    823                     }
    824                     else {
    825                         /* slow release */
    826                         alpha = drcComp->slowDecay[i];
    827                     }
    828                 }
    829 
    830                 /* smooth gain & level */
    831                 if ((gain < drcComp->smoothGain[i]) || (drcComp->holdCnt[i] == 0)) { /* hold gain unless we have an attack or hold period is over */
    832                     FIXP_DBL accu;
    833 
    834                     /* drcComp->smoothLevel[i] = (1-alpha) * drcComp->smoothLevel[i] + alpha * level; */
    835                     accu =  fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothLevel[i]);
    836                     accu += fMult(alpha,level);
    837                     drcComp->smoothLevel[i] = accu;
    838 
    839                     /* drcComp->smoothGain[i]  = (1-alpha) * drcComp->smoothGain[i] + alpha * gain; */
    840                     accu =  fMult((FL2FXCONST_DBL(1.f)-alpha), drcComp->smoothGain[i]);
    841                     accu += fMult(alpha,gain);
    842                     drcComp->smoothGain[i] = accu;
    843                 }
    844 
    845                 /* hold counter */
    846                 if (drcComp->holdCnt[i]) {
    847                   drcComp->holdCnt[i]--;
    848                 }
    849                 if (gain < drcComp->smoothGain[i]) {
    850                   drcComp->holdCnt[i] = drcComp->holdOff[i];
    851                 }
    852             } /* profile != DRC_NONE */
    853         } /* for i=1..2 */
    854       } else {
    855         /* no compression */
    856         drcComp->smoothGain[0] = FL2FXCONST_DBL(0.f);
    857         drcComp->smoothGain[1] = FL2FXCONST_DBL(0.f);
    858       }
    859 
    860     /**************************************************************************
    861     * limiter
    862     **************************************************************************/
    863 
    864     /* find peak level */
    865     peak[0] = peak[1] = FL2FXCONST_DBL(0.f);
    866     for (i = 0; i < drcComp->blockLength; i++) {
    867         FIXP_DBL tmp;
    868         const INT_PCM* pSamples = &inSamples[i*drcComp->channels];
    869         INT_PCM maxSample = 0;
    870 
    871         /* single channels */
    872         for (c = 0; c < (int)drcComp->channels; c++) {
    873             maxSample = FDKmax(maxSample, fAbs(pSamples[c]));
    874         }
    875         peak[0] = fixMax(peak[0], FX_PCM2FX_DBL(maxSample)>>DOWNMIX_SHIFT);
    876 
    877         /* Lt/Rt downmix */
    878         if (drcComp->fullChannels > 2) {
    879             /* Lt */
    880             tmp = FL2FXCONST_DBL(0.f);
    881 
    882             if (drcComp->channelIdx[LS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);          /* Ls */
    883             if (drcComp->channelIdx[LS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);        /* Ls2 */
    884             if (drcComp->channelIdx[RS] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);          /* Rs */
    885             if (drcComp->channelIdx[RS2] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);        /* Rs2 */
    886             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
    887             if (drcComp->channelIdx[S] >= 0) tmp -= fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1);            /* S */
    888             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);            /* C */
    889             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
    890 
    891             peak[0] = fixMax(peak[0], fixp_abs(tmp));
    892 
    893             /* Rt */
    894             tmp = FL2FXCONST_DBL(0.f);
    895             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);          /* Ls */
    896             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);        /* Ls2 */
    897             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);          /* Rs */
    898             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);        /* Rs2 */
    899             if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
    900             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]])>>(DOWNMIX_SHIFT-1);            /* S */
    901             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(FL2FXCONST_DBL(0.707f), (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);            /* C */
    902             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
    903 
    904             peak[0] = fixMax(peak[0], fixp_abs(tmp));
    905         }
    906 
    907         /* Lo/Ro downmix */
    908         if (drcComp->fullChannels > 2) {
    909             /* Lo */
    910             tmp = FL2FXCONST_DBL(0.f);
    911             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);                            /* Ls */
    912             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);                          /* Ls2 */
    913             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
    914             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
    915             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);                              /* C */
    916             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
    917 
    918             peak[0] = fixMax(peak[0], fixp_abs(tmp));
    919 
    920             /* Ro */
    921             tmp = FL2FXCONST_DBL(0.f);
    922             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);                            /* Rs */
    923             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);                          /* Rs2 */
    924             if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 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[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
    928 
    929             peak[0] = fixMax(peak[0], fixp_abs(tmp));
    930         }
    931 
    932         peak[1] = fixMax(peak[0], peak[1]);
    933 
    934         /* Mono Downmix - for comp_val only */
    935         if (drcComp->fullChannels > 1) {
    936             tmp = FL2FXCONST_DBL(0.f);
    937             if (drcComp->channelIdx[LS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS]])>>(DOWNMIX_SHIFT-1);                            /* Ls */
    938             if (drcComp->channelIdx[LS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[LS2]])>>(DOWNMIX_SHIFT-1);                          /* Ls2 */
    939             if (drcComp->channelIdx[RS] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS]])>>(DOWNMIX_SHIFT-1);                            /* Rs */
    940             if (drcComp->channelIdx[RS2] >= 0) tmp += fMultDiv2(slev, (FIXP_PCM)pSamples[drcComp->channelIdx[RS2]])>>(DOWNMIX_SHIFT-1);                          /* Rs2 */
    941             if ((drcComp->channelIdx[LS] >= 0) && (drcComp->channelIdx[LS2] >= 0)) tmp = fMult(FL2FXCONST_DBL(0.707f), tmp);                                     /* 7.1ch */
    942             /*if ((drcComp->channelIdx[RS] >= 0) && (drcComp->channelIdx[RS2] >= 0)) tmp *=0.707f;*/                                                             /* 7.1ch */
    943             if (drcComp->channelIdx[S] >= 0) tmp += fMultDiv2(slev, fMult(FL2FXCONST_DBL(0.7f), (FIXP_PCM)pSamples[drcComp->channelIdx[S]]))>>(DOWNMIX_SHIFT-1); /* S */
    944             if (drcComp->channelIdx[C] >= 0) tmp += fMultDiv2(clev, (FIXP_PCM)pSamples[drcComp->channelIdx[C]])>>(DOWNMIX_SHIFT-1);                              /* C */
    945             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[L]])>>DOWNMIX_SHIFT);                                                                   /* L */
    946             tmp += (FX_PCM2FX_DBL((FIXP_PCM)pSamples[drcComp->channelIdx[R]])>>DOWNMIX_SHIFT);                                                                   /* R */
    947 
    948             peak[1] = fixMax(peak[1], fixp_abs(tmp));
    949         }
    950     }
    951 
    952     for (i=0; i<2; i++) {
    953       FIXP_DBL tmp = drcComp->prevPeak[i];
    954       drcComp->prevPeak[i] = peak[i];
    955       peak[i] = fixMax(peak[i], tmp);
    956 
    957       /*
    958        * Convert to dBFS, apply dialnorm
    959        */
    960       /* descaled peak in ld64 representation */
    961       FIXP_DBL ld_peak = CalcLdData(peak[i]) + (FIXP_DBL)((LONG)DOWNMIX_SHIFT<<(DFRACT_BITS-1-LD_DATA_SHIFT));
    962 
    963       /* if (peak < 1e-6) level = 1e-6f; */
    964       ld_peak = FDKmax(ld_peak, FL2FXCONST_DBL(-0.31143075889569022011284244651463f));
    965 
    966       /* peak[i] = 20 * log(peak[i])/log(10) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
    967        * peak[i] = 20 * log(2)/log(10) * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
    968        * peak[i] = 10 * 2*0.30102999566398119521373889472449 * ld(peak[i]) + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS)
    969        *
    970        *    additional scaling with METADATA_FRACT_BITS:
    971        * peak[i] = (10 * 2*0.30102999566398119521373889472449 * ld64(peak[i]) * 64 + 0.2f + (drcComp->smoothGain[i]*2^METADATA_FRACT_BITS))*2^(-METADATA_FRACT_BITS)
    972        * peak[i] = 10*2^(METADATA_FRACT_BITS+LD_DATA_SHIFT) * 2*0.30102999566398119521373889472449 * ld64(peak[i])
    973        *         + 0.2f*2^(-METADATA_FRACT_BITS) + drcComp->smoothGain[i]
    974        */
    975       peak[i] = fMult((FIXP_DBL)(10<<(METADATA_FRACT_BITS+LD_DATA_SHIFT)), fMult( FL2FX_DBL(2*0.30102999566398119521373889472449f), ld_peak));
    976       peak[i] += (FL2FX_DBL(0.2f)>>METADATA_INT_BITS);           /* add a little bit headroom */
    977       peak[i] +=  drcComp->smoothGain[i];
    978     }
    979 
    980     /* peak -= dialnorm + 31; */  /* this is Dolby style only */
    981     peak[0] -= (FIXP_DBL)((dialnorm-drc_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[0] -= dialnorm - drc_TargetRefLevel */
    982 
    983     /* peak += 11; */   /* this is Dolby style only */      /* RF mode output is 11dB higher */
    984     /*peak += comp_TargetRefLevel - drc_TargetRefLevel;*/
    985     peak[1] -= (FIXP_DBL)((dialnorm-comp_TargetRefLevel)<<(METADATA_FRACT_BITS-16)); /* peak[1] -= dialnorm - comp_TargetRefLevel */
    986 
    987     /* limiter gain */
    988     drcComp->limGain[0] += drcComp->limDecay;               /* linear limiter release */
    989     drcComp->limGain[0] = fixMin(drcComp->limGain[0], -peak[0]);
    990 
    991     drcComp->limGain[1] += 2*drcComp->limDecay;             /* linear limiter release */
    992     drcComp->limGain[1] = fixMin(drcComp->limGain[1], -peak[1]);
    993 
    994     /*************************************************************************/
    995 
    996     /* apply limiting, return DRC gains*/
    997     {
    998         FIXP_DBL tmp;
    999 
   1000         tmp = drcComp->smoothGain[0];
   1001         if (drcComp->limGain[0] < FL2FXCONST_DBL(0.f)) {
   1002           tmp += drcComp->limGain[0];
   1003         }
   1004         *pDynrng = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
   1005 
   1006         tmp = drcComp->smoothGain[1];
   1007         if (drcComp->limGain[1] < FL2FXCONST_DBL(0.f)) {
   1008           tmp += drcComp->limGain[1];
   1009         }
   1010         *pCompr  = (LONG) scaleValue(tmp, -(METADATA_FRACT_BITS-16));
   1011     }
   1012 
   1013     return 0;
   1014 }
   1015 
   1016 
   1017 DRC_PROFILE FDK_DRC_Generator_getDrcProfile(const HDRC_COMP drcComp)
   1018 {
   1019     return drcComp->profile[0];
   1020 }
   1021 
   1022 DRC_PROFILE FDK_DRC_Generator_getCompProfile(const HDRC_COMP drcComp)
   1023 {
   1024     return drcComp->profile[1];
   1025 }
   1026 
   1027 
   1028