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

Sound Spectrum 2012-7-16

Get Adobe Flash player
by bongiovi015 16 Jul 2012
/**
 * Copyright bongiovi015 ( http://wonderfl.net/user/bongiovi015 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/queY
 */

package {
    import com.adobe.utils.AGALMiniAssembler;
    import com.adobe.utils.PerspectiveMatrix3D;
    
    import flash.display.Sprite;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.media.SoundLoaderContext;
    import flash.media.SoundMixer;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;
    
    import frocessing.color.ColorHSL;
    
    import net.hires.debug.Stats;
    
    [SWF(width=465, height=465, frameRate=30, backgroundColor=0)]
    public class SoundSpectrum0715 extends Sprite {
        public const INDEX                         : Vector.<uint> = Vector.<uint>([0, 1, 2, 0, 2, 3]);
        public const MAX_DEPTH                    : int = 4;
        public const NUM_SAMPLE                    : int = 32;
        public const NUM_LINES                    : int = 60;
        public const SPAN                        : Number = 8;
        public const PARTICLE_SIZE                : Number = 4;
        
        public var context:Context3D;
        public var W:int;
        public var H:int;
        private var _modelMatrix:Matrix3D;
        private var _projectionMatrix:PerspectiveMatrix3D;
        private var _particles:Vector.<Particle>;
        private var _vbuffer:VertexBuffer3D;
        private var _ibuffer:IndexBuffer3D;
        private var _sound:Sound;
        private var _channel:SoundChannel;
        private var _bytes:ByteArray = new ByteArray;
        private var soundData:Array;
        
        public function SoundSpectrum0715() {
            W = stage.stageWidth;
            H = stage.stageHeight;
            
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, _onContext);
            stage.stage3Ds[0].requestContext3D();
            
            addChild(new Stats).y = H-100;
        }
        
        protected function _onContext(e:Event) : void {
            context = stage.stage3Ds[0].context3D;
            context.configureBackBuffer(W, H, 1, true);
            _init();
        }
        
        
        protected function _init() : void {
            var scale:Number = 2/W;
            _modelMatrix = new Matrix3D();
            _modelMatrix.appendScale(scale, -scale, 1);
            
            _projectionMatrix = new PerspectiveMatrix3D();
            _projectionMatrix.perspectiveFieldOfViewLH(45*Math.PI/180, W/H, 0.1, 1000);
            
            _initParticles();
            _initBuffer();
            _initShader();
            
            _sound = new Sound;
            var soundContext:SoundLoaderContext = new SoundLoaderContext(10, true);            
            var s:String = "http://www.bongiovi.tw/wonderfl/wumm.mp3";
            _sound.load(new URLRequest(s), soundContext);
            _channel = _sound.play(0, 5);
            
            addEventListener(Event.ENTER_FRAME, _loop);
        }
        
        
        private function _loop(e:Event) : void {
            context.clear(0, 0, 0, 0);
            _updateParticlesData();
            
            var viewMatrix:Matrix3D = new Matrix3D();
            var center:Vector3D = new Vector3D(0, 0, MAX_DEPTH/2);
            viewMatrix.appendRotation( -(stage.mouseX / stage.stageWidth-.5) * 60, new Vector3D(0, 1, 0), center);
            viewMatrix.appendRotation( -(stage.mouseY / stage.stageHeight-.5) * 60, new Vector3D(1, 0, 0), center );
            
            var mtx:Matrix3D = _modelMatrix.clone();
            mtx.append(viewMatrix);
            mtx.append(_projectionMatrix);
            context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mtx, true);
            
            context.setVertexBufferAt(0, _vbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            context.setVertexBufferAt(1, _vbuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
            context.drawTriangles(_ibuffer);
            context.present();
        }        
        
        
        private function _updateParticlesData() : void {
            var i:int, j:int, index:int;
            
            SoundMixer.computeSpectrum(_bytes, true);
            var datas:Array = [];
            for ( i=0; i<NUM_SAMPLE; i++) datas.push(_bytes.readFloat());
            soundData.shift();
            soundData.push(datas);
            var color:ColorHSL = new ColorHSL();
            color.h = 0;
            color.s = .25;
            color.l = .75;
            
            for ( j=0; j<NUM_SAMPLE; j++) {
                for(i=0; i<NUM_LINES; i++) {
                    index = j*NUM_LINES + i;
                    var p:Particle = _particles[index];
                    var offset:Number = Math.sin(i/NUM_LINES * Math.PI);
                    offset = Math.pow(offset, 3);
                    color.h = soundData[i][j] * 120;
                    color.l = offset * .8 - (.6-soundData[i][j] * .6);
                    p.r = color.r/255;
                    p.g = color.g/255;
                    p.b = color.b/255;
                    p.z = 2 - soundData[i][j] * .4 * offset;
                }
            }
            
            _vbuffer = getVertexBufferFromParticles(context, _particles, PARTICLE_SIZE);
        }        
        
        
        private function _initParticles() : void {
            _particles = new Vector.<Particle>();
            var i:int, j:int;
            var totalWidth:Number = SPAN * NUM_LINES;
            var totalHeight:Number = SPAN * NUM_SAMPLE;
            var sx:Number = -totalWidth/2;
            var sy:Number = -totalHeight/2;
            soundData = [];
            for (i=0; i<NUM_LINES; i++) {
                soundData[i] = [];
            }
            
            for ( j=0; j<NUM_SAMPLE; j++) {
                for(i=0; i<NUM_LINES; i++) {
                    var p:Particle = new Particle(i*SPAN+sx, j*SPAN+sy, 1.5, 1, 1, 1, 1);
                    _particles.push(p);
                    soundData[i][j] = 0;
                }
            }
        }
        
        
        private function _initBuffer() : void {
            var index:int = 0, i:int;
            var iBuf:Vector.<uint> = new Vector.<uint>(_particles.length*6);
            for ( i=0; i<_particles.length; i++) {
                for (var j:int=0; j<INDEX.length; j++) {
                    iBuf[index++] = INDEX[j] + i*4;
                }
            }
            _ibuffer = context.createIndexBuffer(iBuf.length);
            _ibuffer.uploadFromVector(iBuf, 0, iBuf.length);
        }
        
        
        private function _initShader() : void {
            var agal:AGALMiniAssembler = new AGALMiniAssembler;
            var code:String = "";
            
            code += "m44 op, va0, vc0\n";
            code += "mov v0, va1\n";
            var vertexShader:ByteArray = agal.assemble(Context3DProgramType.VERTEX, code);
            
            
            code = "mov oc, v0\n";
            var fragmentShader:ByteArray = agal.assemble(Context3DProgramType.FRAGMENT, code);
            
            var program:Program3D = context.createProgram();
            program.upload(vertexShader, fragmentShader);
            context.setProgram(program);
        }
        
        
        public static function getVertexBufferFromParticles(context:Context3D, ps:Vector.<Particle>, size:Number=10) : VertexBuffer3D {
            var numVertices:int = ps.length * 4;
            var vbuffer:VertexBuffer3D = context.createVertexBuffer(numVertices, 6);
            var vbuf:Vector.<Number> = new Vector.<Number>(numVertices * 6);
            var index:int = 0, i:int=0;
            
            for (i=0; i < ps.length; i++) {
                vbuf[index++] = ps[i].x-size;
                vbuf[index++] = ps[i].y-size;
                vbuf[index++] = ps[i].z;
                vbuf[index++] = ps[i].r;
                vbuf[index++] = ps[i].g;
                vbuf[index++] = ps[i].b;
                
                vbuf[index++] = ps[i].x+size;
                vbuf[index++] = ps[i].y-size;
                vbuf[index++] = ps[i].z;
                vbuf[index++] = ps[i].r;
                vbuf[index++] = ps[i].g;
                vbuf[index++] = ps[i].b;
                
                vbuf[index++] = ps[i].x+size;
                vbuf[index++] = ps[i].y+size;
                vbuf[index++] = ps[i].z;
                vbuf[index++] = ps[i].r;
                vbuf[index++] = ps[i].g;
                vbuf[index++] = ps[i].b;
                
                vbuf[index++] = ps[i].x-size;
                vbuf[index++] = ps[i].y+size;
                vbuf[index++] = ps[i].z;
                vbuf[index++] = ps[i].r;
                vbuf[index++] = ps[i].g;
                vbuf[index++] = ps[i].b;
            }
            
            vbuffer.uploadFromVector(vbuf, 0, numVertices);
            
            
            return vbuffer;
        }
        
    }
    
}


class Particle {
    public var x:Number;
    public var y:Number;
    public var z:Number;
    public var r:Number;
    public var g:Number;
    public var b:Number;
    public var a:Number;
    
    public function Particle(_x:Number, _y:Number, _z:Number, _r:Number, _g:Number, _b:Number, _a:Number) {
        x = _x;
        y = _y;
        z = _z;
        r = _r;
        g = _g;
        b = _b;
        a = _a;
    }
}