Simple spectrum analyzer (SiON FFT module + FP10.1 microphone)

by keim_at_Si forked from FP10.1用 マイク録音&再生 (diff: 96)
SiON FFT module で 声紋解析 (Hamming窓+時間分解能11ms)
webpage; http://soundimpulse.sakura.ne.jp/simple-spectrum-analyzer/
♥18 | Line 91 | Modified 2010-01-08 00:59:46 | MIT License
play

ActionScript3 source code

/**
 * Copyright keim_at_Si ( http://wonderfl.net/user/keim_at_Si )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bxCT
 */

// forked from keno42's FP10.1用 マイク録音&再生
// SiON FFT module で 声紋解析 (Hamming窓+時間分解能11ms)
package {
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.text.*;
    import flash.utils.ByteArray;
    import org.si.utils.FFT;
    import frocessing.color.ColorLerp;
    import com.bit101.components.*;
    public class main extends Sprite {
        private var voicePrint:BitmapData = new BitmapData(465, 256, false, 0);
        private var mic:Microphone, scaler:HSlider;
        public function main() {
            _initFFT();
            with(addChild(new Bitmap(voicePrint))){ y=100; }
            (scaler = new HSlider(this, 100, 370, _onScalerChanged)).setSize(264, 20);
            scaler.value = 25;
            mic = Microphone.getMicrophone();
            mic.rate = 44;
            mic.setSilenceLevel(0);
            mic.setLoopBack();
            mic.addEventListener("sampleData", _in);
        }
        
        private function _onScalerChanged(e:Event) : void { 
            scale = scaler.value;
        }
        
        private function _in(e:SampleDataEvent):void {
            for (e.data.position=0; e.data.bytesAvailable>0;) {
                _execFFT(e.data);
                _updateImage();
            }
        }
        
        private function _updateImage() : void {
            voicePrint.scroll(-4, 0);
            for (var i:int=0; i < 256; i++) {
                voicePrint.setPixel(461, 255-i, grad[frm[3][i]]);
                voicePrint.setPixel(462, 255-i, grad[frm[2][i]]);
                voicePrint.setPixel(463, 255-i, grad[frm[1][i]]);
                voicePrint.setPixel(464, 255-i, grad[frm[0][i]]);
            }
        }

        private var src:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
        private var dst:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
        private var amp:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
        private var frm:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(4);
        private var hamm:Vector.<Number> = new Vector.<Number>(2048);
        private var fft:FFT = new FFT(2048);
        private var grad:Array, scale:Number;
        private function _initFFT() : void {
            var i:int;
            for (i=0; i<4; i++) {
                src[i] = new Vector.<Number>(2048);
                dst[i] = new Vector.<Number>(2048);
                amp[i] = new Vector.<Number>(1024);
                frm[i] = new Vector.<int>(256);
            }
            for (i=0; i<2048; i++) hamm[i]=0.54-Math.cos(i*0.00306796)*0.46;
            ColorLerp.mode = "hsv";
            grad = ColorLerp.gradient(0x000040, 0xff0000, 256);
            scale = 25;
        }
        private function _execFFT(data:ByteArray) : void {
            var index:int, i:int, j:int, n:Number, 
                f:Vector.<int>, a:Vector.<Number>,
                s0:Vector.<Number> = src[0],
                s1:Vector.<Number> = src[1],
                s2:Vector.<Number> = src[2],
                s3:Vector.<Number> = src[3];
            for (index=3; index>=0; --index) {
                for (i=0; i<512; i++) {
                    n = data.readFloat();
                    j = i;     s0[j] = n * hamm[j];
                    j += 512;  s1[j] = n * hamm[j];
                    j += 512;  s2[j] = n * hamm[j];
                    j += 512;  s3[j] = n * hamm[j];
                }
                a = amp[index];
                f = frm[index];
                fft.setData(s3).calcDCT().getMagnitude(a)
                for (i=0; i<256; i++) { // from 86Hz to 5.6kHz
                    n = Math.log(a[i+4]*scale);
                    f[i] = int(((n<0) ? 0 : (n>1) ? 1 : n) * 255);
                }
                s3 = s2;
                s2 = s1;
                s1 = s0;
                s0 = src[index];
            }
        }
    }   
}

Forked