In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2010-11-13

マイク入力からのFFT
参考 : http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/index.html
Get Adobe Flash player
by hycro 13 Nov 2010
    Embed
package
{
    import flash.display.Sprite;
    import flash.events.SampleDataEvent;
    import flash.media.Microphone;
    import flash.utils.ByteArray;
    
    [SWF(width=465, height=465, backgroundColor=0xFFFFFF, frameRate=60)]
    public class MicTest extends Sprite
    {
        private var _mic:Microphone;
        
        public function MicTest()
        {
            _mic = Microphone.getMicrophone();
            _mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
        }
        
        private function micSampleDataHandler(evt:SampleDataEvent):void
        {
            var data:ByteArray = evt.data;
            var n:uint = Math.min(data.length/ 4, 256) ;
            var sound:Vector.<Number> = new Vector.<Number>();
            for (var i:uint = 0; i < n; i++) {
                sound.push(data.readFloat());
            }
            
            sound = computeSpectrum(sound);
            
            var offsetW:int = (stage.stageWidth - (sound.length)) / 2;
            var offsetH:uint = stage.stageHeight / 2;
            graphics.clear();
            graphics.lineStyle(1, 0x0);
            for (var x:uint = 0; x < sound.length; x++) {
                graphics.moveTo(x + offsetW,  sound[x]*50 + offsetH);
                graphics.lineTo(x + offsetW, -sound[x]*50 + offsetH);
            }
        }
        
        private function computeSpectrum(data:Vector.<Number>):Vector.<Number>
        {
            var n:uint = data.length;
            var theta:Number = 2 * Math.PI * n;
            var i:uint;
            var j:uint;
            var k:uint;
            var m:uint;
            var mh:uint;
            var irev:uint;
            var wr:Number;
            var wi:Number;
            var xr:Number;
            var xi:Number;
            
            var ar:Vector.<Number> = data.slice();                // 入力データ実部
            var ai:Vector.<Number> = new Vector.<Number>(n);      // 入力データ虚部
            var out:Vector.<Number> = new Vector.<Number>(n);     // 出力データ
            
            i = 0;
            for (j = 1; j < n - 1; j++) {
                for (k = n >> 1; k > (i ^= k); k >>= 1){}
                if (j < i) {
                    xr = ar[j];
                    xi = ai[j];
                    ar[j] = ar[i];
                    ai[j] = ai[i];
                    ar[i] = xr;
                    ai[i] = xi;
                }
            }
            for (mh = 1; (m = mh << 1) <= n; mh = m) {
                irev = 0;
                for (i = 0; i < n; i += m) {
                    wr = Math.cos(theta * irev);
                    wi = Math.sin(theta * irev);
                    for (k = n >> 2; k > (irev ^= k); k >>= 1) {}
                    for (j = i; j < mh + i; j++) {
                        k = j + mh;
                        xr = ar[j] - ar[k];
                        xi = ai[j] - ai[k];
                        ar[j] += ar[k];
                        ai[j] += ai[k];
                        ar[k] = wr * xr - wi * xi;
                        ai[k] = wr * xi + wi * xr;
                    }
                }
            }
            
            // 出力の作成
            for(i = 0; i < n; i++)
            {
                out[i] = Math.sqrt(ar[i]*ar[i] + ai[i]*ai[i]);
            }
            return out;
        }
    }
}