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 /******************* Library for basic calculation routines ********************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 /*!
    104   \file   dct.cpp
    105   \brief  DCT Implementations
    106   Library functions to calculate standard DCTs. This will most likely be
    107   replaced by hand-optimized functions for the specific target processor.
    108 
    109   Three different implementations of the dct type II and the dct type III
    110   transforms are provided.
    111 
    112   By default implementations which are based on a single, standard complex
    113   FFT-kernel are used (dctII_f() and dctIII_f()). These are specifically helpful
    114   in cases where optimized FFT libraries are already available. The FFT used in
    115   these implementation is FFT rad2 from FDK_tools.
    116 
    117   Of course, one might also use DCT-libraries should they be available. The DCT
    118   and DST type IV implementations are only available in a version based on a
    119   complex FFT kernel.
    120 */
    121 
    122 #include "dct.h"
    123 
    124 #include "FDK_tools_rom.h"
    125 #include "fft.h"
    126 
    127 void dct_getTables(const FIXP_WTP **ptwiddle, const FIXP_STP **sin_twiddle,
    128                    int *sin_step, int length) {
    129   const FIXP_WTP *twiddle;
    130   int ld2_length;
    131 
    132   /* Get ld2 of length - 2 + 1
    133       -2: because first table entry is window of size 4
    134       +1: because we already include +1 because of ceil(log2(length)) */
    135   ld2_length = DFRACT_BITS - 1 - fNormz((FIXP_DBL)length) - 1;
    136 
    137   /* Extract sort of "eigenvalue" (the 4 left most bits) of length. */
    138   switch ((length) >> (ld2_length - 1)) {
    139     case 0x4: /* radix 2 */
    140       *sin_twiddle = SineTable1024;
    141       *sin_step = 1 << (10 - ld2_length);
    142       twiddle = windowSlopes[0][0][ld2_length - 1];
    143       break;
    144     case 0x7: /* 10 ms */
    145       *sin_twiddle = SineTable480;
    146       *sin_step = 1 << (8 - ld2_length);
    147       twiddle = windowSlopes[0][1][ld2_length];
    148       break;
    149     case 0x6: /* 3/4 of radix 2 */
    150       *sin_twiddle = SineTable384;
    151       *sin_step = 1 << (8 - ld2_length);
    152       twiddle = windowSlopes[0][2][ld2_length];
    153       break;
    154     case 0x5: /* 5/16 of radix 2*/
    155       *sin_twiddle = SineTable80;
    156       *sin_step = 1 << (6 - ld2_length);
    157       twiddle = windowSlopes[0][3][ld2_length];
    158       break;
    159     default:
    160       *sin_twiddle = NULL;
    161       *sin_step = 0;
    162       twiddle = NULL;
    163       break;
    164   }
    165 
    166   if (ptwiddle != NULL) {
    167     FDK_ASSERT(twiddle != NULL);
    168     *ptwiddle = twiddle;
    169   }
    170 
    171   FDK_ASSERT(*sin_step > 0);
    172 }
    173 
    174 #if !defined(FUNCTION_dct_III)
    175 void dct_III(FIXP_DBL *pDat, /*!< pointer to input/output */
    176              FIXP_DBL *tmp,  /*!< pointer to temporal working buffer */
    177              int L,          /*!< lenght of transform */
    178              int *pDat_e) {
    179   const FIXP_WTP *sin_twiddle;
    180   int i;
    181   FIXP_DBL xr, accu1, accu2;
    182   int inc, index;
    183   int M = L >> 1;
    184 
    185   FDK_ASSERT(L % 4 == 0);
    186   dct_getTables(NULL, &sin_twiddle, &inc, L);
    187   inc >>= 1;
    188 
    189   FIXP_DBL *pTmp_0 = &tmp[2];
    190   FIXP_DBL *pTmp_1 = &tmp[(M - 1) * 2];
    191 
    192   index = 4 * inc;
    193 
    194   /* This loop performs multiplication for index i (i*inc) */
    195   for (i = 1; i<M>> 1; i++, pTmp_0 += 2, pTmp_1 -= 2) {
    196     FIXP_DBL accu3, accu4, accu5, accu6;
    197 
    198     cplxMultDiv2(&accu2, &accu1, pDat[L - i], pDat[i], sin_twiddle[i * inc]);
    199     cplxMultDiv2(&accu4, &accu3, pDat[M + i], pDat[M - i],
    200                  sin_twiddle[(M - i) * inc]);
    201     accu3 >>= 1;
    202     accu4 >>= 1;
    203 
    204     /* This method is better for ARM926, that uses operand2 shifted right by 1
    205      * always */
    206     if (2 * i < (M / 2)) {
    207       cplxMultDiv2(&accu6, &accu5, (accu3 - (accu1 >> 1)),
    208                    ((accu2 >> 1) + accu4), sin_twiddle[index]);
    209     } else {
    210       cplxMultDiv2(&accu6, &accu5, ((accu2 >> 1) + accu4),
    211                    (accu3 - (accu1 >> 1)), sin_twiddle[index]);
    212       accu6 = -accu6;
    213     }
    214     xr = (accu1 >> 1) + accu3;
    215     pTmp_0[0] = (xr >> 1) - accu5;
    216     pTmp_1[0] = (xr >> 1) + accu5;
    217 
    218     xr = (accu2 >> 1) - accu4;
    219     pTmp_0[1] = (xr >> 1) - accu6;
    220     pTmp_1[1] = -((xr >> 1) + accu6);
    221 
    222     /* Create index helper variables for (4*i)*inc indexed equivalent values of
    223      * short tables. */
    224     if (2 * i < ((M / 2) - 1)) {
    225       index += 4 * inc;
    226     } else if (2 * i >= ((M / 2))) {
    227       index -= 4 * inc;
    228     }
    229   }
    230 
    231   xr = fMultDiv2(pDat[M], sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
    232   tmp[0] = ((pDat[0] >> 1) + xr) >> 1;
    233   tmp[1] = ((pDat[0] >> 1) - xr) >> 1;
    234 
    235   cplxMultDiv2(&accu2, &accu1, pDat[L - (M / 2)], pDat[M / 2],
    236                sin_twiddle[M * inc / 2]);
    237   tmp[M] = accu1 >> 1;
    238   tmp[M + 1] = accu2 >> 1;
    239 
    240   /* dit_fft expects 1 bit scaled input values */
    241   fft(M, tmp, pDat_e);
    242 
    243   /* ARM926: 12 cycles per 2-iteration, no overhead code by compiler */
    244   pTmp_1 = &tmp[L];
    245   for (i = M >> 1; i--;) {
    246     FIXP_DBL tmp1, tmp2, tmp3, tmp4;
    247     tmp1 = *tmp++;
    248     tmp2 = *tmp++;
    249     tmp3 = *--pTmp_1;
    250     tmp4 = *--pTmp_1;
    251     *pDat++ = tmp1;
    252     *pDat++ = tmp3;
    253     *pDat++ = tmp2;
    254     *pDat++ = tmp4;
    255   }
    256 
    257   *pDat_e += 2;
    258 }
    259 
    260 void dst_III(FIXP_DBL *pDat, /*!< pointer to input/output */
    261              FIXP_DBL *tmp,  /*!< pointer to temporal working buffer */
    262              int L,          /*!< lenght of transform */
    263              int *pDat_e) {
    264   int L2 = L >> 1;
    265   int i;
    266   FIXP_DBL t;
    267 
    268   /* note: DCT III is reused here, direct DST III implementation might be more
    269    * efficient */
    270 
    271   /* mirror input */
    272   for (i = 0; i < L2; i++) {
    273     t = pDat[i];
    274     pDat[i] = pDat[L - 1 - i];
    275     pDat[L - 1 - i] = t;
    276   }
    277 
    278   /* DCT-III */
    279   dct_III(pDat, tmp, L, pDat_e);
    280 
    281   /* flip signs at odd indices */
    282   for (i = 1; i < L; i += 2) pDat[i] = -pDat[i];
    283 }
    284 
    285 #endif
    286 
    287 #if !defined(FUNCTION_dct_II)
    288 void dct_II(
    289     FIXP_DBL *pDat, /*!< pointer to input/output */
    290     FIXP_DBL *tmp,  /*!< pointer to temporal working buffer */
    291     int L, /*!< lenght of transform (has to be a multiple of 8 (or 4 in case
    292               DCT_II_L_MULTIPLE_OF_4_SUPPORT is defined) */
    293     int *pDat_e) {
    294   const FIXP_WTP *sin_twiddle;
    295   FIXP_DBL accu1, accu2;
    296   FIXP_DBL *pTmp_0, *pTmp_1;
    297 
    298   int i;
    299   int inc, index = 0;
    300   int M = L >> 1;
    301 
    302   FDK_ASSERT(L % 4 == 0);
    303   dct_getTables(NULL, &sin_twiddle, &inc, L);
    304   inc >>= 1;
    305 
    306   {
    307     for (i = 0; i < M; i++) {
    308       tmp[i] = pDat[2 * i] >> 1; /* dit_fft expects 1 bit scaled input values */
    309       tmp[L - 1 - i] =
    310           pDat[2 * i + 1] >> 1; /* dit_fft expects 1 bit scaled input values */
    311     }
    312   }
    313 
    314   fft(M, tmp, pDat_e);
    315 
    316   pTmp_0 = &tmp[2];
    317   pTmp_1 = &tmp[(M - 1) * 2];
    318 
    319   index = inc * 4;
    320 
    321   for (i = 1; i<M>> 1; i++, pTmp_0 += 2, pTmp_1 -= 2) {
    322     FIXP_DBL a1, a2;
    323     FIXP_DBL accu3, accu4;
    324 
    325     a1 = ((pTmp_0[1] >> 1) + (pTmp_1[1] >> 1));
    326     a2 = ((pTmp_1[0] >> 1) - (pTmp_0[0] >> 1));
    327 
    328     if (2 * i < (M / 2)) {
    329       cplxMultDiv2(&accu1, &accu2, a2, a1, sin_twiddle[index]);
    330     } else {
    331       cplxMultDiv2(&accu1, &accu2, a1, a2, sin_twiddle[index]);
    332       accu1 = -accu1;
    333     }
    334     accu1 <<= 1;
    335     accu2 <<= 1;
    336 
    337     a1 = ((pTmp_0[0] >> 1) + (pTmp_1[0] >> 1));
    338     a2 = ((pTmp_0[1] >> 1) - (pTmp_1[1] >> 1));
    339 
    340     cplxMultDiv2(&accu3, &accu4, (a1 + accu2), -(accu1 + a2),
    341                  sin_twiddle[i * inc]);
    342     pDat[L - i] = accu4;
    343     pDat[i] = accu3;
    344 
    345     cplxMultDiv2(&accu3, &accu4, (a1 - accu2), -(accu1 - a2),
    346                  sin_twiddle[(M - i) * inc]);
    347     pDat[M + i] = accu4;
    348     pDat[M - i] = accu3;
    349 
    350     /* Create index helper variables for (4*i)*inc indexed equivalent values of
    351      * short tables. */
    352     if (2 * i < ((M / 2) - 1)) {
    353       index += 4 * inc;
    354     } else if (2 * i >= ((M / 2))) {
    355       index -= 4 * inc;
    356     }
    357   }
    358 
    359   cplxMultDiv2(&accu1, &accu2, tmp[M], tmp[M + 1], sin_twiddle[(M / 2) * inc]);
    360   pDat[L - (M / 2)] = accu2;
    361   pDat[M / 2] = accu1;
    362 
    363   pDat[0] = (tmp[0] >> 1) + (tmp[1] >> 1);
    364   pDat[M] = fMult(((tmp[0] >> 1) - (tmp[1] >> 1)),
    365                   sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
    366 
    367   *pDat_e += 2;
    368 }
    369 #endif
    370 
    371 #if !defined(FUNCTION_dct_IV)
    372 
    373 void dct_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
    374   int sin_step = 0;
    375   int M = L >> 1;
    376 
    377   const FIXP_WTP *twiddle;
    378   const FIXP_STP *sin_twiddle;
    379 
    380   FDK_ASSERT(L >= 4);
    381 
    382   FDK_ASSERT(L >= 4);
    383 
    384   dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
    385 
    386   {
    387     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
    388     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
    389     int i;
    390 
    391     /* 29 cycles on ARM926 */
    392     for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
    393       FIXP_DBL accu1, accu2, accu3, accu4;
    394 
    395       accu1 = pDat_1[1];
    396       accu2 = pDat_0[0];
    397       accu3 = pDat_0[1];
    398       accu4 = pDat_1[0];
    399 
    400       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
    401       cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
    402 
    403       pDat_0[0] = accu2 >> 1;
    404       pDat_0[1] = accu1 >> 1;
    405       pDat_1[0] = accu4 >> 1;
    406       pDat_1[1] = -(accu3 >> 1);
    407     }
    408     if (M & 1) {
    409       FIXP_DBL accu1, accu2;
    410 
    411       accu1 = pDat_1[1];
    412       accu2 = pDat_0[0];
    413 
    414       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
    415 
    416       pDat_0[0] = accu2 >> 1;
    417       pDat_0[1] = accu1 >> 1;
    418     }
    419   }
    420 
    421   fft(M, pDat, pDat_e);
    422 
    423   {
    424     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
    425     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
    426     FIXP_DBL accu1, accu2, accu3, accu4;
    427     int idx, i;
    428 
    429     /* Sin and Cos values are 0.0f and 1.0f */
    430     accu1 = pDat_1[0];
    431     accu2 = pDat_1[1];
    432 
    433     pDat_1[1] = -pDat_0[1];
    434 
    435     /* 28 cycles for ARM926 */
    436     for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
    437       FIXP_STP twd = sin_twiddle[idx];
    438       cplxMult(&accu3, &accu4, accu1, accu2, twd);
    439       pDat_0[1] = accu3;
    440       pDat_1[0] = accu4;
    441 
    442       pDat_0 += 2;
    443       pDat_1 -= 2;
    444 
    445       cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
    446 
    447       accu1 = pDat_1[0];
    448       accu2 = pDat_1[1];
    449 
    450       pDat_1[1] = -accu3;
    451       pDat_0[0] = accu4;
    452     }
    453 
    454     if ((M & 1) == 0) {
    455       /* Last Sin and Cos value pair are the same */
    456       accu1 = fMult(accu1, WTC(0x5a82799a));
    457       accu2 = fMult(accu2, WTC(0x5a82799a));
    458 
    459       pDat_1[0] = accu1 + accu2;
    460       pDat_0[1] = accu1 - accu2;
    461     }
    462   }
    463 
    464   /* Add twiddeling scale. */
    465   *pDat_e += 2;
    466 }
    467 #endif /* defined (FUNCTION_dct_IV) */
    468 
    469 #if !defined(FUNCTION_dst_IV)
    470 void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
    471   int sin_step = 0;
    472   int M = L >> 1;
    473 
    474   const FIXP_WTP *twiddle;
    475   const FIXP_STP *sin_twiddle;
    476 
    477   FDK_ASSERT(L >= 4);
    478 
    479   FDK_ASSERT(L >= 4);
    480 
    481   dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
    482 
    483   {
    484     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
    485     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
    486     int i;
    487 
    488     /* 34 cycles on ARM926 */
    489     for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
    490       FIXP_DBL accu1, accu2, accu3, accu4;
    491 
    492       accu1 = pDat_1[1];
    493       accu2 = -pDat_0[0];
    494       accu3 = pDat_0[1];
    495       accu4 = -pDat_1[0];
    496 
    497       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
    498       cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
    499 
    500       pDat_0[0] = accu2 >> 1;
    501       pDat_0[1] = accu1 >> 1;
    502       pDat_1[0] = accu4 >> 1;
    503       pDat_1[1] = -(accu3 >> 1);
    504     }
    505     if (M & 1) {
    506       FIXP_DBL accu1, accu2;
    507 
    508       accu1 = pDat_1[1];
    509       accu2 = -pDat_0[0];
    510 
    511       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
    512 
    513       pDat_0[0] = accu2 >> 1;
    514       pDat_0[1] = accu1 >> 1;
    515     }
    516   }
    517 
    518   fft(M, pDat, pDat_e);
    519 
    520   {
    521     FIXP_DBL *RESTRICT pDat_0;
    522     FIXP_DBL *RESTRICT pDat_1;
    523     FIXP_DBL accu1, accu2, accu3, accu4;
    524     int idx, i;
    525 
    526     pDat_0 = &pDat[0];
    527     pDat_1 = &pDat[L - 2];
    528 
    529     /* Sin and Cos values are 0.0f and 1.0f */
    530     accu1 = pDat_1[0];
    531     accu2 = pDat_1[1];
    532 
    533     pDat_1[1] = -pDat_0[0];
    534     pDat_0[0] = pDat_0[1];
    535 
    536     for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
    537       FIXP_STP twd = sin_twiddle[idx];
    538 
    539       cplxMult(&accu3, &accu4, accu1, accu2, twd);
    540       pDat_1[0] = -accu3;
    541       pDat_0[1] = -accu4;
    542 
    543       pDat_0 += 2;
    544       pDat_1 -= 2;
    545 
    546       cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
    547 
    548       accu1 = pDat_1[0];
    549       accu2 = pDat_1[1];
    550 
    551       pDat_0[0] = accu3;
    552       pDat_1[1] = -accu4;
    553     }
    554 
    555     if ((M & 1) == 0) {
    556       /* Last Sin and Cos value pair are the same */
    557       accu1 = fMult(accu1, WTC(0x5a82799a));
    558       accu2 = fMult(accu2, WTC(0x5a82799a));
    559 
    560       pDat_0[1] = -accu1 - accu2;
    561       pDat_1[0] = accu2 - accu1;
    562     }
    563   }
    564 
    565   /* Add twiddeling scale. */
    566   *pDat_e += 2;
    567 }
    568 #endif /* !defined(FUNCTION_dst_IV) */
    569