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 surround encoder library *************************
     96 
     97    Author(s):   Christian Goettlinger
     98 
     99    Description: Encoder Library Interface
    100                 delay management of the encoder
    101 
    102 *******************************************************************************/
    103 
    104 /**************************************************************************/ /**
    105  \file
    106  This file contains all delay infrastructure
    107  ******************************************************************************/
    108 
    109 /* Includes ******************************************************************/
    110 #include "sacenc_delay.h"
    111 #include "sacenc_const.h"
    112 #include "FDK_matrixCalloc.h"
    113 
    114 /* Defines *******************************************************************/
    115 
    116 /* Data Types ****************************************************************/
    117 struct DELAY {
    118   struct DELAY_CONFIG {
    119     /* Routing Config Switches*/
    120     INT bDmxAlign;
    121     INT bTimeDomDmx;
    122     INT bMinimizeDelay;
    123     INT bSacTimeAlignmentDynamicOut;
    124 
    125     /* Needed Input Variables*/
    126     INT nQmfLen;
    127     INT nFrameLen;
    128     INT nSurroundDelay;
    129     INT nArbDmxDelay;
    130     INT nLimiterDelay;
    131     INT nCoreCoderDelay;
    132     INT nSacStreamMuxDelay;
    133     INT nSacTimeAlignment; /* Overwritten, if bSacTimeAlignmentDynamicOut */
    134   } config;
    135 
    136   /* Variable Delaybuffers -> Delays */
    137   INT nDmxAlignBuffer;
    138   INT nSurroundAnalysisBuffer;
    139   INT nArbDmxAnalysisBuffer;
    140   INT nOutputAudioBuffer;
    141   INT nBitstreamFrameBuffer;
    142   INT nOutputAudioQmfFrameBuffer;
    143   INT nDiscardOutFrames;
    144 
    145   /* Variable Delaybuffers Computation Variables */
    146   INT nBitstreamFrameBufferSize;
    147 
    148   /* Output: Infos */
    149   INT nInfoDmxDelay; /* Delay of the downmixed signal after the space encoder */
    150   INT nInfoCodecDelay; /* Delay of the whole en-/decoder including CoreCoder */
    151   INT nInfoDecoderDelay; /* Delay of the Mpeg Surround decoder */
    152 };
    153 
    154 /* Constants *****************************************************************/
    155 
    156 /* Function / Class Declarations *********************************************/
    157 
    158 /* Function / Class Definition ***********************************************/
    159 
    160 /*-----------------------------------------------------------------------------
    161 functionname: fdk_sacenc_delay_Open()
    162 description:  initializes Delays
    163 returns:      noError on success, an apropriate error code else
    164 -----------------------------------------------------------------------------*/
    165 FDK_SACENC_ERROR fdk_sacenc_delay_Open(HANDLE_DELAY *phDelay) {
    166   FDK_SACENC_ERROR error = SACENC_OK;
    167 
    168   if (NULL == phDelay) {
    169     error = SACENC_INVALID_HANDLE;
    170   } else {
    171     FDK_ALLOCATE_MEMORY_1D(*phDelay, 1, struct DELAY);
    172   }
    173   return error;
    174 
    175 bail:
    176   fdk_sacenc_delay_Close(phDelay);
    177   return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
    178 }
    179 
    180 /*-----------------------------------------------------------------------------
    181 functionname: fdk_sacenc_delay_Close()
    182 description:  destructs Delay
    183 returns:      noError on success, an apropriate error code else
    184 -----------------------------------------------------------------------------*/
    185 FDK_SACENC_ERROR fdk_sacenc_delay_Close(HANDLE_DELAY *phDelay) {
    186   FDK_SACENC_ERROR error = SACENC_OK;
    187 
    188   if (NULL == phDelay) {
    189     error = SACENC_INVALID_HANDLE;
    190   } else {
    191     if (NULL != *phDelay) {
    192       FDK_FREE_MEMORY_1D(*phDelay);
    193     }
    194   }
    195   return error;
    196 }
    197 
    198 FDK_SACENC_ERROR fdk_sacenc_delay_Init(HANDLE_DELAY hDelay, const INT nQmfLen,
    199                                        const INT nFrameLen,
    200                                        const INT nCoreCoderDelay,
    201                                        const INT nSacStreamMuxDelay) {
    202   FDK_SACENC_ERROR error = SACENC_OK;
    203 
    204   if (NULL == hDelay) {
    205     error = SACENC_INVALID_HANDLE;
    206   } else {
    207     /* Fill structure before calculation */
    208     FDKmemclear(&hDelay->config, sizeof(hDelay->config));
    209 
    210     hDelay->config.nQmfLen = nQmfLen;
    211     hDelay->config.nFrameLen = nFrameLen;
    212     hDelay->config.nCoreCoderDelay = nCoreCoderDelay;
    213     hDelay->config.nSacStreamMuxDelay = nSacStreamMuxDelay;
    214   }
    215   return error;
    216 }
    217 
    218 /*-----------------------------------------------------------------------------
    219 functionname: fdk_sacenc_delay_SubCalulateBufferDelays()
    220 description:  Calculates the Delays of the buffers
    221 returns:      Error Code
    222 -----------------------------------------------------------------------------*/
    223 FDK_SACENC_ERROR fdk_sacenc_delay_SubCalulateBufferDelays(HANDLE_DELAY hDel) {
    224   FDK_SACENC_ERROR error = SACENC_OK;
    225 
    226   if (NULL == hDel) {
    227     error = SACENC_INVALID_HANDLE;
    228   } else {
    229     int nEncoderAnDelay, nEncoderSynDelay, nEncoderWinDelay, nDecoderAnDelay,
    230         nDecoderSynDelay, nResidualCoderFrameDelay,
    231         nArbDmxResidualCoderFrameDelay;
    232 
    233     if (hDel->config.bSacTimeAlignmentDynamicOut > 0) {
    234       hDel->config.nSacTimeAlignment = 0;
    235     }
    236 
    237     {
    238       nEncoderAnDelay =
    239           2 * hDel->config.nQmfLen +
    240           hDel->config.nQmfLen / 2; /* Only Ld-QMF Delay, no hybrid */
    241       nEncoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
    242       nDecoderAnDelay = 2 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
    243       nDecoderSynDelay = 1 * hDel->config.nQmfLen + hDel->config.nQmfLen / 2;
    244       nEncoderWinDelay =
    245           hDel->config.nFrameLen / 2; /* WindowLookahead is just half a frame */
    246     }
    247 
    248     { nResidualCoderFrameDelay = 0; }
    249 
    250     { nArbDmxResidualCoderFrameDelay = 0; }
    251 
    252     /* Calculate variable Buffer-Delays */
    253     if (hDel->config.bTimeDomDmx == 0) {
    254       /* ArbitraryDmx and TdDmx off */
    255       int tempDelay;
    256 
    257       hDel->nSurroundAnalysisBuffer = 0;
    258       hDel->nArbDmxAnalysisBuffer = 0;
    259       tempDelay = nEncoderSynDelay + hDel->config.nLimiterDelay +
    260                   hDel->config.nCoreCoderDelay +
    261                   hDel->config.nSacTimeAlignment + nDecoderAnDelay;
    262       tempDelay = (nResidualCoderFrameDelay * hDel->config.nFrameLen) +
    263                   hDel->config.nSacStreamMuxDelay - tempDelay;
    264 
    265       if (tempDelay > 0) {
    266         hDel->nBitstreamFrameBuffer = 0;
    267         hDel->nOutputAudioBuffer = tempDelay;
    268       } else {
    269         tempDelay = -tempDelay;
    270         hDel->nBitstreamFrameBuffer =
    271             (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
    272         hDel->nOutputAudioBuffer =
    273             (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen) - tempDelay;
    274       }
    275 
    276       hDel->nOutputAudioQmfFrameBuffer =
    277           (hDel->nOutputAudioBuffer + (hDel->config.nQmfLen / 2) - 1) /
    278           hDel->config.nQmfLen;
    279 
    280       if (hDel->config.bDmxAlign > 0) {
    281         tempDelay = nEncoderWinDelay + nEncoderAnDelay + nEncoderSynDelay +
    282                     hDel->nOutputAudioBuffer + hDel->config.nLimiterDelay +
    283                     hDel->config.nCoreCoderDelay;
    284         hDel->nDiscardOutFrames =
    285             (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
    286         hDel->nDmxAlignBuffer =
    287             hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
    288       } else {
    289         hDel->nDiscardOutFrames = 0;
    290         hDel->nDmxAlignBuffer = 0;
    291       }
    292 
    293       /* Output: Info-Variables */
    294       hDel->nInfoDmxDelay = hDel->nSurroundAnalysisBuffer + nEncoderAnDelay +
    295                             nEncoderWinDelay + nEncoderSynDelay +
    296                             hDel->nOutputAudioBuffer +
    297                             hDel->config.nLimiterDelay;
    298       hDel->nInfoCodecDelay =
    299           hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
    300           hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
    301 
    302     } else {
    303       /* ArbitraryDmx or TdDmx on */
    304       int tempDelay1, tempDelay2, tempDelay12, tempDelay3;
    305 
    306       tempDelay1 = hDel->config.nArbDmxDelay - hDel->config.nSurroundDelay;
    307 
    308       if (tempDelay1 >= 0) {
    309         hDel->nSurroundAnalysisBuffer = tempDelay1;
    310         hDel->nArbDmxAnalysisBuffer = 0;
    311       } else {
    312         hDel->nSurroundAnalysisBuffer = 0;
    313         hDel->nArbDmxAnalysisBuffer = -tempDelay1;
    314       }
    315 
    316       tempDelay1 = nEncoderWinDelay + hDel->config.nSurroundDelay +
    317                    hDel->nSurroundAnalysisBuffer +
    318                    nEncoderAnDelay; /*Surround Path*/
    319       tempDelay2 = nEncoderWinDelay + hDel->config.nArbDmxDelay +
    320                    hDel->nArbDmxAnalysisBuffer +
    321                    nEncoderAnDelay; /* ArbDmx Compare Path */
    322       tempDelay3 = hDel->config.nArbDmxDelay + hDel->config.nLimiterDelay +
    323                    hDel->config.nCoreCoderDelay +
    324                    hDel->config.nSacTimeAlignment +
    325                    nDecoderAnDelay; /* ArbDmx Passthrough*/
    326 
    327       tempDelay12 =
    328           FDKmax(nResidualCoderFrameDelay, nArbDmxResidualCoderFrameDelay) *
    329           hDel->config.nFrameLen;
    330       tempDelay12 += hDel->config.nSacStreamMuxDelay;
    331 
    332       if (tempDelay1 > tempDelay2) {
    333         tempDelay12 += tempDelay1;
    334       } else {
    335         tempDelay12 += tempDelay2;
    336       }
    337 
    338       if (tempDelay3 > tempDelay12) {
    339         if (hDel->config.bMinimizeDelay > 0) {
    340           hDel->nBitstreamFrameBuffer =
    341               (tempDelay3 - tempDelay12) / hDel->config.nFrameLen; /*floor*/
    342           hDel->nOutputAudioBuffer = 0;
    343           hDel->nSurroundAnalysisBuffer +=
    344               (tempDelay3 - tempDelay12 -
    345                (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
    346           hDel->nArbDmxAnalysisBuffer +=
    347               (tempDelay3 - tempDelay12 -
    348                (hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen));
    349         } else {
    350           hDel->nBitstreamFrameBuffer =
    351               ((tempDelay3 - tempDelay12) + hDel->config.nFrameLen - 1) /
    352               hDel->config.nFrameLen;
    353           hDel->nOutputAudioBuffer =
    354               hDel->nBitstreamFrameBuffer * hDel->config.nFrameLen +
    355               tempDelay12 - tempDelay3;
    356         }
    357       } else {
    358         hDel->nBitstreamFrameBuffer = 0;
    359         hDel->nOutputAudioBuffer = tempDelay12 - tempDelay3;
    360       }
    361 
    362       if (hDel->config.bDmxAlign > 0) {
    363         int tempDelay = hDel->config.nArbDmxDelay + hDel->nOutputAudioBuffer +
    364                         hDel->config.nLimiterDelay +
    365                         hDel->config.nCoreCoderDelay;
    366         hDel->nDiscardOutFrames =
    367             (tempDelay + hDel->config.nFrameLen - 1) / hDel->config.nFrameLen;
    368         hDel->nDmxAlignBuffer =
    369             hDel->nDiscardOutFrames * hDel->config.nFrameLen - tempDelay;
    370       } else {
    371         hDel->nDiscardOutFrames = 0;
    372         hDel->nDmxAlignBuffer = 0;
    373       }
    374 
    375       /* Output: Info-Variables */
    376       hDel->nInfoDmxDelay = hDel->config.nArbDmxDelay +
    377                             hDel->nOutputAudioBuffer +
    378                             hDel->config.nLimiterDelay;
    379       hDel->nInfoCodecDelay =
    380           hDel->nInfoDmxDelay + hDel->config.nCoreCoderDelay +
    381           hDel->config.nSacTimeAlignment + nDecoderAnDelay + nDecoderSynDelay;
    382       hDel->nInfoDecoderDelay = nDecoderAnDelay + nDecoderSynDelay;
    383 
    384     } /* ArbitraryDmx or TdDmx on */
    385 
    386     /* Additonal Variables needed for Computation Issues */
    387     hDel->nBitstreamFrameBufferSize = hDel->nBitstreamFrameBuffer + 1;
    388   }
    389 
    390   return error;
    391 }
    392 
    393 static FDK_SACENC_ERROR assignParameterInRange(
    394     const INT startRange, /* including startRange */
    395     const INT stopRange,  /* including stopRange */
    396     const INT value,      /* value to write*/
    397     INT *const ptr        /* destination pointer*/
    398 ) {
    399   FDK_SACENC_ERROR error = SACENC_INVALID_CONFIG;
    400 
    401   if ((startRange <= value) && (value <= stopRange)) {
    402     *ptr = value;
    403     error = SACENC_OK;
    404   }
    405 
    406   return error;
    407 }
    408 
    409 FDK_SACENC_ERROR fdk_sacenc_delay_SetDmxAlign(HANDLE_DELAY hDelay,
    410                                               const INT bDmxAlignIn) {
    411   return (assignParameterInRange(0, 1, bDmxAlignIn, &hDelay->config.bDmxAlign));
    412 }
    413 
    414 FDK_SACENC_ERROR fdk_sacenc_delay_SetTimeDomDmx(HANDLE_DELAY hDelay,
    415                                                 const INT bTimeDomDmxIn) {
    416   return (
    417       assignParameterInRange(0, 1, bTimeDomDmxIn, &hDelay->config.bTimeDomDmx));
    418 }
    419 
    420 FDK_SACENC_ERROR fdk_sacenc_delay_SetSacTimeAlignmentDynamicOut(
    421     HANDLE_DELAY hDelay, const INT bSacTimeAlignmentDynamicOutIn) {
    422   return (assignParameterInRange(0, 1, bSacTimeAlignmentDynamicOutIn,
    423                                  &hDelay->config.bSacTimeAlignmentDynamicOut));
    424 }
    425 
    426 FDK_SACENC_ERROR fdk_sacenc_delay_SetNSacTimeAlignment(
    427     HANDLE_DELAY hDelay, const INT nSacTimeAlignmentIn) {
    428   return (assignParameterInRange(-32768, 32767, nSacTimeAlignmentIn,
    429                                  &hDelay->config.nSacTimeAlignment));
    430 }
    431 
    432 FDK_SACENC_ERROR fdk_sacenc_delay_SetMinimizeDelay(HANDLE_DELAY hDelay,
    433                                                    const INT bMinimizeDelay) {
    434   return (assignParameterInRange(0, 1, bMinimizeDelay,
    435                                  &hDelay->config.bMinimizeDelay));
    436 }
    437 
    438 INT fdk_sacenc_delay_GetOutputAudioBufferDelay(HANDLE_DELAY hDelay) {
    439   return (hDelay->nOutputAudioBuffer);
    440 }
    441 
    442 INT fdk_sacenc_delay_GetSurroundAnalysisBufferDelay(HANDLE_DELAY hDelay) {
    443   return (hDelay->nSurroundAnalysisBuffer);
    444 }
    445 
    446 INT fdk_sacenc_delay_GetArbDmxAnalysisBufferDelay(HANDLE_DELAY hDelay) {
    447   return (hDelay->nArbDmxAnalysisBuffer);
    448 }
    449 
    450 INT fdk_sacenc_delay_GetBitstreamFrameBufferSize(HANDLE_DELAY hDelay) {
    451   return (hDelay->nBitstreamFrameBufferSize);
    452 }
    453 
    454 INT fdk_sacenc_delay_GetDmxAlignBufferDelay(HANDLE_DELAY hDelay) {
    455   return (hDelay->nDmxAlignBuffer);
    456 }
    457 
    458 INT fdk_sacenc_delay_GetDiscardOutFrames(HANDLE_DELAY hDelay) {
    459   return (hDelay->nDiscardOutFrames);
    460 }
    461 
    462 INT fdk_sacenc_delay_GetInfoDmxDelay(HANDLE_DELAY hDelay) {
    463   return (hDelay->nInfoDmxDelay);
    464 }
    465 
    466 INT fdk_sacenc_delay_GetInfoCodecDelay(HANDLE_DELAY hDelay) {
    467   return (hDelay->nInfoCodecDelay);
    468 }
    469 
    470 INT fdk_sacenc_delay_GetInfoDecoderDelay(HANDLE_DELAY hDelay) {
    471   return (hDelay->nInfoDecoderDelay);
    472 }
    473