1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2019 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
dct_getTables(const FIXP_WTP ** ptwiddle,const FIXP_STP ** sin_twiddle,int * sin_step,int length)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)
dct_III(FIXP_DBL * pDat,FIXP_DBL * tmp,int L,int * pDat_e)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
dst_III(FIXP_DBL * pDat,FIXP_DBL * tmp,int L,int * pDat_e)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)
dct_II(FIXP_DBL * pDat,FIXP_DBL * tmp,int L,int * pDat_e)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
dct_IV(FIXP_DBL * pDat,int L,int * pDat_e)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)
dst_IV(FIXP_DBL * pDat,int L,int * pDat_e)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] >> 1;
493 accu2 = -(pDat_0[0] >> 1);
494 accu3 = pDat_0[1] >> 1;
495 accu4 = -(pDat_1[0] >> 1);
496
497 cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
498 cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
499
500 pDat_0[0] = accu2;
501 pDat_0[1] = accu1;
502 pDat_1[0] = accu4;
503 pDat_1[1] = -accu3;
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