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

SoundSpectrum 2012-7-17 02

Get Adobe Flash player
by bongiovi015 16 Jul 2012

    Talk

    gaurav.rane at 28 Nov 2012 17:14
    Hi, Can you put up a tutorial for this up on your blog.
    Embed
/**
 * Copyright bongiovi015 ( http://wonderfl.net/user/bongiovi015 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/h2bn
 */

package {
    import com.adobe.utils.AGALMiniAssembler;
    import com.adobe.utils.PerspectiveMatrix3D;
    
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.Shape;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DTextureFormat;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.VertexBuffer3D;
    import flash.display3D.textures.Texture;
    import flash.events.Event;
    import flash.geom.Matrix;
    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 flash.display.Sprite;
    import flash.display3D.Context3D;
    import flash.events.Event;
    
    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/2;
        public const NUM_LINES                    : int = 120/2;
        public const SPAN                        : Number = 20;
        public const PARTICLE_SIZE                : int = 7;
        
        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();
            _initTexture();
            _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 _initTexture() : void {
            var textureSize:Number = 256;
            var strokeWeight:Number = 5;
            var s:Shape = new Shape();
            s.graphics.beginFill(0x000000, 1);
            s.graphics.drawRect(0, 0, textureSize, textureSize);
            s.graphics.endFill();
            
            s.graphics.beginFill(0xFFFFFF, 1);
            s.graphics.drawRect(strokeWeight, strokeWeight, textureSize-strokeWeight*2, textureSize-strokeWeight*2);
            s.graphics.endFill();
            
            var texture:Texture = context.createTexture(textureSize, textureSize, Context3DTextureFormat.BGRA, false);
            var ws:int = textureSize;
            var hs:int = textureSize;
            var tmp:BitmapData;
            var level:int=0;
            var transform:Matrix = new Matrix();
            tmp = new BitmapData(s.width, s.height, true, 0x00000000);
            while ( ws >= 1 && hs >= 1 ) {
                tmp.draw(s, transform, null, null, null, true); 
                texture.uploadFromBitmapData(tmp, level);
                transform.scale(0.5, 0.5);
                level++;
                ws >>= 1;
                hs >>= 1;
                if (hs && ws) {
                    tmp.dispose();
                    tmp = new BitmapData(ws, hs, true, 0x00000000);
                }
            }
            tmp.dispose();
            
            context.setTextureAt(0, texture);
        }
        
        
        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) * 180, new Vector3D(0, 0, 1), center);
            viewMatrix.appendRotation( -(stage.mouseY / stage.stageHeight-.5) * 180, 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_2);
            context.setVertexBufferAt(2, _vbuffer, 5, 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;
                }
            }
            
            _getVertexBufferFromParticles();
        }        
        
        
        private function _getVertexBufferFromParticles() : void {
            var numVertices:int = _particles.length * 4;
            _vbuffer = context.createVertexBuffer(numVertices, 8);
            var vbuf:Vector.<Number> = new Vector.<Number>(numVertices * 8);
            var index:int = 0, i:int, j:int, tempIndex:int, ti:int, tj:int;
            var r:Number, g:Number, b:Number;
            
            for (j=0; j<NUM_SAMPLE; j++) {
                for (i=0; i<NUM_LINES; i++) {
                    tempIndex = j*NUM_LINES + i;
                    vbuf[index++] = _particles[tempIndex].x;
                    vbuf[index++] = _particles[tempIndex].y;
                    vbuf[index++] = _particles[tempIndex].z;
                    vbuf[index++] = 0;
                    vbuf[index++] = 0;
                    vbuf[index++] = _particles[tempIndex].r;
                    vbuf[index++] = _particles[tempIndex].g;
                    vbuf[index++] = _particles[tempIndex].b;
                    r = _particles[tempIndex].r;
                    g = _particles[tempIndex].g;
                    b = _particles[tempIndex].b;
                    
                    ti = i == NUM_LINES-1 ? i : i+1;
                    tj = j;
                    tempIndex = tj*NUM_LINES + ti;
                    vbuf[index++] = _particles[tempIndex].x;
                    vbuf[index++] = _particles[tempIndex].y;
                    vbuf[index++] = _particles[tempIndex].z;
                    vbuf[index++] = 1;
                    vbuf[index++] = 0;
                    vbuf[index++] = r;
                    vbuf[index++] = g;
                    vbuf[index++] = b;
                    
                    ti = i == NUM_LINES-1 ? i : i+1;
                    tj = j == NUM_SAMPLE-1 ? j : j+1;
                    tempIndex = tj*NUM_LINES + ti;
                    vbuf[index++] = _particles[tempIndex].x;
                    vbuf[index++] = _particles[tempIndex].y;
                    vbuf[index++] = _particles[tempIndex].z;
                    vbuf[index++] = 1;
                    vbuf[index++] = 1;
                    vbuf[index++] = r;
                    vbuf[index++] = g;
                    vbuf[index++] = b;
                    
                    ti = i;
                    tj = j == NUM_SAMPLE-1 ? j : j+1;
                    tempIndex = tj*NUM_LINES + ti;
                    vbuf[index++] = _particles[tempIndex].x;
                    vbuf[index++] = _particles[tempIndex].y;
                    vbuf[index++] = _particles[tempIndex].z;
                    vbuf[index++] = 0;
                    vbuf[index++] = 1;
                    vbuf[index++] = r;
                    vbuf[index++] = g;
                    vbuf[index++] = b;
                }
            }
            
            _vbuffer.uploadFromVector(vbuf, 0, numVertices);
        }        
        
        
        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";
            code += "mov v1, va2\n";
            var vertexShader:ByteArray = agal.assemble(Context3DProgramType.VERTEX, code);
            
            
            code = "mov oc, v0\n";
            code = "tex ft1, v0, fs0 <2d,clamp,linear,mipnearest>\n";
            code += "mul oc ft1, v1\n";
            var fragmentShader:ByteArray = agal.assemble(Context3DProgramType.FRAGMENT, code);
            
            var program:Program3D = context.createProgram();
            program.upload(vertexShader, fragmentShader);
            context.setProgram(program);
        }
        
    }
    
}


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;
    }
}