• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2020 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] >> 2;
309       tmp[L - 1 - i] = pDat[2 * i + 1] >> 2;
310     }
311   }
312 
313   fft(M, tmp, pDat_e);
314 
315   pTmp_0 = &tmp[2];
316   pTmp_1 = &tmp[(M - 1) * 2];
317 
318   index = inc * 4;
319 
320   for (i = 1; i<M>> 1; i++, pTmp_0 += 2, pTmp_1 -= 2) {
321     FIXP_DBL a1, a2;
322     FIXP_DBL accu3, accu4;
323 
324     a1 = ((pTmp_0[1] >> 1) + (pTmp_1[1] >> 1));
325     a2 = ((pTmp_1[0] >> 1) - (pTmp_0[0] >> 1));
326 
327     if (2 * i < (M / 2)) {
328       cplxMultDiv2(&accu1, &accu2, a2, a1, sin_twiddle[index]);
329     } else {
330       cplxMultDiv2(&accu1, &accu2, a1, a2, sin_twiddle[index]);
331       accu1 = -accu1;
332     }
333     accu1 <<= 1;
334     accu2 <<= 1;
335 
336     a1 = ((pTmp_0[0] >> 1) + (pTmp_1[0] >> 1));
337     a2 = ((pTmp_0[1] >> 1) - (pTmp_1[1] >> 1));
338 
339     cplxMult(&accu3, &accu4, (accu1 + a2), (a1 + accu2), sin_twiddle[i * inc]);
340     pDat[L - i] = -accu3;
341     pDat[i] = accu4;
342 
343     cplxMult(&accu3, &accu4, (accu1 - a2), (a1 - accu2),
344              sin_twiddle[(M - i) * inc]);
345     pDat[M + i] = -accu3;
346     pDat[M - i] = accu4;
347 
348     /* Create index helper variables for (4*i)*inc indexed equivalent values of
349      * short tables. */
350     if (2 * i < ((M / 2) - 1)) {
351       index += 4 * inc;
352     } else if (2 * i >= ((M / 2))) {
353       index -= 4 * inc;
354     }
355   }
356 
357   cplxMult(&accu1, &accu2, tmp[M], tmp[M + 1], sin_twiddle[(M / 2) * inc]);
358   pDat[L - (M / 2)] = accu2;
359   pDat[M / 2] = accu1;
360 
361   pDat[0] = tmp[0] + tmp[1];
362   pDat[M] = fMult(tmp[0] - tmp[1],
363                   sin_twiddle[M * inc].v.re); /* cos((PI/(2*L))*M); */
364 
365   *pDat_e += 2;
366 }
367 #endif
368 
369 #if !defined(FUNCTION_dct_IV)
370 
dct_IV(FIXP_DBL * pDat,int L,int * pDat_e)371 void dct_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
372   int sin_step = 0;
373   int M = L >> 1;
374 
375   const FIXP_WTP *twiddle;
376   const FIXP_STP *sin_twiddle;
377 
378   FDK_ASSERT(L >= 4);
379 
380   FDK_ASSERT(L >= 4);
381 
382   dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
383 
384   {
385     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
386     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
387     int i;
388 
389     /* 29 cycles on ARM926 */
390     for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
391       FIXP_DBL accu1, accu2, accu3, accu4;
392 
393       accu1 = pDat_1[1];
394       accu2 = pDat_0[0];
395       accu3 = pDat_0[1];
396       accu4 = pDat_1[0];
397 
398       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
399       cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
400 
401       pDat_0[0] = accu2 >> 1;
402       pDat_0[1] = accu1 >> 1;
403       pDat_1[0] = accu4 >> 1;
404       pDat_1[1] = -(accu3 >> 1);
405     }
406     if (M & 1) {
407       FIXP_DBL accu1, accu2;
408 
409       accu1 = pDat_1[1];
410       accu2 = pDat_0[0];
411 
412       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
413 
414       pDat_0[0] = accu2 >> 1;
415       pDat_0[1] = accu1 >> 1;
416     }
417   }
418 
419   fft(M, pDat, pDat_e);
420 
421   {
422     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
423     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
424     FIXP_DBL accu1, accu2, accu3, accu4;
425     int idx, i;
426 
427     /* Sin and Cos values are 0.0f and 1.0f */
428     accu1 = pDat_1[0];
429     accu2 = pDat_1[1];
430 
431     pDat_1[1] = -pDat_0[1];
432 
433     /* 28 cycles for ARM926 */
434     for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
435       FIXP_STP twd = sin_twiddle[idx];
436       cplxMult(&accu3, &accu4, accu1, accu2, twd);
437       pDat_0[1] = accu3;
438       pDat_1[0] = accu4;
439 
440       pDat_0 += 2;
441       pDat_1 -= 2;
442 
443       cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
444 
445       accu1 = pDat_1[0];
446       accu2 = pDat_1[1];
447 
448       pDat_1[1] = -accu3;
449       pDat_0[0] = accu4;
450     }
451 
452     if ((M & 1) == 0) {
453       /* Last Sin and Cos value pair are the same */
454       accu1 = fMult(accu1, WTC(0x5a82799a));
455       accu2 = fMult(accu2, WTC(0x5a82799a));
456 
457       pDat_1[0] = accu1 + accu2;
458       pDat_0[1] = accu1 - accu2;
459     }
460   }
461 
462   /* Add twiddeling scale. */
463   *pDat_e += 2;
464 }
465 #endif /* defined (FUNCTION_dct_IV) */
466 
467 #if !defined(FUNCTION_dst_IV)
dst_IV(FIXP_DBL * pDat,int L,int * pDat_e)468 void dst_IV(FIXP_DBL *pDat, int L, int *pDat_e) {
469   int sin_step = 0;
470   int M = L >> 1;
471 
472   const FIXP_WTP *twiddle;
473   const FIXP_STP *sin_twiddle;
474 
475   FDK_ASSERT(L >= 4);
476 
477   FDK_ASSERT(L >= 4);
478 
479   dct_getTables(&twiddle, &sin_twiddle, &sin_step, L);
480 
481   {
482     FIXP_DBL *RESTRICT pDat_0 = &pDat[0];
483     FIXP_DBL *RESTRICT pDat_1 = &pDat[L - 2];
484     int i;
485 
486     /* 34 cycles on ARM926 */
487     for (i = 0; i < M - 1; i += 2, pDat_0 += 2, pDat_1 -= 2) {
488       FIXP_DBL accu1, accu2, accu3, accu4;
489 
490       accu1 = pDat_1[1] >> 1;
491       accu2 = -(pDat_0[0] >> 1);
492       accu3 = pDat_0[1] >> 1;
493       accu4 = -(pDat_1[0] >> 1);
494 
495       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
496       cplxMultDiv2(&accu3, &accu4, accu4, accu3, twiddle[i + 1]);
497 
498       pDat_0[0] = accu2;
499       pDat_0[1] = accu1;
500       pDat_1[0] = accu4;
501       pDat_1[1] = -accu3;
502     }
503     if (M & 1) {
504       FIXP_DBL accu1, accu2;
505 
506       accu1 = pDat_1[1];
507       accu2 = -pDat_0[0];
508 
509       cplxMultDiv2(&accu1, &accu2, accu1, accu2, twiddle[i]);
510 
511       pDat_0[0] = accu2 >> 1;
512       pDat_0[1] = accu1 >> 1;
513     }
514   }
515 
516   fft(M, pDat, pDat_e);
517 
518   {
519     FIXP_DBL *RESTRICT pDat_0;
520     FIXP_DBL *RESTRICT pDat_1;
521     FIXP_DBL accu1, accu2, accu3, accu4;
522     int idx, i;
523 
524     pDat_0 = &pDat[0];
525     pDat_1 = &pDat[L - 2];
526 
527     /* Sin and Cos values are 0.0f and 1.0f */
528     accu1 = pDat_1[0];
529     accu2 = pDat_1[1];
530 
531     pDat_1[1] = -pDat_0[0];
532     pDat_0[0] = pDat_0[1];
533 
534     for (idx = sin_step, i = 1; i<(M + 1)>> 1; i++, idx += sin_step) {
535       FIXP_STP twd = sin_twiddle[idx];
536 
537       cplxMult(&accu3, &accu4, accu1, accu2, twd);
538       pDat_1[0] = -accu3;
539       pDat_0[1] = -accu4;
540 
541       pDat_0 += 2;
542       pDat_1 -= 2;
543 
544       cplxMult(&accu3, &accu4, pDat_0[1], pDat_0[0], twd);
545 
546       accu1 = pDat_1[0];
547       accu2 = pDat_1[1];
548 
549       pDat_0[0] = accu3;
550       pDat_1[1] = -accu4;
551     }
552 
553     if ((M & 1) == 0) {
554       /* Last Sin and Cos value pair are the same */
555       accu1 = fMult(accu1, WTC(0x5a82799a));
556       accu2 = fMult(accu2, WTC(0x5a82799a));
557 
558       pDat_0[1] = -accu1 - accu2;
559       pDat_1[0] = accu2 - accu1;
560     }
561   }
562 
563   /* Add twiddeling scale. */
564   *pDat_e += 2;
565 }
566 #endif /* !defined(FUNCTION_dst_IV) */
567