root/as3/SiOPM/trunk/src/org/si/utils/FFT.as

リビジョン 4264, 39.4 kB (コミッタ: keim, コミット時期: 2 年 前)

SiON ver0.61 updated

Line 
1 //----------------------------------------------------------------------------------------------------
2 // Optimized Fast Fourier Transform module.
3 //  Ported and modified by keim. The code is optimized for Flash10.
4 //  This soruce code is distributed under BSD-style license (see org.si.license.txt).
5 // [REMARKS]
6 //  The optimization reduces the calculation time from 1575[ms] to 268[ms] in my PC.
7 //  And compare with the simple recursive Cooley-Tukey calculation, the speed is about 10 times faster.
8 // 
9 // Original code (written by c)
10 //  The original source code is free licensed.
11 //----- < Following text is from original code's readme.txt. > -----
12 //    Copyright(C) 1996-2001 Takuya OOURA
13 //    email: ooura@mmm.t.u-tokyo.ac.jp
14 //    download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
15 //    You may use, copy, modify this code for any purpose and
16 //    without fee. You may distribute this ORIGINAL package.
17 //----- < up to here > -----
18 // [NOTES] Now the download site is moved to http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html.
19 //         And the email address might be unavailable.
20 //----------------------------------------------------------------------------------------------------
21
22
23
24
25 package org.si.utils {
26     /** Fast Fourier Transform module optimized for Flash10.
27
28 @example Basic usage for complex discrete fourier transfer.
29 <listing version="3.0">
30 // variables
31 var fft:FFT = new FFT(1024);    // specify source data length (must be 2^n)
32
33 var source:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(1024);     // source vector
34 var result:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(1024);     // result vector
35 var magnitude:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(512);   // result vector for magnitude (half size of source)
36 var phase    :Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(512);   // result vector for phase (half size of source)
37
38 // complex source data
39 for (var i:int=0; i&lt;1024; i+=2) {
40     source[i]   = (i&lt;512) ? -1 : 1;     // even members for real part
41     source[i+1] = 0;                    // odd members for imaginal part
42 }
43
44 // calculation
45 fft.setData(source);                // set source data
46 fft.calcFFT();                      // calculate FFT
47
48 // get result
49 trace(fft.re);                      // real part of FFT result (length = 512)
50 trace(fft.im);                      // imaginal part of FFT result (length = 512)
51 fft.getData(result);                // recieve combinated result by vector
52 trace(result);                      // combinated result (length = 1024, even for real/odd for imaginal)
53 trace(fft.getMagnitude(magnitude)); // vector for magnitude (length = 512)
54 trace(fft.getPhase(phase));         // vector for phase (length = 512)
55
56 // reconstruction
57 fft.calcIFFT().scale(1/512);    // calculate Inversed FFT with previous result (re and im).
58                                 // [REMARKS] The result from calcIFFT(), calcRealIFFT() or calcDCT() is scaled by length/2.
59
60 // get result (another way to get result vector)
61 var reconstructed:Vector.&lt;Number&gt; = fft.getData();  // allocate and return result vector (length = 1024)
62
63 // "fft.setData(source).calcFFT().calcIFFT().scale(2/source.length).getData()" is same as source.
64 trace(reconstructed);
65 </listing>
66
67 @example Basic usage for FFT (for real values) and DCT.
68 <listing version="3.0">
69 // create FFT module
70 var fft:FFT = new FFT(1024);    // specify source data length (must be 2^n)
71    
72 // real number source
73 var source:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;(1024);
74 for (var i:int=0; i&lt;1024; i++) {
75     source[i] = 1-i/512;        // simple real number vector
76 }
77
78 // calculate and get result
79 fft.setDat(source).calcRealFFT();                   // calculate FFT for real numbers
80 trace(fft.re);                                      // real part of FFT result(length = 512)
81 trace(fft.im);                                      // imaginal part of FFT result (length = 512)
82 trace(fft.setDat(source).calcDCT().getIntensity()); // intensity of DCT result (length = 512)
83 </listing>
84      */
85     public class FFT
86     {
87     // valiables
88     //------------------------------------------------------------
89         /** Vector for real numbers, you can set data and get result by this valiables, the length is a HALF of the source data length. */
90         public var re:Vector.<Number>;
91         /** Vector for imaginal numbers, you can set data and get result by this valiables, the length is a HALF of the source data length.  */
92         public var im:Vector.<Number>;
93        
94         private var _length:int = 0;
95         private var _cosTable :Vector.<Number> = new Vector.<Number>();
96         private var _bitrvTemp:Vector.<int> = new Vector.<int>(256);
97         private var _waveTabler:Vector.<Number> = new Vector.<Number>();
98         private var _waveTablei:Vector.<Number> = new Vector.<Number>();
99        
100        
101        
102        
103     // properties
104     //------------------------------------------------------------
105         /** source data length */
106         public function get length() : int { return _length; }
107        
108        
109        
110        
111     // constructor
112     //------------------------------------------------------------
113         /** constructor, specify source data length. The length must be 2^n. */
114         function FFT(len:int)
115         {
116             _initialize(len>>1);
117         }
118        
119        
120        
121        
122     // calculation (functions from original code)
123     //------------------------------------------------------------
124         /** [Functions from original code] Complex Discrete Fourier Tranform
125          *  @param isgn 1 for FFT, -1 for IFFT.
126          *  @param src data to transform. The length must be same as you passed to constructor.
127          */
128         public function cdft(isgn:int, src:Vector.<Number>) : void
129         {
130             setData(src);
131             if (isgn >= 0) calcFFT();
132             else           calcIFFT();
133             getData(src);
134         }
135        
136        
137
138         /** [Functions from original code] Real Discrete Fourier Tranform
139          *  @param isgn 1 for FFT, -1 for IFFT.
140          *  @param src data to transform. The length must be same as you passed to constructor.
141          */
142         public function rdft(isgn:int, src:Vector.<Number>) : void
143         {
144             setData(src);
145             if (isgn >= 0) calcRealFFT();
146             else           calcRealIFFT();
147             getData(src);
148         }
149        
150        
151         /** [Functions from original code] Discrete Cosine Tranform
152          *  @param isgn [ATTENTION] -1 for DCT, 1 for IDCT. Opposite from FFT.
153          *  @param src data to transform. The length must be same as you passed to constructor.
154          */
155         public function ddct(isgn:int, src:Vector.<Number>) : void
156         {
157             setData(src);
158             if (isgn >= 0) calcIDCT();
159             else           calcDCT();
160             getData(src);
161         }
162
163
164         /** [Functions from original code] Discrete Sine Tranform (has some bugs in current version)
165          *  @param isgn [ATTENTION] -1 for DST, 1 for IDST. Opposite from FFT.
166          *  @param src data to transform. The length must be same as you passed to constructor.
167          */
168         public function ddst(isgn:int, src:Vector.<Number>) : void
169         {
170             var j:int, xr:Number;
171            
172             setData(src);
173             if (isgn >= 0) {
174                 xr = im[_length - 1];
175                 for (j=_length-1; j>=1; j--) {
176                     im[j] = -re[j] - im[j-1];
177                     re[j] -= im[j-1];
178                 }
179                 im[0] = re[0] + xr;
180                 re[0] -= xr;
181                 _rftbsub();
182                 _bitrv2();
183                 _cftbsub();
184                 _dstsub();
185             } else {
186                 _dstsub();
187                 _bitrv2();
188                 _cftfsub();
189                 _rftfsub();
190                 xr = re[0] - im[0];
191                 re[0] += im[0];
192                 for (j=1; j<_length; j++) {
193                     im[j - 1] = - re[j] - im[j];
194                     re[j] -= im[j];
195                 }
196                 im[_length - 1] = xr;
197             }
198             getData(src);
199         }
200        
201        
202        
203        
204     // setter
205     //------------------------------------------------------------
206         /** Set source data, the passed vector is copied to "re" and "im" properties, the length of "src" must be same as you passed to constructor.
207          *  @return this insance
208          */
209         public function setData(src:Vector.<Number>) : FFT
210         {
211             var i:int, i2:int;
212             for (i=0, i2=0; i<_length; i++) {
213                 re[i] = src[i2]; i2++;
214                 im[i] = src[i2]; i2++;
215             }
216             return this;
217         }
218        
219        
220        
221        
222     // getter
223     //------------------------------------------------------------
224         /** Get result. The returned vector is a combination of "re"(even member) and "im"(odd member) properties.
225          *  @param dst Vector to recieve the result. The length must be same as you passed to constructor. Allocate vector inside when you pass null.
226          *  @return A combination of "re"(even member) and "im"(odd member) properties.
227          */
228         public function getData(dst:Vector.<Number>=null) : Vector.<Number>
229         {
230             if (dst == null) dst = new Vector.<Number>(_length<<1);
231             var i:int, i2:int;
232             for (i=0, i2=0; i<_length; i++) {
233                 dst[i2] = re[i]; i2++;
234                 dst[i2] = im[i]; i2++;
235             }
236             return dst;
237         }
238        
239        
240         /** Get intensity (re^2+im^2).
241          *  @param dst Vector to recieve intensities. The length must be HALF of the source data length. Allocate vector inside when you pass null.
242          *  @return Vector of intensities, same vector as passed by the arugument when its not null.
243          */
244         public function getIntensity(dst:Vector.<Number>=null) : Vector.<Number>
245         {
246             var i:int, x:Number, y:Number;
247             if (dst == null) dst = new Vector.<Number>(_length);
248             for (i=0; i<_length; i++) {
249                 x = re[i];
250                 y = im[i];
251                 dst[i] = x*x + y*y;
252             }
253             return dst;
254         }
255        
256        
257         /** Get magnitude (sqrt(re^2+im^2)).
258          *  @param dst The vector to recieve magnitudes. The length must be HALF of the source data length. Allocate vector inside when you pass null.
259          *  @return Vector of magnitudes, same vector as passed by the arugument when its not null.
260          */
261         public function getMagnitude(dst:Vector.<Number>=null) : Vector.<Number>
262         {
263             var i:int, x:Number, y:Number;
264             if (dst == null) dst = new Vector.<Number>(_length);
265             for (i=0; i<_length; i++) {
266                 x = re[i];
267                 y = im[i];
268                 dst[i] = Math.sqrt(x*x + y*y);
269             }
270             return dst;
271         }
272        
273        
274         /** Get phase (atan2(re^2+im^2)).
275          *  @param dst The vector to recieve phases. The length must be HALF of the source data length. Allocate vector inside when you pass null.
276          *  @return Vector of phases, same vector as passed by the arugument when its not null.
277          */
278         public function getPhase(dst:Vector.<Number>=null) : Vector.<Number>
279         {
280             if (dst == null) dst = new Vector.<Number>(_length);
281             for (var i:int=0; i<_length; i++) {
282                 dst[i] = Math.atan2(im[i], re[i]);
283             }
284             return dst;
285         }
286        
287        
288        
289        
290     // calculator
291     //------------------------------------------------------------
292         /** Scaling data.
293          *  @param scaling factor
294          *  @return this insance
295          */
296         public function scale(n:Number) : FFT
297         {
298             for (var i:int=0; i<_length; i++) {
299                 re[i] *= n;
300                 im[i] *= n;
301             }
302             return this;
303         }
304        
305        
306         /** Calculate Fast Fourier Transform with complex numbers.
307          *  @return this insance
308          */
309         public function calcFFT() : FFT
310         {
311             _bitrv2();
312             _cftfsub();
313             return this;
314         }
315        
316        
317         /** Calculate Inversed Fast Fourier Transform with complex numbers.
318          *  @return this insance
319          */
320         public function calcIFFT() : FFT
321         {
322             _bitrv2conj();
323             _cftbsub();
324             return this;
325         }
326        
327        
328         /** Calculate Fast Fourier Transform with real numbers.
329          *  @return this insance
330          */
331         public function calcRealFFT() : FFT
332         {
333             _bitrv2();
334             _cftfsub();
335             _rftfsub();
336             var xi:Number = re[0] - im[0];
337             re[0] += im[0];
338             im[0] = xi;
339             return this;
340         }
341        
342        
343         /** Calculate Inversed Fast Fourier Transform with real numbers.
344          *  @return this insance
345          */
346         public function calcRealIFFT() : FFT
347         {
348             im[0] = 0.5 * (re[0] - im[0]);
349             re[0] -= im[0];
350             _rftbsub();
351             _bitrv2();
352             _cftbsub();
353             return this;
354         }
355        
356        
357         /** Calculate Discrete Cosine Transform
358          *  @return this insance
359          */
360         public function calcDCT() : FFT
361         {
362             var j:int, dj:int = _length - 1, xr:Number;
363             xr = im[dj];
364             for (j = _length - 1; j>=1; j--) {
365                 dj = j - 1;
366                 im[j] = re[j] - im[dj];
367                 re[j] += im[dj];
368             }
369             im[0] = re[0] - xr;
370             re[0] += xr;
371             _rftbsub();
372             _bitrv2();
373             _cftbsub();
374             _dctsub();
375             return this;
376         }
377        
378        
379         /** Calculate Inversed Discrete Cosine Transform
380          *  @return this insance
381          */
382         public function calcIDCT() : FFT
383         {
384             var j:int, dj:int, xr:Number;
385             _dctsub();
386             _bitrv2();
387             _cftfsub();
388             _rftfsub();
389             xr = re[0] - im[0];
390             re[0] += im[0];
391             dj = 0;
392             for (j=1; j<_length; j++) {
393                 im[dj] = re[j] - im[j];
394                 re[j] += im[j];
395                 dj = j;
396             }
397             im[dj] = xr;
398             return this;
399         }
400        
401        
402        
403        
404     // internal function
405     //------------------------------------------------------------
406         // initializer
407         private function _initialize(len:int) : void
408         {
409             // length = 2^n && length >= 8
410             for (var l:int=8; l<len;) l<<=1;
411             len = l;
412             var tableLength:int = len >> 2;
413            
414             // wave table
415             _waveTabler.length = tableLength;
416             _waveTablei.length = tableLength;
417             var i:int, imax:int = len >> 3, dt:Number = 6.283185307179586 / len;
418             _waveTabler[0] = 1;
419             _waveTablei[0] = 0;
420             _waveTabler[imax] = _waveTablei[imax] = Math.cos(0.7853981633974483);
421             for (i=1; i<imax; i++) {
422                 _waveTablei[tableLength-i] = _waveTabler[i] = Math.cos(i*dt);
423                 _waveTabler[tableLength-i] = _waveTablei[i] = Math.sin(i*dt);
424             }
425             // bit scrambling
426             re = _waveTabler;
427             im = _waveTablei;
428             _length = tableLength;
429             _bitrv2();
430            
431             // cosine table
432             imax = len << 1;
433             _cosTable.length = imax;
434             dt = 1.5707963267948965 / imax;
435             for (i=0; i<imax; i++) _cosTable[i] = Math.cos(i*dt) * 0.5;
436            
437             // allocate calculation area
438             re = new Vector.<Number>(len);
439             im = new Vector.<Number>(len);
440             _length = len;
441         }
442        
443        
444         // bit reverse
445         private function _bitrv2() : void
446         {
447             var j:int, j1:int, k:int, k1:int,
448                 xr:Number, xi:Number, yr:Number, yi:Number;
449            
450             _bitrvTemp[0] = 0;
451             var l:int = _length, m:int = 1;
452             while ((m << 2) < l) {
453                 l >>= 1;
454                 for (j = 0; j < m; j++) _bitrvTemp[m + j] = _bitrvTemp[j] + l;
455                 m <<= 1;
456             }
457            
458             if ((m << 2) == l) {
459                 for (k = 0; k < m; k++) {
460                     for (j = 0; j < k; j++) {
461                         j1 = j + _bitrvTemp[k];
462                         k1 = k + _bitrvTemp[j];
463                         xr = re[j1];
464                         xi = im[j1];
465                         yr = re[k1];
466                         yi = im[k1];
467                         re[j1] = yr;
468                         im[j1] = yi;
469                         re[k1] = xr;
470                         im[k1] = xi;
471                         j1 += m;
472                         k1 += m + m;
473                         xr = re[j1];
474                         xi = im[j1];
475                         yr = re[k1];
476                         yi = im[k1];
477                         re[j1] = yr;
478                         im[j1] = yi;
479                         re[k1] = xr;
480                         im[k1] = xi;
481                         j1 += m;
482                         k1 -= m;
483                         xr = re[j1];
484                         xi = im[j1];
485                         yr = re[k1];
486                         yi = im[k1];
487                         re[j1] = yr;
488                         im[j1] = yi;
489                         re[k1] = xr;
490                         im[k1] = xi;
491                         j1 += m;
492                         k1 += m + m;
493                         xr = re[j1];
494                         xi = im[j1];
495                         yr = re[k1];
496                         yi = im[k1];
497                         re[j1] = yr;
498                         im[j1] = yi;
499                         re[k1] = xr;
500                         im[k1] = xi;
501                     }
502                     j1 = k + m + _bitrvTemp[k];
503                     k1 = j1 + m;
504                     xr = re[j1];
505                     xi = im[j1];
506                     yr = re[k1];
507                     yi = im[k1];
508                     re[j1] = yr;
509                     im[j1] = yi;
510                     re[k1] = xr;
511                     im[k1] = xi;
512                 }
513             } else {
514                 for (k = 1; k < m; k++) {
515                     for (j = 0; j < k; j++) {
516                         j1 = j + _bitrvTemp[k];
517                         k1 = k + _bitrvTemp[j];
518                         xr = re[j1];
519                         xi = im[j1];
520                         yr = re[k1];
521                         yi = im[k1];
522                         re[j1] = yr;
523                         im[j1] = yi;
524                         re[k1] = xr;
525                         im[k1] = xi;
526                         j1 += m;
527                         k1 += m;
528                         xr = re[j1];
529                         xi = im[j1];
530                         yr = re[k1];
531                         yi = im[k1];
532                         re[j1] = yr;
533                         im[j1] = yi;
534                         re[k1] = xr;
535                         im[k1] = xi;
536                     }
537                 }
538             }
539         }
540        
541        
542         // bit reverse (conjugation)
543         private function _bitrv2conj() : void
544         {
545             var j:int, j1:int, k:int, k1:int,
546                 xr:Number, xi:Number, yr:Number, yi:Number;
547            
548             _bitrvTemp[0] = 0;
549             var l:int = _length, m:int = 1;
550             while ((m << 2) < l) {
551                 l >>= 1;
552                 for (j = 0; j < m; j++) _bitrvTemp[m + j] = _bitrvTemp[j] + l;
553                 m <<= 1;
554             }
555
556             if ((m << 2) == l) {
557                 for (k = 0; k < m; k++) {
558                     for (j = 0; j < k; j++) {
559                         j1 = j + _bitrvTemp[k];
560                         k1 = k + _bitrvTemp[j];
561                         xr =  re[j1];
562                         xi = -im[j1];
563                         yr =  re[k1];
564                         yi = -im[k1];
565                         re[j1] = yr;
566                         im[j1] = yi;
567                         re[k1] = xr;
568                         im[k1] = xi;
569                         j1 += m;
570                         k1 += m + m;
571                         xr =  re[j1];
572                         xi = -im[j1];
573                         yr =  re[k1];
574                         yi = -im[k1];
575                         re[j1] = yr;
576                         im[j1] = yi;
577                         re[k1] = xr;
578                         im[k1] = xi;
579                         j1 += m;
580                         k1 -= m;
581                         xr =  re[j1];
582                         xi = -im[j1];
583                         yr =  re[k1];
584                         yi = -im[k1];
585                         re[j1] = yr;
586                         im[j1] = yi;
587                         re[k1] = xr;
588                         im[k1] = xi;
589                         j1 += m;
590                         k1 += m + m;
591                         xr =  re[j1];
592                         xi = -im[j1];
593                         yr =  re[k1];
594                         yi = -im[k1];
595                         re[j1] = yr;
596                         im[j1] = yi;
597                         re[k1] = xr;
598                         im[k1] = xi;
599                     }
600                     k1 = k + _bitrvTemp[k];
601                     im[k1] = -im[k1];
602                     j1 = k1 + m;
603                     k1 = j1 + m;
604                     xr =  re[j1];
605                     xi = -im[j1];
606                     yr =  re[k1];
607                     yi = -im[k1];
608                     re[j1] = yr;
609                     im[j1] = yi;
610                     re[k1] = xr;
611                     im[k1] = xi;
612                     k1 += m;
613                     im[k1] = -im[k1];
614                 }
615             } else {
616                 im[0] = -im[0];
617                 im[m] = -im[m];
618                 for (k = 1; k < m; k++) {
619                     for (j = 0; j < k; j++) {
620                         j1 = j + _bitrvTemp[k];
621                         k1 = k + _bitrvTemp[j];
622                         xr =  re[j1];
623                         xi = -im[j1];
624                         yr =  re[k1];
625                         yi = -im[k1];
626                         re[j1] = yr;
627                         im[j1] = yi;
628                         re[k1] = xr;
629                         im[k1] = xi;
630                         j1 += m;
631                         k1 += m;
632                         xr =  re[j1];
633                         xi = -im[j1];
634                         yr =  re[k1];
635                         yi = -im[k1];
636                         re[j1] = yr;
637                         im[j1] = yi;
638                         re[k1] = xr;
639                         im[k1] = xi;
640                     }
641                     k1 = k + _bitrvTemp[k];
642                     im[k1] = -im[k1];
643                     im[k1 + m] = -im[k1 + m];
644                 }
645             }
646         }
647        
648        
649        
650        
651     // sub routines
652     //------------------------------------------------------------
653         private function _cftfsub() : void
654         {
655             var j0:int, j1:int, j2:int, j3:int, l:int,
656                 x0r:Number, x1r:Number, x2r:Number, x3r:Number,
657                 x0i:Number, x1i:Number, x2i:Number, x3i:Number;
658            
659             _cft1st();
660             l = 4;
661             while ((l << 2) < _length) {
662                 _cftmdl(l);
663                 l <<= 2;
664             }
665            
666             if ((l << 2) == _length) {
667                 for (j0 = 0; j0 < l; j0++) {
668                     j1 = j0 + l;
669                     j2 = j1 + l;
670                     j3 = j2 + l;
671                     x0r = re[j0] + re[j1];
672                     x0i = im[j0] + im[j1];
673                     x1r = re[j0] - re[j1];
674                     x1i = im[j0] - im[j1];
675                     x2r = re[j2] + re[j3];
676                     x2i = im[j2] + im[j3];
677                     x3r = re[j2] - re[j3];
678                     x3i = im[j2] - im[j3];
679                     re[j0] = x0r + x2r;
680                     im[j0] = x0i + x2i;
681                     re[j2] = x0r - x2r;
682                     im[j2] = x0i - x2i;
683                     re[j1] = x1r - x3i;
684                     im[j1] = x1i + x3r;
685                     re[j3] = x1r + x3i;
686                     im[j3] = x1i - x3r;
687                 }
688             } else {
689                 for (j0 = 0; j0 < l; j0++) {
690                     j1 = j0 + l;
691                     x0r = re[j0] - re[j1];
692                     x0i = im[j0] - im[j1];
693                     re[j0] += re[j1];
694                     im[j0] += im[j1];
695                     re[j1] = x0r;
696                     im[j1] = x0i;
697                 }
698             }
699         }
700
701
702         private function _cftbsub() : void
703         {
704             var j0:int, j1:int, j2:int, j3:int, l:int,
705                 x0r:Number, x1r:Number, x2r:Number, x3r:Number,
706                 x0i:Number, x1i:Number, x2i:Number, x3i:Number;
707            
708             _cft1st();
709             l = 4;
710             while ((l << 2) < _length) {
711                 _cftmdl(l);
712                 l <<= 2;
713             }
714
715             if ((l << 2) == _length) {
716                 for (j0 = 0; j0 < l; j0++) {
717                     j1 = j0 + l;
718                     j2 = j1 + l;
719                     j3 = j2 + l;
720                     x0r =  re[j0] + re[j1];
721                     x0i = -im[j0] - im[j1];
722                     x1r =  re[j0] - re[j1];
723                     x1i = -im[j0] + im[j1];
724                     x2r =  re[j2] + re[j3];
725                     x2i =  im[j2] + im[j3];
726                     x3r =  re[j2] - re[j3];
727                     x3i =  im[j2] - im[j3];
728                     re[j0] = x0r + x2r;
729                     im[j0] = x0i - x2i;
730                     re[j2] = x0r - x2r;
731                     im[j2] = x0i + x2i;
732                     re[j1] = x1r - x3i;
733                     im[j1] = x1i - x3r;
734                     re[j3] = x1r + x3i;
735                     im[j3] = x1i + x3r;
736                 }
737             } else {
738                 for (j0 = 0; j0 < l; j0++) {
739                     j1 = j0 + l;
740                     x0r =  re[j0] - re[j1];
741                     x0i = -im[j0] + im[j1];
742                     re[j0] +=  re[j1];
743                     im[j0] = -im[j0] - im[j1];
744                     re[j1] = x0r;
745                     im[j1] = x0i;
746                 }
747             }
748         }
749        
750        
751         private function _cft1st() : void
752         {
753             var j0:int, j1:int, j2:int, j3:int, k1:int, k2:int,
754                 wk1r:Number, wk2r:Number, wk3r:Number, x0r:Number, x1r:Number, x2r:Number, x3r:Number,
755                 wk1i:Number, wk2i:Number, wk3i:Number, x0i:Number, x1i:Number, x2i:Number, x3i:Number;
756            
757             x0r = re[0] + re[1];
758             x0i = im[0] + im[1];
759             x1r = re[0] - re[1];
760             x1i = im[0] - im[1];
761             x2r = re[2] + re[3];
762             x2i = im[2] + im[3];
763             x3r = re[2] - re[3];
764             x3i = im[2] - im[3];
765             re[0] = x0r + x2r;
766             im[0] = x0i + x2i;
767             re[2] = x0r - x2r;
768             im[2] = x0i - x2i;
769             re[1] = x1r - x3i;
770             im[1] = x1i + x3r;
771             re[3] = x1r + x3i;
772             im[3] = x1i - x3r;
773             wk1r = _waveTabler[1];
774             x0r = re[4] + re[5];
775             x0i = im[4] + im[5];
776             x1r = re[4] - re[5];
777             x1i = im[4] - im[5];
778             x2r = re[6] + re[7];
779             x2i = im[6] + im[7];
780             x3r = re[6] - re[7];
781             x3i = im[6] - im[7];
782             re[4] = x0r + x2r;
783             im[4] = x0i + x2i;
784             re[6] = x2i - x0i;
785             im[6] = x0r - x2r;
786             x0r = x1r - x3i;
787             x0i = x1i + x3r;
788             re[5] = wk1r * (x0r - x0i);
789             im[5] = wk1r * (x0r + x0i);
790             x0r = x3i + x1r;
791             x0i = x3r - x1i;
792             re[7] = wk1r * (x0i - x0r);
793             im[7] = wk1r * (x0i + x0r);
794             k1 = 0;
795             for (j0 = 8; j0 < _length; j0 += 4) {
796                 j1 = j0 + 1;
797                 j2 = j1 + 1;
798                 j3 = j2 + 1;
799                 k1++;
800                 k2 = 2 * k1;
801                 wk2r = _waveTabler[k1];
802                 wk2i = _waveTablei[k1];
803                 wk1r = _waveTabler[k2];
804                 wk1i = _waveTablei[k2];
805                 wk3r = wk1r - 2 * wk2i * wk1i;
806                 wk3i = 2 * wk2i * wk1r - wk1i;
807                 x0r = re[j0] + re[j1];
808                 x0i = im[j0] + im[j1];
809                 x1r = re[j0] - re[j1];
810                 x1i = im[j0] - im[j1];
811                 x2r = re[j2] + re[j3];
812                 x2i = im[j2] + im[j3];
813                 x3r = re[j2] - re[j3];
814                 x3i = im[j2] - im[j3];
815                 re[j0] = x0r + x2r;
816                 im[j0] = x0i + x2i;
817                 x0r -= x2r;
818                 x0i -= x2i;
819                 re[j2] = wk2r * x0r - wk2i * x0i;
820                 im[j2] = wk2r * x0i + wk2i * x0r;
821                 x0r = x1r - x3i;
822                 x0i = x1i + x3r;
823                 re[j1] = wk1r * x0r - wk1i * x0i;
824                 im[j1] = wk1r * x0i + wk1i * x0r;
825                 x0r = x1r + x3i;
826                 x0i = x1i - x3r;
827                 re[j3] = wk3r * x0r - wk3i * x0i;
828                 im[j3] = wk3r * x0i + wk3i * x0r;
829                
830                 k2++;
831                 wk1r = _waveTabler[k2];
832                 wk1i = _waveTablei[k2];
833                 wk3r = wk1r - 2 * wk2r * wk1i;
834                 wk3i = 2 * wk2r * wk1r - wk1i;
835                 j0 += 4;
836                 j1 = j0 + 1;
837                 j2 = j1 + 1;
838                 j3 = j2 + 1;
839                 x0r = re[j0] + re[j1];
840                 x0i = im[j0] + im[j1];
841                 x1r = re[j0] - re[j1];
842                 x1i = im[j0] - im[j1];
843                 x2r = re[j2] + re[j3];
844                 x2i = im[j2] + im[j3];
845                 x3r = re[j2] - re[j3];
846                 x3i = im[j2] - im[j3];
847                 re[j0] = x0r + x2r;
848                 im[j0] = x0i + x2i;
849                 x0r -= x2r;
850                 x0i -= x2i;
851                 re[j2] = -wk2i * x0r - wk2r * x0i;
852                 im[j2] = -wk2i * x0i + wk2r * x0r;
853                 x0r = x1r - x3i;
854                 x0i = x1i + x3r;
855                 re[j1] = wk1r * x0r - wk1i * x0i;
856                 im[j1] = wk1r * x0i + wk1i * x0r;
857                 x0r = x1r + x3i;
858                 x0i = x1i - x3r;
859                 re[j3] = wk3r * x0r - wk3i * x0i;
860                 im[j3] = wk3r * x0i + wk3i * x0r;
861             }
862         }
863        
864        
865         private function _cftmdl(l:int) : void
866         {
867             var j0:int, j1:int, j2:int, j3:int, k:int, k1:int, k2:int, m:int, m2:int,
868                 wk1r:Number, wk2r:Number, wk3r:Number, x0r:Number, x1r:Number, x2r:Number, x3r:Number,
869                 wk1i:Number, wk2i:Number, wk3i:Number, x0i:Number, x1i:Number, x2i:Number, x3i:Number;
870            
871             m = l << 2;
872             for (j0 = 0; j0 < l; j0++) {
873                 j1 = j0 + l;
874                 j2 = j1 + l;
875                 j3 = j2 + l;
876                 x0r = re[j0] + re[j1];
877                 x0i = im[j0] + im[j1];
878                 x1r = re[j0] - re[j1];
879                 x1i = im[j0] - im[j1];
880                 x2r = re[j2] + re[j3];
881                 x2i = im[j2] + im[j3];
882                 x3r = re[j2] - re[j3];
883                 x3i = im[j2] - im[j3];
884                 re[j0] = x0r + x2r;
885                 im[j0] = x0i + x2i;
886                 re[j2] = x0r - x2r;
887                 im[j2] = x0i - x2i;
888                 re[j1] = x1r - x3i;
889                 im[j1] = x1i + x3r;
890                 re[j3] = x1r + x3i;
891                 im[j3] = x1i - x3r;
892             }
893             wk1r = _waveTabler[1];
894             for (j0 = m; j0 < l + m; j0++) {
895                 j1 = j0 + l;
896                 j2 = j1 + l;
897                 j3 = j2 + l;
898                 x0r = re[j0] + re[j1];
899                 x0i = im[j0] + im[j1];
900                 x1r = re[j0] - re[j1];
901                 x1i = im[j0] - im[j1];
902                 x2r = re[j2] + re[j3];
903                 x2i = im[j2] + im[j3];
904                 x3r = re[j2] - re[j3];
905                 x3i = im[j2] - im[j3];
906                 re[j0] = x0r + x2r;
907                 im[j0] = x0i + x2i;
908                 re[j2] = x2i - x0i;
909                 im[j2] = x0r - x2r;
910                 x0r = x1r - x3i;
911                 x0i = x1i + x3r;
912                 re[j1] = wk1r * (x0r - x0i);
913                 im[j1] = wk1r * (x0r + x0i);
914                 x0r = x3i + x1r;
915                 x0i = x3r - x1i;
916                 re[j3] = wk1r * (x0i - x0r);
917                 im[j3] = wk1r * (x0i + x0r);
918             }
919             k1 = 0;
920             m2 = 2 * m;
921             for (k = m2; k < _length; k += m2) {
922                 k1 += 1;
923                 k2 = 2 * k1;
924                 wk2r = _waveTabler[k1];
925                 wk2i = _waveTablei[k1];
926                 wk1r = _waveTabler[k2];
927                 wk1i = _waveTablei[k2];
928                 wk3r = wk1r - 2 * wk2i * wk1i;
929                 wk3i = 2 * wk2i * wk1r - wk1i;
930                 for (j0 = k; j0 < l + k; j0++) {
931                     j1 = j0 + l;
932                     j2 = j1 + l;
933                     j3 = j2 + l;
934                     x0r = re[j0] + re[j1];
935                     x0i = im[j0] + im[j1];
936                     x1r = re[j0] - re[j1];
937                     x1i = im[j0] - im[j1];
938                     x2r = re[j2] + re[j3];
939                     x2i = im[j2] + im[j3];
940                     x3r = re[j2] - re[j3];
941                     x3i = im[j2] - im[j3];
942                     re[j0] = x0r + x2r;
943                     im[j0] = x0i + x2i;
944                     x0r -= x2r;
945                     x0i -= x2i;
946                     re[j2] = wk2r * x0r - wk2i * x0i;
947                     im[j2] = wk2r * x0i + wk2i * x0r;
948                     x0r = x1r - x3i;
949                     x0i = x1i + x3r;
950                     re[j1] = wk1r * x0r - wk1i * x0i;
951                     im[j1] = wk1r * x0i + wk1i * x0r;
952                     x0r = x1r + x3i;
953                     x0i = x1i - x3r;
954                     re[j3] = wk3r * x0r - wk3i * x0i;
955                     im[j3] = wk3r * x0i + wk3i * x0r;
956                 }
957                 k2++;
958                 wk1r = _waveTabler[k2];
959                 wk1i = _waveTablei[k2];
960                 wk3r = wk1r - 2 * wk2r * wk1i;
961                 wk3i = 2 * wk2r * wk1r - wk1i;
962                 for (j0 = k + m; j0 < l + (k + m); j0++) {
963                     j1 = j0 + l;
964                     j2 = j1 + l;
965                     j3 = j2 + l;
966                     x0r = re[j0] + re[j1];
967                     x0i = im[j0] + im[j1];
968                     x1r = re[j0] - re[j1];
969                     x1i = im[j0] - im[j1];
970                     x2r = re[j2] + re[j3];
971                     x2i = im[j2] + im[j3];
972                     x3r = re[j2] - re[j3];
973                     x3i = im[j2] - im[j3];
974                     re[j0] = x0r + x2r;
975                     im[j0] = x0i + x2i;
976                     x0r -= x2r;
977                     x0i -= x2i;
978                     re[j2] = -wk2i * x0r - wk2r * x0i;
979                     im[j2] = -wk2i * x0i + wk2r * x0r;
980                     x0r = x1r - x3i;
981                     x0i = x1i + x3r;
982                     re[j1] = wk1r * x0r - wk1i * x0i;
983                     im[j1] = wk1r * x0i + wk1i * x0r;
984                     x0r = x1r + x3i;
985                     x0i = x1i - x3r;
986                     re[j3] = wk3r * x0r - wk3i * x0i;
987                     im[j3] = wk3r * x0i + wk3i * x0r;
988                 }
989             }
990         }
991        
992        
993         private function _rftfsub() : void
994         {
995             var j:int, k:int, kk:int, m:int, ctLength:int = _cosTable.length,
996                 wkr:Number, wki:Number, xr:Number, xi:Number, yr:Number, yi:Number;
997            
998             m = _length >> 1;
999             kk = 0;
1000             for (j = 1; j < m; j++) {
1001                 k = _length - j;
1002                 kk += 4;
1003                 wkr = 0.5 - _cosTable[ctLength - kk];
1004                 wki = _cosTable[kk];
1005                 xr = re[j] - re[k];
1006                 xi = im[j] + im[k];
1007                 yr = wkr * xr - wki * xi;
1008                 yi = wkr * xi + wki * xr;
1009                 re[j] -= yr;
1010                 im[j] -= yi;
1011                 re[k] += yr;
1012                 im[k] -= yi;
1013             }
1014         }
1015
1016
1017         private function _rftbsub() : void
1018         {
1019             var j:int, k:int, kk:int, m:int, ctLength:int = _cosTable.length,
1020                 wkr:Number, wki:Number, xr:Number, xi:Number, yr:Number, yi:Number;
1021            
1022             im[0] = -im[0];
1023             m = _length >> 1;
1024             kk = 0;
1025             for (j = 1; j < m; j++) {
1026                 k = _length - j;
1027                 kk += 4;
1028                 wkr = 0.5 - _cosTable[ctLength - kk];
1029                 wki = _cosTable[kk];
1030                 xr = re[j] - re[k];
1031                 xi = im[j] + im[k];
1032                 yr = wkr * xr + wki * xi;
1033                 yi = wkr * xi - wki * xr;
1034                 re[j] -= yr;
1035                 im[j]  = yi - im[j];
1036                 re[k] += yr;
1037                 im[k]  = yi - im[k];
1038             }
1039             im[m] = -im[m];
1040         }
1041        
1042        
1043         private function _dctsub() : void
1044         {
1045             var j:int, k:int, kk:int, ikk:int,
1046                 m:int, wkr:Number, wki:Number, xr:Number,
1047                 ctLength:int = _cosTable.length;
1048            
1049             m = _length >> 1;
1050             k = _length-1;
1051             kk = 1;
1052             ikk = ctLength - 1;
1053             wkr = _cosTable[kk] - _cosTable[ikk];
1054             wki = _cosTable[kk] + _cosTable[ikk];
1055             xr       = wki * im[0] - wkr * im[k];
1056             im[0] = wkr * im[0] + wki * im[k];
1057             im[k] = xr;
1058             for (j = 1; j < m; j++) {
1059                 k = _length - j;
1060                 kk++;
1061                 ikk--;
1062                 wkr = _cosTable[kk] - _cosTable[ikk];
1063                 wki = _cosTable[kk] + _cosTable[ikk];
1064                 xr    = wki * re[j] - wkr * re[k];
1065                 re[j] = wkr * re[j] + wki * re[k];
1066                 re[k] = xr;
1067                 k--;
1068                 kk++;
1069                 ikk--;
1070                 wkr = _cosTable[kk] - _cosTable[ikk];
1071                 wki = _cosTable[kk] + _cosTable[ikk];
1072                 xr    = wki * im[j] - wkr * im[k];
1073                 im[j] = wkr * im[j] + wki * im[k];
1074                 im[k] = xr;
1075             }
1076             re[m] *= 0.7071067811865476; // cos(pi/4)
1077         }
1078
1079
1080         private function _dstsub() : void
1081         {
1082             var j:int, k:int, kk:int, ikk:int,
1083                 m:int, wkr:Number, wki:Number, xr:Number,
1084                 ctLength:int = _cosTable.length;
1085            
1086             m = _length >> 1;
1087             k = _length-1;
1088             kk = 1;
1089             ikk = ctLength - 1;
1090             wkr = _cosTable[kk] - _cosTable[ikk];
1091             wki = _cosTable[kk] + _cosTable[ikk];
1092             xr    = wki * im[k] - wkr * im[0];
1093             im[k] = wkr * im[k] + wki * im[0];
1094             im[0] = xr;
1095             for (j = 1; j < m; j++) {
1096                 k = _length - j;
1097                 kk++;
1098                 ikk--;
1099                 wkr = _cosTable[kk] - _cosTable[ikk];
1100                 wki = _cosTable[kk] + _cosTable[ikk];
1101                 xr    = wki * re[k] - wkr * re[j];
1102                 re[k] = wkr * re[k] + wki * re[j];
1103                 re[j] = xr;
1104                 k--;
1105                 kk++;
1106                 ikk--;
1107                 wkr = _cosTable[kk] - _cosTable[ikk];
1108                 wki = _cosTable[kk] + _cosTable[ikk];
1109                 xr    = wki * im[k] - wkr * im[j];
1110                 im[k] = wkr * im[k] + wki * im[j];
1111                 im[j] = xr;
1112             }
1113             re[m] *= 0.7071067811865476; // cos(pi/4)
1114         }
1115     }
1116 }
1117
1118
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。