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 Visualizer #02

----------------------------------
Music by "SHW"(http://shw.in/)
----------------------------------
Get Adobe Flash player
by hycro 14 Feb 2016
/**
 * Copyright hycro ( http://wonderfl.net/user/hycro )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/AfJl2
 */

package
{
    //----------------------------------
    // Music by "SHW"(http://shw.in/)
    //----------------------------------
    
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    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.display.F5MovieClip2DBmp;
    
    [SWF(width="465", height="465", frameRate="60")]
    public class SoundVisualizer2 extends F5MovieClip2DBmp
    {
        private static const POLICY_FILE:String = "http://hycro.crz.jp/crossdomain.xml";
        private static const SOUND_FILE:String = "http://hycro.crz.jp/wonderfl/sound/tsudumi-japan2.mp3";
        
        private const Radius:uint = 100;
        
        private var _sound:Sound;
        private var _channel:SoundChannel;
        
        private var _circle:Circle;
        private var _count:uint = 0;
        
        /**
         * コンストラクタ
         * 
         */
        public function SoundVisualizer2()
        {
            _circle = new Circle(0, 128);
            _sound = new Sound();
            
            _sound.load(new URLRequest(SOUND_FILE), new SoundLoaderContext(5000, true));
            _sound.addEventListener(ProgressEvent.PROGRESS, onProgress);
            _sound.addEventListener(Event.COMPLETE, onLoadComplete);
        }
        
        /**
         * 描画関連の初期化
         * 
         */
        public function setup():void {
            size(stage.stageWidth, stage.stageHeight);
            background(0x0);
            stroke(255, .8);
            noFill();
        }
        
        /**
         * 音楽ファイルロード中の処理
         * 
         */
        private function onProgress(evt:ProgressEvent):void {
            _circle.radius = Radius * evt.bytesLoaded / evt.bytesTotal;
        }
        
        /**
         * 音楽ファイルロード完了
         * 
         */
        private function onLoadComplete(evt:Event):void {
            _channel = _sound.play(0, int.MAX_VALUE);
            _circle.radius = Radius;
        }
        
        /**
         * 頂点データの更新
         * 
         */
        private function updateCircle():void {
            var data:ByteArray = new ByteArray();
            SoundMixer.computeSpectrum(data, true);
            
            var volume:Vector.<Number> = new Vector.<Number>(128);
            for (var i:uint = 0; i<64; i++) {
                volume[i] = 128*Math.sqrt((data.readFloat() + data.readFloat() + data.readFloat() + data.readFloat()) / 4);
            }
            for (var j:uint = 0; j<64; j++) {
                volume[128-j-1] = 128*Math.sqrt((data.readFloat() + data.readFloat() + data.readFloat() + data.readFloat()) / 4);
            }
            
            _circle.update(volume);
        }
        
        /**
         * 描画
         * 
         */
        public function draw():void {
            if (_channel) {
                updateCircle();
            }
            
            translate( stage.stageWidth / 2,  stage.stageHeight / 2 );
            
            beginShape();
            for each (var v:Vertex in _circle.vertices) {
                this.curveVertex(v.x, v.y);
            }
            this.curveVertex(_circle.vertices[0].x, _circle.vertices[0].y);
            this.curveVertex(_circle.vertices[1].x, _circle.vertices[1].y);
            this.curveVertex(_circle.vertices[2].x, _circle.vertices[2].y);
            endShape();
            
            if (_count++ % 3 == 0) {
                bitmapData.colorTransform(bitmapData.rect, new ColorTransform(.965, .945, .945));
            }
            if (_count % 5 == 0) {
                this.bitmapData.applyFilter(bitmapData, bitmapData.rect, new Point(0, 0), new BlurFilter(4, 4));
            }
        }
    }
}

class Circle {
    private var _vertices:Vector.<Vertex>;
    private var _radius:Number;
    private var _slice:uint;
    /**
     * コンストラクタ
     * 
     * @param radius 半径
     * @param slice 円周の分割数
     */
    public function Circle(radius:Number=100, slice:uint=512) {
        _vertices = new Vector.<Vertex>();
        _radius = radius;
        _slice = slice;
        
        var degree:Number = 3*Math.PI/2;
        for (var i:uint = 0; i<slice; i++) {
            _vertices.push(new Vertex(radius, degree));
            degree += 2 * Math.PI / slice;
        }
    }
    
    /**
     * 頂点データの取得
     * 
     */
    public function get vertices():Vector.<Vertex> {
        return _vertices;
    }
    
    /**
     * 半径の設定
     * 
     */
    public function set radius(value:Number):void {
        _radius = value;
        for each (var v:Vertex in _vertices) {
            v.radius = value;
        }
    }
    
    /**
     * 頂点データの更新
     * 
     * @param level 各頂点の移動量
     */
    public function update(level:Vector.<Number>):void {
        for (var i:uint=0; i<level.length; i++) {
            if (_vertices[i].radius > _radius + level[i]) {
                _vertices[i].radius = Math.max(_radius, _vertices[i].radius - 5);
            } else {
                _vertices[i].radius = Math.max(_vertices[i].radius, _radius + level[i]);
            }
        }
    }
}

class Vertex {
    private var _radius:Number;
    private var _degree:Number;
    private var _mutable:Boolean;
    
    private var _x:Number;
    private var _y:Number;
    
    public function Vertex(radius:Number, degree:Number, mutable:Boolean=true) {
        _radius = radius;
        _degree = degree;
        _mutable = mutable;
        if (!_mutable) {
            _x = _radius * Math.cos(_degree);
            _y = -_radius * Math.sin(_degree);
        }
    }
    
    public function get x():Number {
        if (_mutable) {
            return _radius * Math.cos(_degree);
        } else {
            return _x;
        }
    }
    
    public function get y():Number {
        if (_mutable) {
            return -_radius * Math.sin(_degree);
        } else {
            return _y;
        }
    }

    public function get radius():Number
    {
        return _radius;
    }

    public function set radius(value:Number):void
    {
        if (_mutable) {
            _radius = value;
        }
    }

    public function get degree():Number
    {
        return _degree;
    }

    public function set degree(value:Number):void
    {
        if (_mutable) {
            _degree = value;
        }
    }
}