1 
2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
4 
5 � Copyright  1995 - 2013 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6   All rights reserved.
7 
8  1.    INTRODUCTION
9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12 
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16 of the MPEG specifications.
17 
18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20 individually for the purpose of encoding or decoding bit streams in products that are compliant with
21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23 software may already be covered under those patent licenses when it is used for those licensed purposes only.
24 
25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27 applications information and documentation.
28 
29 2.    COPYRIGHT LICENSE
30 
31 Redistribution and use in source and binary forms, with or without modification, are permitted without
32 payment of copyright license fees provided that you satisfy the following conditions:
33 
34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35 your modifications thereto in source code form.
36 
37 You must retain the complete text of this software license in the documentation and/or other materials
38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40 modifications thereto to recipients of copies in binary form.
41 
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
44 
45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46 software or your modifications thereto.
47 
48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49 and the date of any change. For modified versions of the FDK AAC Codec, the term
50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52 
53 3.    NO PATENT LICENSE
54 
55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57 respect to this software.
58 
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
61 
62 4.    DISCLAIMER
63 
64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69 or business interruption, however caused and on any theory of liability, whether in contract, strict
70 liability, or tort (including negligence), arising in any way out of the use of this software, even if
71 advised of the possibility of such damage.
72 
73 5.    CONTACT INFORMATION
74 
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
77 Am Wolfsmantel 33
78 91058 Erlangen, Germany
79 
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
83 
84 /***************************  Fraunhofer IIS FDK Tools  **********************
85 
86    Author(s):   M. Lohwasser, M. Gayer
87    Description:
88 
89 ******************************************************************************/
90 
91 #include "fft_rad2.h"
92 
93 #include "scramble.h"
94 
95 #define __FFT_RAD2_CPP__
96 
97 #if defined(__arm__)	/* cppp replaced: elif */
98 #include "arm/fft_rad2_arm.cpp"
99 
100 #elif defined(__GNUC__) && defined(__mips__) && defined(__mips_dsp)	/* cppp replaced: elif */
101 #include "mips/fft_rad2_mips.cpp"
102 
103 #endif
104 
105 
106 
107 /*****************************************************************************
108 
109     functionname: dit_fft (analysis)
110     description:  dit-tukey-algorithm
111                   scrambles data at entry
112                   i.e. loop is made with scrambled data
113     returns:
114     input:
115     output:
116 
117 *****************************************************************************/
118 
119 #ifndef FUNCTION_dit_fft
120 
dit_fft(FIXP_DBL * x,const INT ldn,const FIXP_STP * trigdata,const INT trigDataSize)121 void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize)
122 {
123     const INT n=1<<ldn;
124     INT trigstep,i,ldm;
125 
126     scramble(x,n);
127     /*
128      * 1+2 stage radix 4
129      */
130 
131     for (i=0;i<n*2;i+=8)
132     {
133       FIXP_DBL a00, a10, a20, a30;
134       a00 = (x[i + 0] + x[i + 2])>>1;  /* Re A + Re B */
135       a10 = (x[i + 4] + x[i + 6])>>1;  /* Re C + Re D */
136       a20 = (x[i + 1] + x[i + 3])>>1;  /* Im A + Im B */
137       a30 = (x[i + 5] + x[i + 7])>>1;  /* Im C + Im D */
138 
139       x[i + 0] = a00 + a10;       /* Re A' = Re A + Re B + Re C + Re D */
140       x[i + 4] = a00 - a10;       /* Re C' = Re A + Re B - Re C - Re D */
141       x[i + 1] = a20 + a30;       /* Im A' = Im A + Im B + Im C + Im D */
142       x[i + 5] = a20 - a30;       /* Im C' = Im A + Im B - Im C - Im D */
143 
144       a00 = a00 - x[i + 2];       /* Re A - Re B */
145       a10 = a10 - x[i + 6];       /* Re C - Re D */
146       a20 = a20 - x[i + 3];       /* Im A - Im B */
147       a30 = a30 - x[i + 7];       /* Im C - Im D */
148 
149       x[i + 2] = a00 + a30;       /* Re B' = Re A - Re B + Im C - Im D */
150       x[i + 6] = a00 - a30;       /* Re D' = Re A - Re B - Im C + Im D */
151       x[i + 3] = a20 - a10;       /* Im B' = Im A - Im B - Re C + Re D */
152       x[i + 7] = a20 + a10;       /* Im D' = Im A - Im B + Re C - Re D */
153     }
154 
155     for(ldm=3; ldm<=ldn; ++ldm)
156     {
157         INT m=(1<<ldm);
158         INT mh=(m>>1);
159         INT j,r;
160 
161         trigstep=((trigDataSize << 2)>>ldm);
162 
163         FDK_ASSERT(trigstep > 0);
164 
165         /* Do first iteration with c=1.0 and s=0.0 separately to avoid loosing to much precision.
166            Beware: The impact on the overal FFT precision is rather large. */
167         {
168             j = 0;
169 
170             for(r=0; r<n; r+=m)
171             {
172                 INT t1 = (r+j)<<1;
173                 INT t2 = t1 + (mh<<1);
174                 FIXP_DBL vr,vi,ur,ui;
175 
176                 //cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
177                 vi = x[t2+1]>>1;
178                 vr = x[t2]>>1;
179 
180                 ur = x[t1]>>1;
181                 ui = x[t1+1]>>1;
182 
183                 x[t1]   = ur+vr;
184                 x[t1+1] = ui+vi;
185 
186                 x[t2]   = ur-vr;
187                 x[t2+1] = ui-vi;
188 
189                 t1 += mh;
190                 t2 = t1+(mh<<1);
191 
192                 //cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], (FIXP_SGL)1.0, (FIXP_SGL)0.0);
193                 vr = x[t2+1]>>1;
194                 vi = x[t2]>>1;
195 
196                 ur = x[t1]>>1;
197                 ui = x[t1+1]>>1;
198 
199                 x[t1]   = ur+vr;
200                 x[t1+1] = ui-vi;
201 
202                 x[t2]   = ur-vr;
203                 x[t2+1] = ui+vi;
204             }
205         }
206         for(j=1; j<mh/4; ++j)
207         {
208             FIXP_STP cs;
209 
210             cs = trigdata[j*trigstep];
211 
212             for(r=0; r<n; r+=m)
213             {
214                 INT t1 = (r+j)<<1;
215                 INT t2 = t1 + (mh<<1);
216                 FIXP_DBL vr,vi,ur,ui;
217 
218                 cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], cs);
219 
220                 ur = x[t1]>>1;
221                 ui = x[t1+1]>>1;
222 
223                 x[t1]   = ur+vr;
224                 x[t1+1] = ui+vi;
225 
226                 x[t2]   = ur-vr;
227                 x[t2+1] = ui-vi;
228 
229                 t1 += mh;
230                 t2 = t1+(mh<<1);
231 
232                 cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], cs);
233 
234                 ur = x[t1]>>1;
235                 ui = x[t1+1]>>1;
236 
237                 x[t1]   = ur+vr;
238                 x[t1+1] = ui-vi;
239 
240                 x[t2]   = ur-vr;
241                 x[t2+1] = ui+vi;
242 
243                 /* Same as above but for t1,t2 with j>mh/4 and thus cs swapped */
244                 t1 = (r+mh/2-j)<<1;
245                 t2 = t1 + (mh<<1);
246 
247                 cplxMultDiv2(&vi, &vr, x[t2], x[t2+1], cs);
248 
249                 ur = x[t1]>>1;
250                 ui = x[t1+1]>>1;
251 
252                 x[t1]   = ur+vr;
253                 x[t1+1] = ui-vi;
254 
255                 x[t2]   = ur-vr;
256                 x[t2+1] = ui+vi;
257 
258                 t1 += mh;
259                 t2 = t1+(mh<<1);
260 
261                 cplxMultDiv2(&vr, &vi, x[t2], x[t2+1], cs);
262 
263                 ur = x[t1]>>1;
264                 ui = x[t1+1]>>1;
265 
266                 x[t1]   = ur-vr;
267                 x[t1+1] = ui-vi;
268 
269                 x[t2]   = ur+vr;
270                 x[t2+1] = ui+vi;
271             }
272         }
273         {
274             j = mh/4;
275 
276             for(r=0; r<n; r+=m)
277             {
278                 INT t1 = (r+j)<<1;
279                 INT t2 = t1 + (mh<<1);
280                 FIXP_DBL vr,vi,ur,ui;
281 
282                 cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], STC(0x5a82799a), STC(0x5a82799a));
283 
284                 ur = x[t1]>>1;
285                 ui = x[t1+1]>>1;
286 
287                 x[t1]   = ur+vr;
288                 x[t1+1] = ui+vi;
289 
290                 x[t2]   = ur-vr;
291                 x[t2+1] = ui-vi;
292 
293                 t1 += mh;
294                 t2 = t1+(mh<<1);
295 
296                 cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], STC(0x5a82799a), STC(0x5a82799a));
297 
298                 ur = x[t1]>>1;
299                 ui = x[t1+1]>>1;
300 
301                 x[t1]   = ur+vr;
302                 x[t1+1] = ui-vi;
303 
304                 x[t2]   = ur-vr;
305                 x[t2+1] = ui+vi;
306             }
307         }
308     }
309 }
310 #endif
311 
312 
313 /*****************************************************************************
314 
315     functionname: dit_ifft (synthesis)
316     description:  dit-tukey-algorithm
317                   scrambles data at entry
318                   i.e. loop is made with scrambled data
319     returns:
320     input:
321     output:
322 
323 *****************************************************************************/
324 
325 #if !defined(FUNCTION_dit_ifft)
dit_ifft(FIXP_DBL * x,const INT ldn,const FIXP_STP * trigdata,const INT trigDataSize)326 void dit_ifft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize)
327 {
328     const INT n=1<<ldn;
329     INT trigstep,i,ldm;
330 
331     scramble(x,n);
332 
333     /*
334       1+2 stage radix 4
335     */
336 
337     for (i=0;i<n*2;i+=8)
338     {
339       FIXP_DBL a0, a1, a2, a3, a00, a10, a20, a30;
340 
341       a00 = (x[i + 0] + x[i + 2])>>1;   /* Re A + Re B */
342       a10 = (x[i + 4] + x[i + 6])>>1;   /* Re C + Re D */
343       a20 = (x[i + 1] + x[i + 3])>>1;   /* Im A + Im B */
344       a30 = (x[i + 5] + x[i + 7])>>1;   /* Im C + Im D */
345       a0  = (x[i + 0] - x[i + 2])>>1;   /* Re A - Re B */
346       a2  = (x[i + 4] - x[i + 6])>>1;   /* Re C - Re D */
347       a3  = (x[i + 1] - x[i + 3])>>1;   /* Im A - Im B */
348       a1  = (x[i + 5] - x[i + 7])>>1;   /* Im C - Im D */
349 
350       x[i + 0] = a00 + a10;    /* Re A' = Re A + Re B + Re C + Re D */
351       x[i + 4] = a00 - a10;    /* Re C' = Re A + Re B - Re C - Re D */
352       x[i + 1] = a20 + a30;    /* Im A' = Im A + Im B + Im C + Im D */
353       x[i + 5] = a20 - a30;    /* Im C' = Im A + Im B - Im C - Im D */
354       x[i + 2] = a0 - a1;      /* Re B' = Re A - Re B - Im C + Im D */
355       x[i + 6] = a0 + a1;      /* Re D' = Re A - Re B + Im C - Im D */
356       x[i + 3] = a3 + a2;      /* Im B' = Im A - Im B + Re C - Re D */
357       x[i + 7] = a3 - a2;      /* Im D' = Im A - Im B - Re C + Re D */
358     }
359 
360     for(ldm=3; ldm<=ldn; ++ldm)
361     {
362         const INT m=(1<<ldm);
363         const INT mh=(m>>1);
364 
365         INT j,r;
366 
367         trigstep=((trigDataSize << 2)>>ldm);
368 
369         {
370             j = 0;
371 
372             for(r=0; r<n; r+=m)
373             {
374                 INT t1 = (r+j)<<1;
375                 INT t2 = t1 + (mh<<1);
376                 FIXP_DBL vr,vi,ur,ui;
377 
378                 //cplxMultDiv2(&vr, &vi, x[t2], x[t2+1], FL2FXCONST_SGL(1.0), (FIXP_SGL)0.0);
379                 vi = x[t2+1]>>1;
380                 vr = x[t2]>>1;
381 
382                 ur = x[t1]>>1;
383                 ui = x[t1+1]>>1;
384 
385                 x[t1]   = ur+vr;
386                 x[t1+1] = ui+vi;
387 
388                 x[t2]   = ur-vr;
389                 x[t2+1] = ui-vi;
390 
391                 t1 += mh;
392                 t2 = t1+(mh<<1);
393 
394                 //cplxMultDiv2(&vi, &vr, x[t2], x[t2+1], FL2FXCONST_SGL(1.0), FL2FXCONST_SGL(0.0));
395                 vr = x[t2+1]>>1;
396                 vi = x[t2]>>1;
397 
398                 ur = x[t1]>>1;
399                 ui = x[t1+1]>>1;
400 
401                 x[t1]   = ur-vr;
402                 x[t1+1] = ui+vi;
403 
404                 x[t2]   = ur+vr;
405                 x[t2+1] = ui-vi;
406             }
407         }
408         for(j=1; j<mh/4; ++j)
409         {
410             FIXP_STP cs;
411 
412             cs = trigdata[j*trigstep];
413 
414             for(r=0; r<n; r+=m)
415             {
416                 INT t1 = (r+j)<<1;
417                 INT t2 = t1 + (mh<<1);
418                 FIXP_DBL vr,vi,ur,ui;
419 
420                 cplxMultDiv2(&vr, &vi, x[t2], x[t2+1], cs);
421 
422                 ur = x[t1]>>1;
423                 ui = x[t1+1]>>1;
424 
425                 x[t1]   = ur+vr;
426                 x[t1+1] = ui+vi;
427 
428                 x[t2]   = ur-vr;
429                 x[t2+1] = ui-vi;
430 
431                 t1 += mh;
432                 t2 = t1+(mh<<1);
433 
434                 cplxMultDiv2(&vi, &vr, x[t2], x[t2+1], cs);
435 
436                 ur = x[t1]>>1;
437                 ui = x[t1+1]>>1;
438 
439                 x[t1]   = ur-vr;
440                 x[t1+1] = ui+vi;
441 
442                 x[t2]   = ur+vr;
443                 x[t2+1] = ui-vi;
444 
445                 /* Same as above but for t1,t2 with j>mh/4 and thus cs swapped */
446                 t1 = (r+mh/2-j)<<1;
447                 t2 = t1 + (mh<<1);
448 
449                 cplxMultDiv2(&vr, &vi, x[t2+1], x[t2], cs);
450 
451                 ur = x[t1]>>1;
452                 ui = x[t1+1]>>1;
453 
454                 x[t1]   = ur-vr;
455                 x[t1+1] = ui+vi;
456 
457                 x[t2]   = ur+vr;
458                 x[t2+1] = ui-vi;
459 
460                 t1 += mh;
461                 t2 = t1+(mh<<1);
462 
463                 cplxMultDiv2(&vi, &vr, x[t2+1], x[t2], cs);
464 
465                 ur = x[t1]>>1;
466                 ui = x[t1+1]>>1;
467 
468                 x[t1]   = ur-vr;
469                 x[t1+1] = ui-vi;
470 
471                 x[t2]   = ur+vr;
472                 x[t2+1] = ui+vi;
473             }
474         }
475         {
476             j = mh/4;
477             for(r=0; r<n; r+=m)
478             {
479                 INT t1 = (r+mh/2-j)<<1;
480                 INT t2 = t1 + (mh<<1);
481                 FIXP_DBL vr,vi,ur,ui;
482 
483                 cplxMultDiv2(&vr, &vi, x[t2], x[t2+1], STC(0x5a82799a), STC(0x5a82799a));
484 
485                 ur = x[t1]>>1;
486                 ui = x[t1+1]>>1;
487 
488                 x[t1]   = ur+vr;
489                 x[t1+1] = ui+vi;
490 
491                 x[t2]   = ur-vr;
492                 x[t2+1] = ui-vi;
493 
494                 t1 += mh;
495                 t2 = t1+(mh<<1);
496 
497                 cplxMultDiv2(&vi, &vr, x[t2], x[t2+1], STC(0x5a82799a), STC(0x5a82799a));
498 
499                 ur = x[t1]>>1;
500                 ui = x[t1+1]>>1;
501 
502                 x[t1]   = ur-vr;
503                 x[t1+1] = ui+vi;
504 
505                 x[t2]   = ur+vr;
506                 x[t2+1] = ui-vi;
507             }
508         }
509     }
510 }
511 #endif
512 
513