Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /************************* MPEG-D DRC decoder library **************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "drcDec_types.h"
    104 #include "drcDec_gainDecoder.h"
    105 #include "drcGainDec_preprocess.h"
    106 #include "drcGainDec_init.h"
    107 #include "drcGainDec_process.h"
    108 #include "drcDec_tools.h"
    109 
    110 /*******************************************/
    111 /* static functions                        */
    112 /*******************************************/
    113 
    114 static int _fitsLocation(DRC_INSTRUCTIONS_UNI_DRC* pInst,
    115                          const GAIN_DEC_LOCATION drcLocation) {
    116   int downmixId = pInst->drcApplyToDownmix ? pInst->downmixId[0] : 0;
    117   switch (drcLocation) {
    118     case GAIN_DEC_DRC1:
    119       return (downmixId == 0);
    120     case GAIN_DEC_DRC1_DRC2:
    121       return ((downmixId == 0) || (downmixId == DOWNMIX_ID_ANY_DOWNMIX));
    122     case GAIN_DEC_DRC2:
    123       return (downmixId == DOWNMIX_ID_ANY_DOWNMIX);
    124     case GAIN_DEC_DRC3:
    125       return ((downmixId != 0) && (downmixId != DOWNMIX_ID_ANY_DOWNMIX));
    126     case GAIN_DEC_DRC2_DRC3:
    127       return (downmixId != 0);
    128   }
    129   return 0;
    130 }
    131 
    132 static void _setChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
    133                              const int numChannelGains,
    134                              const FIXP_DBL* channelGainDb) {
    135   int i, channelGain_e;
    136   FIXP_DBL channelGain;
    137   FDK_ASSERT(numChannelGains <= 8);
    138   for (i = 0; i < numChannelGains; i++) {
    139     if (channelGainDb[i] == (FIXP_DBL)MINVAL_DBL) {
    140       hGainDec->channelGain[i] = (FIXP_DBL)0;
    141     } else {
    142       /* add loudness normalisation gain (dB) to channel gain (dB) */
    143       FIXP_DBL tmp_channelGainDb = (channelGainDb[i] >> 1) +
    144                                    (hGainDec->loudnessNormalisationGainDb >> 2);
    145       tmp_channelGainDb =
    146           SATURATE_LEFT_SHIFT(tmp_channelGainDb, 1, DFRACT_BITS);
    147       channelGain = dB2lin(tmp_channelGainDb, 8, &channelGain_e);
    148       hGainDec->channelGain[i] = scaleValue(channelGain, channelGain_e - 8);
    149     }
    150   }
    151 }
    152 
    153 /*******************************************/
    154 /* public functions                        */
    155 /*******************************************/
    156 
    157 DRC_ERROR
    158 drcDec_GainDecoder_Open(HANDLE_DRC_GAIN_DECODER* phGainDec) {
    159   DRC_GAIN_DECODER* hGainDec = NULL;
    160 
    161   hGainDec = (DRC_GAIN_DECODER*)FDKcalloc(1, sizeof(DRC_GAIN_DECODER));
    162   if (hGainDec == NULL) return DE_MEMORY_ERROR;
    163 
    164   hGainDec->multiBandActiveDrcIndex = -1;
    165   hGainDec->channelGainActiveDrcIndex = -1;
    166 
    167   *phGainDec = hGainDec;
    168 
    169   return DE_OK;
    170 }
    171 
    172 DRC_ERROR
    173 drcDec_GainDecoder_Init(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
    174                         const int sampleRate) {
    175   DRC_ERROR err = DE_OK;
    176 
    177   err = initGainDec(hGainDec, frameSize, sampleRate);
    178   if (err) return err;
    179 
    180   initDrcGainBuffers(hGainDec->frameSize, &hGainDec->drcGainBuffers);
    181 
    182   return err;
    183 }
    184 
    185 DRC_ERROR
    186 drcDec_GainDecoder_SetCodecDependentParameters(
    187     HANDLE_DRC_GAIN_DECODER hGainDec, const DELAY_MODE delayMode,
    188     const int timeDomainSupported,
    189     const SUBBAND_DOMAIN_MODE subbandDomainSupported) {
    190   if ((delayMode != DM_REGULAR_DELAY) && (delayMode != DM_LOW_DELAY)) {
    191     return DE_NOT_OK;
    192   }
    193   hGainDec->delayMode = delayMode;
    194   hGainDec->timeDomainSupported = timeDomainSupported;
    195   hGainDec->subbandDomainSupported = subbandDomainSupported;
    196 
    197   return DE_OK;
    198 }
    199 
    200 DRC_ERROR
    201 drcDec_GainDecoder_Config(HANDLE_DRC_GAIN_DECODER hGainDec,
    202                           HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    203                           const UCHAR numSelectedDrcSets,
    204                           const SCHAR* selectedDrcSetIds,
    205                           const UCHAR* selectedDownmixIds) {
    206   DRC_ERROR err = DE_OK;
    207   int a;
    208 
    209   hGainDec->nActiveDrcs = 0;
    210   hGainDec->multiBandActiveDrcIndex = -1;
    211   hGainDec->channelGainActiveDrcIndex = -1;
    212   for (a = 0; a < numSelectedDrcSets; a++) {
    213     err = initActiveDrc(hGainDec, hUniDrcConfig, selectedDrcSetIds[a],
    214                         selectedDownmixIds[a]);
    215     if (err) return err;
    216   }
    217 
    218   err = initActiveDrcOffset(hGainDec);
    219   if (err) return err;
    220 
    221   return err;
    222 }
    223 
    224 DRC_ERROR
    225 drcDec_GainDecoder_Close(HANDLE_DRC_GAIN_DECODER* phGainDec) {
    226   if (*phGainDec != NULL) {
    227     FDKfree(*phGainDec);
    228     *phGainDec = NULL;
    229   }
    230 
    231   return DE_OK;
    232 }
    233 
    234 DRC_ERROR
    235 drcDec_GainDecoder_Preprocess(HANDLE_DRC_GAIN_DECODER hGainDec,
    236                               HANDLE_UNI_DRC_GAIN hUniDrcGain,
    237                               const FIXP_DBL loudnessNormalizationGainDb,
    238                               const FIXP_SGL boost, const FIXP_SGL compress) {
    239   DRC_ERROR err = DE_OK;
    240   int a, c;
    241 
    242   /* lnbPointer is the index on the most recent node buffer */
    243   hGainDec->drcGainBuffers.lnbPointer++;
    244   if (hGainDec->drcGainBuffers.lnbPointer >= NUM_LNB_FRAMES)
    245     hGainDec->drcGainBuffers.lnbPointer = 0;
    246 
    247   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
    248     /* prepare gain interpolation of sequences used by copying and modifying
    249      * nodes in node buffers */
    250     err = prepareDrcGain(hGainDec, hUniDrcGain, compress, boost,
    251                          loudnessNormalizationGainDb, a);
    252     if (err) return err;
    253   }
    254 
    255   for (a = 0; a < MAX_ACTIVE_DRCS; a++) {
    256     for (c = 0; c < 8; c++) {
    257       hGainDec->activeDrc[a]
    258           .lnbIndexForChannel[c][hGainDec->drcGainBuffers.lnbPointer] =
    259           -1; /* "no DRC processing" */
    260     }
    261     hGainDec->activeDrc[a].subbandGainsReady = 0;
    262   }
    263 
    264   for (c = 0; c < 8; c++) {
    265     hGainDec->drcGainBuffers
    266         .channelGain[c][hGainDec->drcGainBuffers.lnbPointer] =
    267         FL2FXCONST_DBL(1.0f / (float)(1 << 8));
    268   }
    269 
    270   return err;
    271 }
    272 
    273 /* create gain sequence out of gain sequences of last frame for concealment and
    274  * flushing */
    275 DRC_ERROR
    276 drcDec_GainDecoder_Conceal(HANDLE_DRC_GAIN_DECODER hGainDec,
    277                            HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    278                            HANDLE_UNI_DRC_GAIN hUniDrcGain) {
    279   int seq, gainSequenceCount;
    280   DRC_COEFFICIENTS_UNI_DRC* pCoef =
    281       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
    282   if (pCoef == NULL) return DE_OK;
    283 
    284   gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
    285 
    286   for (seq = 0; seq < gainSequenceCount; seq++) {
    287     int lastNodeIndex = 0;
    288     FIXP_SGL lastGainDb = (FIXP_SGL)0;
    289 
    290     lastNodeIndex = hUniDrcGain->nNodes[seq] - 1;
    291     if ((lastNodeIndex >= 0) && (lastNodeIndex < 16)) {
    292       lastGainDb = hUniDrcGain->gainNode[seq][lastNodeIndex].gainDb;
    293     }
    294 
    295     hUniDrcGain->nNodes[seq] = 1;
    296     if (lastGainDb > (FIXP_SGL)0) {
    297       hUniDrcGain->gainNode[seq][0].gainDb =
    298           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.9f), lastGainDb));
    299     } else {
    300       hUniDrcGain->gainNode[seq][0].gainDb =
    301           FX_DBL2FX_SGL(fMult(FL2FXCONST_SGL(0.98f), lastGainDb));
    302     }
    303     hUniDrcGain->gainNode[seq][0].time = hGainDec->frameSize - 1;
    304   }
    305   return DE_OK;
    306 }
    307 
    308 void drcDec_GainDecoder_SetChannelGains(HANDLE_DRC_GAIN_DECODER hGainDec,
    309                                         const int numChannels,
    310                                         const int frameSize,
    311                                         const FIXP_DBL* channelGainDb,
    312                                         const int audioBufferChannelOffset,
    313                                         FIXP_DBL* audioBuffer) {
    314   int c, i;
    315 
    316   if (hGainDec->channelGainActiveDrcIndex >= 0) {
    317     /* channel gains will be applied in drcDec_GainDecoder_ProcessTimeDomain or
    318      * drcDec_GainDecoder_ProcessSubbandDomain, respectively. */
    319     _setChannelGains(hGainDec, numChannels, channelGainDb);
    320 
    321     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
    322       DRC_GAIN_BUFFERS* pDrcGainBuffers = &hGainDec->drcGainBuffers;
    323       for (c = 0; c < numChannels; c++) {
    324         for (i = 0; i < NUM_LNB_FRAMES; i++) {
    325           pDrcGainBuffers->channelGain[c][i] = hGainDec->channelGain[c];
    326         }
    327       }
    328       hGainDec->status = 1;
    329     }
    330   } else {
    331     /* smooth and apply channel gains */
    332     FIXP_DBL prevChannelGain[8];
    333     for (c = 0; c < numChannels; c++) {
    334       prevChannelGain[c] = hGainDec->channelGain[c];
    335     }
    336 
    337     _setChannelGains(hGainDec, numChannels, channelGainDb);
    338 
    339     if (!hGainDec->status) { /* overwrite previous channel gains at startup */
    340       for (c = 0; c < numChannels; c++)
    341         prevChannelGain[c] = hGainDec->channelGain[c];
    342       hGainDec->status = 1;
    343     }
    344 
    345     for (c = 0; c < numChannels; c++) {
    346       INT n_min = fMin(fMin(CntLeadingZeros(prevChannelGain[c]),
    347                             CntLeadingZeros(hGainDec->channelGain[c])) -
    348                            1,
    349                        9);
    350       FIXP_DBL gain = prevChannelGain[c] << n_min;
    351       FIXP_DBL stepsize = ((hGainDec->channelGain[c] << n_min) - gain);
    352       if (stepsize != (FIXP_DBL)0) {
    353         if (frameSize == 1024)
    354           stepsize = stepsize >> 10;
    355         else
    356           stepsize = (LONG)stepsize / frameSize;
    357       }
    358       n_min = 9 - n_min;
    359 #ifdef FUNCTION_drcDec_GainDecoder_SetChannelGains_func1
    360       drcDec_GainDecoder_SetChannelGains_func1(audioBuffer, gain, stepsize,
    361                                                n_min, frameSize);
    362 #else
    363       for (i = 0; i < frameSize; i++) {
    364         audioBuffer[i] = fMultDiv2(audioBuffer[i], gain) << n_min;
    365         gain += stepsize;
    366       }
    367 #endif
    368       audioBuffer += audioBufferChannelOffset;
    369     }
    370   }
    371 }
    372 
    373 DRC_ERROR
    374 drcDec_GainDecoder_ProcessTimeDomain(
    375     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
    376     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
    377     const int drcChannelOffset, const int numChannelsProcessed,
    378     const int timeDataChannelOffset, FIXP_DBL* audioIOBuffer) {
    379   DRC_ERROR err = DE_OK;
    380   int a;
    381 
    382   if (!hGainDec->timeDomainSupported) {
    383     return DE_NOT_OK;
    384   }
    385 
    386   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
    387     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
    388 
    389     /* Apply DRC */
    390     err = processDrcTime(hGainDec, a, delaySamples, channelOffset,
    391                          drcChannelOffset, numChannelsProcessed,
    392                          timeDataChannelOffset, audioIOBuffer);
    393     if (err) return err;
    394   }
    395 
    396   return err;
    397 }
    398 
    399 DRC_ERROR
    400 drcDec_GainDecoder_ProcessSubbandDomain(
    401     HANDLE_DRC_GAIN_DECODER hGainDec, const int delaySamples,
    402     const GAIN_DEC_LOCATION drcLocation, const int channelOffset,
    403     const int drcChannelOffset, const int numChannelsProcessed,
    404     const int processSingleTimeslot, FIXP_DBL* audioIOBufferReal[],
    405     FIXP_DBL* audioIOBufferImag[]) {
    406   DRC_ERROR err = DE_OK;
    407   int a;
    408 
    409   if (hGainDec->subbandDomainSupported == SDM_OFF) {
    410     return DE_NOT_OK;
    411   }
    412 
    413   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
    414     if (!_fitsLocation(hGainDec->activeDrc[a].pInst, drcLocation)) continue;
    415 
    416     /* Apply DRC */
    417     err = processDrcSubband(hGainDec, a, delaySamples, channelOffset,
    418                             drcChannelOffset, numChannelsProcessed,
    419                             processSingleTimeslot, audioIOBufferReal,
    420                             audioIOBufferImag);
    421     if (err) return err;
    422   }
    423 
    424   return err;
    425 }
    426 
    427 DRC_ERROR
    428 drcDec_GainDecoder_SetLoudnessNormalizationGainDb(
    429     HANDLE_DRC_GAIN_DECODER hGainDec, FIXP_DBL loudnessNormalizationGainDb) {
    430   hGainDec->loudnessNormalisationGainDb = loudnessNormalizationGainDb;
    431 
    432   return DE_OK;
    433 }
    434 
    435 int drcDec_GainDecoder_GetFrameSize(HANDLE_DRC_GAIN_DECODER hGainDec) {
    436   if (hGainDec == NULL) return -1;
    437 
    438   return hGainDec->frameSize;
    439 }
    440 
    441 int drcDec_GainDecoder_GetDeltaTminDefault(HANDLE_DRC_GAIN_DECODER hGainDec) {
    442   if (hGainDec == NULL) return -1;
    443 
    444   return hGainDec->deltaTminDefault;
    445 }
    446