• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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