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