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 "fixpoint_math.h"
    106 #include "drcDecoder.h"
    107 
    108 int getDeltaTmin(const int sampleRate) {
    109   /* half_ms = round (0.0005 * sampleRate); */
    110   int half_ms = (sampleRate + 1000) / 2000;
    111   int deltaTmin = 1;
    112   if (sampleRate < 1000) {
    113     return DE_NOT_OK;
    114   }
    115   while (deltaTmin <= half_ms) {
    116     deltaTmin = deltaTmin << 1;
    117   }
    118   return deltaTmin;
    119 }
    120 
    121 DRC_COEFFICIENTS_UNI_DRC* selectDrcCoefficients(
    122     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int location) {
    123   int n;
    124   int c = -1;
    125   for (n = 0; n < hUniDrcConfig->drcCoefficientsUniDrcCount; n++) {
    126     if (hUniDrcConfig->drcCoefficientsUniDrc[n].drcLocation == location) {
    127       c = n;
    128     }
    129   }
    130   if (c >= 0) {
    131     return &(hUniDrcConfig->drcCoefficientsUniDrc[c]);
    132   }
    133   return NULL; /* possible during bitstream parsing */
    134 }
    135 
    136 DRC_INSTRUCTIONS_UNI_DRC* selectDrcInstructions(
    137     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int drcSetId) {
    138   int i;
    139   for (i = 0; i < hUniDrcConfig->drcInstructionsCountInclVirtual; i++) {
    140     if (hUniDrcConfig->drcInstructionsUniDrc[i].drcSetId == drcSetId) {
    141       return &(hUniDrcConfig->drcInstructionsUniDrc[i]);
    142     }
    143   }
    144   return NULL;
    145 }
    146 
    147 DOWNMIX_INSTRUCTIONS* selectDownmixInstructions(
    148     HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int downmixId) {
    149   int i;
    150   for (i = 0; i < hUniDrcConfig->downmixInstructionsCount; i++) {
    151     if (hUniDrcConfig->downmixInstructions[i].downmixId == downmixId) {
    152       return &(hUniDrcConfig->downmixInstructions[i]);
    153     }
    154   }
    155   return NULL;
    156 }
    157 
    158 DRC_ERROR
    159 deriveDrcChannelGroups(
    160     const int drcSetEffect,                                    /* in */
    161     const int channelCount,                                    /* in */
    162     const SCHAR* gainSetIndex,                                 /* in */
    163     const DUCKING_MODIFICATION* duckingModificationForChannel, /* in */
    164     UCHAR* nDrcChannelGroups,                                  /* out */
    165     SCHAR* uniqueIndex,     /* out (gainSetIndexForChannelGroup) */
    166     SCHAR* groupForChannel, /* out */
    167     DUCKING_MODIFICATION* duckingModificationForChannelGroup) /* out */
    168 {
    169   int duckingSequence = -1;
    170   int c, n, g, match, idx;
    171   FIXP_SGL factor;
    172   FIXP_SGL uniqueScaling[8];
    173 
    174   for (g = 0; g < 8; g++) {
    175     uniqueIndex[g] = -10;
    176     uniqueScaling[g] = FIXP_SGL(-1.0f);
    177   }
    178 
    179   g = 0;
    180 
    181   if (drcSetEffect & EB_DUCK_OTHER) {
    182     for (c = 0; c < channelCount; c++) {
    183       match = 0;
    184       if (c >= 8) return DE_MEMORY_ERROR;
    185       idx = gainSetIndex[c];
    186       factor = duckingModificationForChannel[c].duckingScaling;
    187       if (idx < 0) {
    188         for (n = 0; n < g; n++) {
    189           if (uniqueScaling[n] == factor) {
    190             match = 1;
    191             groupForChannel[c] = n;
    192             break;
    193           }
    194         }
    195         if (match == 0) {
    196           if (g >= 8) return DE_MEMORY_ERROR;
    197           uniqueIndex[g] = idx;
    198           uniqueScaling[g] = factor;
    199           groupForChannel[c] = g;
    200           g++;
    201         }
    202       } else {
    203         if ((duckingSequence > 0) && (duckingSequence != idx)) {
    204           return DE_NOT_OK;
    205         }
    206         duckingSequence = idx;
    207         groupForChannel[c] = -1;
    208       }
    209     }
    210     if (duckingSequence == -1) {
    211       return DE_NOT_OK;
    212     }
    213   } else if (drcSetEffect & EB_DUCK_SELF) {
    214     for (c = 0; c < channelCount; c++) {
    215       match = 0;
    216       if (c >= 8) return DE_MEMORY_ERROR;
    217       idx = gainSetIndex[c];
    218       factor = duckingModificationForChannel[c].duckingScaling;
    219       if (idx >= 0) {
    220         for (n = 0; n < g; n++) {
    221           if ((uniqueIndex[n] == idx) && (uniqueScaling[n] == factor)) {
    222             match = 1;
    223             groupForChannel[c] = n;
    224             break;
    225           }
    226         }
    227         if (match == 0) {
    228           if (g >= 8) return DE_MEMORY_ERROR;
    229           uniqueIndex[g] = idx;
    230           uniqueScaling[g] = factor;
    231           groupForChannel[c] = g;
    232           g++;
    233         }
    234       } else {
    235         groupForChannel[c] = -1;
    236       }
    237     }
    238   } else { /* no ducking */
    239     for (c = 0; c < channelCount; c++) {
    240       if (c >= 8) return DE_MEMORY_ERROR;
    241       idx = gainSetIndex[c];
    242       match = 0;
    243       if (idx >= 0) {
    244         for (n = 0; n < g; n++) {
    245           if (uniqueIndex[n] == idx) {
    246             match = 1;
    247             groupForChannel[c] = n;
    248             break;
    249           }
    250         }
    251         if (match == 0) {
    252           if (g >= 8) return DE_MEMORY_ERROR;
    253           uniqueIndex[g] = idx;
    254           groupForChannel[c] = g;
    255           g++;
    256         }
    257       } else {
    258         groupForChannel[c] = -1;
    259       }
    260     }
    261   }
    262   *nDrcChannelGroups = g;
    263 
    264   if (drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
    265     for (g = 0; g < *nDrcChannelGroups; g++) {
    266       if (drcSetEffect & EB_DUCK_OTHER) {
    267         uniqueIndex[g] = duckingSequence;
    268       }
    269       duckingModificationForChannelGroup[g].duckingScaling = uniqueScaling[g];
    270       if (uniqueScaling[g] != FL2FXCONST_SGL(1.0f / (float)(1 << 2))) {
    271         duckingModificationForChannelGroup[g].duckingScalingPresent = 1;
    272       } else {
    273         duckingModificationForChannelGroup[g].duckingScalingPresent = 0;
    274       }
    275     }
    276   }
    277 
    278   return DE_OK;
    279 }
    280 
    281 FIXP_DBL
    282 dB2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) {
    283   /* get linear value from dB.
    284      return lin_val = 10^(dB_val/20) = 2^(log2(10)/20*dB_val)
    285      with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
    286   FIXP_DBL lin_m =
    287       f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1660964f * (float)(1 << 2))), dB_e - 2,
    288             pLin_e);
    289 
    290   return lin_m;
    291 }
    292 
    293 FIXP_DBL
    294 lin2dB(const FIXP_DBL lin_m, const int lin_e, int* pDb_e) {
    295   /* get dB value from linear value.
    296      return dB_val = 20*log10(lin_val)
    297      with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
    298   FIXP_DBL dB_m;
    299 
    300   if (lin_m == (FIXP_DBL)0) { /* return very small value representing -inf */
    301     dB_m = (FIXP_DBL)MINVAL_DBL;
    302     *pDb_e = DFRACT_BITS - 1;
    303   } else {
    304     /* 20*log10(lin_val) = 20/log2(10)*log2(lin_val) */
    305     dB_m = fMultDiv2(FL2FXCONST_DBL(6.02059991f / (float)(1 << 3)),
    306                      fLog2(lin_m, lin_e, pDb_e));
    307     *pDb_e += 3 + 1;
    308   }
    309 
    310   return dB_m;
    311 }
    312 
    313 FIXP_DBL
    314 approxDb2lin(const FIXP_DBL dB_m, const int dB_e, int* pLin_e) {
    315   /* get linear value from approximate dB.
    316      return lin_val = 2^(dB_val/6)
    317      with dB_val = dB_m *2^dB_e and lin_val = lin_m * 2^lin_e */
    318   FIXP_DBL lin_m =
    319       f2Pow(fMult(dB_m, FL2FXCONST_DBL(0.1666667f * (float)(1 << 2))), dB_e - 2,
    320             pLin_e);
    321 
    322   return lin_m;
    323 }
    324 
    325 int bitstreamContainsMultibandDrc(HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    326                                   const int downmixId) {
    327   int i, g, d, seq;
    328   DRC_INSTRUCTIONS_UNI_DRC* pInst;
    329   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
    330   int isMultiband = 0;
    331 
    332   pCoef = selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
    333   if (pCoef == NULL) return 0;
    334 
    335   for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
    336     pInst = &(hUniDrcConfig->drcInstructionsUniDrc[i]);
    337     for (d = 0; d < pInst->downmixIdCount; d++) {
    338       if (downmixId == pInst->downmixId[d]) {
    339         for (g = 0; g < pInst->nDrcChannelGroups; g++) {
    340           seq = pInst->gainSetIndexForChannelGroup[g];
    341           if (pCoef->gainSet[seq].bandCount > 1) {
    342             isMultiband = 1;
    343           }
    344         }
    345       }
    346     }
    347   }
    348 
    349   return isMultiband;
    350 }
    351 
    352 FIXP_DBL getDownmixOffset(DOWNMIX_INSTRUCTIONS* pDown, int baseChannelCount) {
    353   FIXP_DBL downmixOffset = FL2FXCONST_DBL(1.0f / (1 << 1)); /* e = 1 */
    354   if ((pDown->bsDownmixOffset == 1) || (pDown->bsDownmixOffset == 2)) {
    355     int e_a, e_downmixOffset;
    356     FIXP_DBL a, q;
    357     if (baseChannelCount <= pDown->targetChannelCount) return downmixOffset;
    358 
    359     q = fDivNorm((FIXP_DBL)pDown->targetChannelCount,
    360                  (FIXP_DBL)baseChannelCount); /* e = 0 */
    361     a = lin2dB(q, 0, &e_a);
    362     if (pDown->bsDownmixOffset == 2) {
    363       e_a += 1; /* a *= 2 */
    364     }
    365     /* a = 0.5 * round (a) */
    366     a = fixp_round(a, e_a) >> 1;
    367     downmixOffset = dB2lin(a, e_a, &e_downmixOffset);
    368     downmixOffset = scaleValue(downmixOffset, e_downmixOffset - 1);
    369   }
    370   return downmixOffset;
    371 }
    372