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