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_tools.h"
    105 #include "drcDec_gainDecoder.h"
    106 #include "drcGainDec_init.h"
    107 
    108 static DRC_ERROR _generateDrcInstructionsDerivedData(
    109     HANDLE_DRC_GAIN_DECODER hGainDec, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    110     DRC_INSTRUCTIONS_UNI_DRC* pInst, DRC_COEFFICIENTS_UNI_DRC* pCoef,
    111     ACTIVE_DRC* pActiveDrc) {
    112   DRC_ERROR err = DE_OK;
    113   int g;
    114   int gainElementCount = 0;
    115   UCHAR nDrcChannelGroups = 0;
    116   SCHAR gainSetIndexForChannelGroup[8];
    117 
    118   err = deriveDrcChannelGroups(
    119       pInst->drcSetEffect, pInst->drcChannelCount, pInst->gainSetIndex,
    120       pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)
    121           ? pInst->duckingModificationForChannel
    122           : NULL,
    123       &nDrcChannelGroups, gainSetIndexForChannelGroup,
    124       pActiveDrc->channelGroupForChannel,
    125       pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)
    126           ? pActiveDrc->duckingModificationForChannelGroup
    127           : NULL);
    128   if (err) return (err);
    129 
    130   /* sanity check */
    131   if (nDrcChannelGroups != pInst->nDrcChannelGroups) return DE_NOT_OK;
    132   for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    133     if (gainSetIndexForChannelGroup[g] != pInst->gainSetIndexForChannelGroup[g])
    134       return DE_NOT_OK;
    135   }
    136 
    137   for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    138     int seq = pInst->gainSetIndexForChannelGroup[g];
    139     if (seq != -1 && (hUniDrcConfig->drcCoefficientsUniDrcCount == 0 ||
    140                       seq >= pCoef->gainSetCount)) {
    141       pActiveDrc->channelGroupIsParametricDrc[g] = 1;
    142     } else {
    143       pActiveDrc->channelGroupIsParametricDrc[g] = 0;
    144       if (seq >= pCoef->gainSetCount) {
    145         return DE_NOT_OK;
    146       }
    147     }
    148   }
    149 
    150   /* gainElementCount */
    151   if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
    152     for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    153       pActiveDrc->bandCountForChannelGroup[g] = 1;
    154     }
    155     pActiveDrc->gainElementCount =
    156         pInst->nDrcChannelGroups; /* one gain element per channel group */
    157   } else {
    158     for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    159       if (pActiveDrc->channelGroupIsParametricDrc[g]) {
    160         gainElementCount++;
    161         pActiveDrc->bandCountForChannelGroup[g] = 1;
    162       } else {
    163         int seq, bandCount;
    164         seq = pInst->gainSetIndexForChannelGroup[g];
    165         bandCount = pCoef->gainSet[seq].bandCount;
    166         pActiveDrc->bandCountForChannelGroup[g] = bandCount;
    167         gainElementCount += bandCount;
    168       }
    169     }
    170     pActiveDrc->gainElementCount = gainElementCount;
    171   }
    172 
    173   /* prepare gainElementForGroup (cumulated sum of bandCountForChannelGroup) */
    174   pActiveDrc->gainElementForGroup[0] = 0;
    175   for (g = 1; g < pInst->nDrcChannelGroups; g++) {
    176     pActiveDrc->gainElementForGroup[g] =
    177         pActiveDrc->gainElementForGroup[g - 1] +
    178         pActiveDrc->bandCountForChannelGroup[g - 1]; /* index of first gain
    179                                                         sequence in channel
    180                                                         group */
    181   }
    182 
    183   return DE_OK;
    184 }
    185 
    186 DRC_ERROR
    187 initGainDec(HANDLE_DRC_GAIN_DECODER hGainDec, const int frameSize,
    188             const int sampleRate) {
    189   int i, j, k;
    190 
    191   if (frameSize < 1) {
    192     return DE_NOT_OK;
    193   }
    194 
    195   hGainDec->frameSize = frameSize;
    196 
    197   if (hGainDec->frameSize * 1000 < sampleRate) {
    198     return DE_NOT_OK;
    199   }
    200 
    201   hGainDec->deltaTminDefault = getDeltaTmin(sampleRate);
    202   if (hGainDec->deltaTminDefault > hGainDec->frameSize) {
    203     return DE_NOT_OK;
    204   }
    205 
    206   for (i = 0; i < MAX_ACTIVE_DRCS; i++) {
    207     for (j = 0; j < 8; j++) {
    208       /* use startup node at the beginning */
    209       hGainDec->activeDrc[i].lnbIndexForChannel[j][0] = 0;
    210       for (k = 1; k < NUM_LNB_FRAMES; k++) {
    211         hGainDec->activeDrc[i].lnbIndexForChannel[j][k] = -1;
    212       }
    213     }
    214   }
    215 
    216   for (j = 0; j < 8; j++) {
    217     hGainDec->channelGain[j] = FL2FXCONST_DBL(1.0f / (float)(1 << 8));
    218   }
    219 
    220   for (i = 0; i < 4 * 1024 / 256; i++) {
    221     hGainDec->dummySubbandGains[i] = FL2FXCONST_DBL(1.0f / (float)(1 << 7));
    222   }
    223 
    224   hGainDec->status = 0; /* startup */
    225 
    226   return DE_OK;
    227 }
    228 
    229 void initDrcGainBuffers(const int frameSize, DRC_GAIN_BUFFERS* drcGainBuffers) {
    230   int i, c, j;
    231   /* prepare 12 instances of node buffers */
    232   for (i = 0; i < 12; i++) {
    233     for (j = 0; j < NUM_LNB_FRAMES; j++) {
    234       drcGainBuffers->linearNodeBuffer[i].nNodes[j] = 1;
    235       drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].gainLin =
    236           FL2FXCONST_DBL(1.0f / (float)(1 << 7));
    237       if (j == 0) {
    238         drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
    239             0; /* initialize last node with startup node */
    240       } else {
    241         drcGainBuffers->linearNodeBuffer[i].linearNode[j][0].time =
    242             frameSize - 1;
    243       }
    244     }
    245   }
    246 
    247   /* prepare dummyLnb, a linearNodeBuffer containing a constant gain of 0 dB,
    248    * for the "no DRC processing" case */
    249   drcGainBuffers->dummyLnb.gainInterpolationType = GIT_LINEAR;
    250   for (i = 0; i < NUM_LNB_FRAMES; i++) {
    251     drcGainBuffers->dummyLnb.nNodes[i] = 1;
    252     drcGainBuffers->dummyLnb.linearNode[i][0].gainLin =
    253         FL2FXCONST_DBL(1.0f / (float)(1 << 7));
    254     drcGainBuffers->dummyLnb.linearNode[i][0].time = frameSize - 1;
    255   }
    256 
    257   /* prepare channelGain delay line */
    258   for (c = 0; c < 8; c++) {
    259     for (i = 0; i < NUM_LNB_FRAMES; i++) {
    260       drcGainBuffers->channelGain[c][i] =
    261           FL2FXCONST_DBL(1.0f / (float)(1 << 8));
    262     }
    263   }
    264 
    265   drcGainBuffers->lnbPointer = 0;
    266 }
    267 
    268 DRC_ERROR
    269 initActiveDrc(HANDLE_DRC_GAIN_DECODER hGainDec,
    270               HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetIdSelected,
    271               const int downmixIdSelected) {
    272   int g, isMultiband = 0;
    273   DRC_ERROR err = DE_OK;
    274   DRC_INSTRUCTIONS_UNI_DRC* pInst = NULL;
    275   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
    276 
    277   pInst = selectDrcInstructions(hUniDrcConfig, drcSetIdSelected);
    278   if (pInst == NULL) {
    279     return DE_NOT_OK;
    280   }
    281 
    282   if (pInst->drcSetId >= 0) {
    283     pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
    284     if (pCoef == NULL) {
    285       return DE_NOT_OK;
    286     }
    287 
    288     if (pCoef->drcFrameSizePresent) {
    289       if (pCoef->drcFrameSize != hGainDec->frameSize) {
    290         return DE_NOT_OK;
    291       }
    292     }
    293 
    294     err = _generateDrcInstructionsDerivedData(
    295         hGainDec, hUniDrcConfig, pInst, pCoef,
    296         &(hGainDec->activeDrc[hGainDec->nActiveDrcs]));
    297     if (err) return err;
    298   }
    299 
    300   hGainDec->activeDrc[hGainDec->nActiveDrcs].pInst = pInst;
    301   hGainDec->activeDrc[hGainDec->nActiveDrcs].pCoef = pCoef;
    302 
    303   for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    304     if (hGainDec->activeDrc[hGainDec->nActiveDrcs].bandCountForChannelGroup[g] >
    305         1) {
    306       if (hGainDec->multiBandActiveDrcIndex != -1) {
    307         return DE_NOT_OK;
    308       }
    309       isMultiband = 1;
    310     }
    311   }
    312 
    313   if (isMultiband) {
    314     /* Keep activeDrc index of multiband DRC set */
    315     hGainDec->multiBandActiveDrcIndex = hGainDec->nActiveDrcs;
    316   }
    317 
    318   if ((hGainDec->channelGainActiveDrcIndex == -1) &&
    319       (downmixIdSelected == DOWNMIX_ID_BASE_LAYOUT) &&
    320       (hUniDrcConfig->drcInstructionsUniDrcCount >
    321        0)) { /* use this activeDrc to apply channelGains */
    322     hGainDec->channelGainActiveDrcIndex = hGainDec->nActiveDrcs;
    323   }
    324 
    325   hGainDec->nActiveDrcs++;
    326   if (hGainDec->nActiveDrcs > MAX_ACTIVE_DRCS) return DE_NOT_OK;
    327 
    328   return DE_OK;
    329 }
    330 
    331 DRC_ERROR
    332 initActiveDrcOffset(HANDLE_DRC_GAIN_DECODER hGainDec) {
    333   int a, accGainElementCount;
    334 
    335   accGainElementCount = 0;
    336   for (a = 0; a < hGainDec->nActiveDrcs; a++) {
    337     hGainDec->activeDrc[a].activeDrcOffset = accGainElementCount;
    338     accGainElementCount += hGainDec->activeDrc[a].gainElementCount;
    339   }
    340 
    341   if (accGainElementCount > 12) return DE_NOT_OK;
    342 
    343   return DE_OK;
    344 }
    345