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

forked from: BeatDrawing + MP3 Choice

Just added loading MP3 from hard drive to see how it visualizes other songs. 
Cool stuff, reminds me of one my own visualizer from here http://wonderwhy-er.deviantart.com/gallery/2601142#/d1j6l06
Will need to get to porting it to WonderFl :)

Update: 
Tuned params a little to allow more quite songs to produce some change
Also removed random colors and made coloring somewhat change with the song
/**
 * Copyright wonderwhyer ( http://wonderfl.net/user/wonderwhyer )
 * GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
 * Downloaded from: http://wonderfl.net/c/vFvs
 */

// forked from rettuce's BeatDrawing
package
{
    import flash.geom.ColorTransform;
    import flash.display.GradientType;
    import caurina.transitions.Tweener;
    
    //import com.demonsters.debugger.MonsterDebugger;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.filters.BlurFilter;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.media.Sound;
    import flash.media.SoundLoaderContext;
    import flash.media.SoundMixer;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.utils.ByteArray;
    import com.codeazur.as3swf.SWF;
    import com.codeazur.as3swf.SWFData;
    import com.codeazur.as3swf.data.SWFScene;
    import com.codeazur.as3swf.data.SWFSymbol;
    import com.codeazur.as3swf.data.consts.SoundCompression;
    import com.codeazur.as3swf.data.consts.SoundRate;
    import com.codeazur.as3swf.data.consts.SoundSize;
    import com.codeazur.as3swf.data.consts.SoundType;
    import com.codeazur.as3swf.tags.TagDefineSceneAndFrameLabelData;
    import com.codeazur.as3swf.tags.TagDefineSound;
    import com.codeazur.as3swf.tags.TagDoABC;
    import com.codeazur.as3swf.tags.TagEnd;
    import com.codeazur.as3swf.tags.TagFileAttributes;
    import com.codeazur.as3swf.tags.TagSetBackgroundColor;
    import com.codeazur.as3swf.tags.TagShowFrame;
    import com.codeazur.as3swf.tags.TagSymbolClass;
    import flash.media.SoundChannel;
    import flash.net.FileFilter;
    import flash.net.FileReference;
    import flash.events.MouseEvent;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    
    /**
     * ...
     * @author rettuce
     * 
     */
    
    [SWF(width = 465, height = 465, backgroundColor = 0xFFFFFF, frameRate = 60)]
    
    public class Beat extends Sprite
    {
        public function Beat()
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init );
        }        
        private function init(e:Event = null ):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init );
            setStage();
            
            stage.addEventListener(MouseEvent.MOUSE_UP,up);
            var txt:TextField = new TextField();
            txt.defaultTextFormat = new TextFormat(null,12,0x000000);
            txt.autoSize = TextFieldAutoSize.LEFT;
            txt.selectable=false;
            txt.text = "Click anywhere to select an mp3 file";
            txt.x = 120;      
            
            // SoundMixer
            playSoundMixer();
            
            addChild(txt);
            
            addEventListener(Event.ENTER_FRAME,beatCheck2);            
            loaderInfo.addEventListener(Event.UNLOAD, function(e:Event):void {
                stage.removeEventListener(Event.RESIZE, resizeEvent);
                loaderInfo.removeEventListener(Event.UNLOAD, arguments.callee );
            });
        }
        /* sound loading */
        ///////////////////////////////////////////////////////////////////////
        
        public var fr:FileReference;
        public var soundSource:Sound;
        public var currentSong:SoundChannel;
        
        public function up(e:Event):void {
            fr = new FileReference();
            fr.addEventListener(Event.SELECT, onFileSelected);
            fr.addEventListener(Event.COMPLETE, parse);
            var mp3Filter:FileFilter = new FileFilter("mp3","*.mp3");
            fr.browse([mp3Filter]);
            if (currentSong)
            {
                currentSong.stop();
                currentSong = null;
            }
        }
        
        public function onFileSelected(e:Event):void
        {
            fr.load();
        }
        
        public function parse(e:Event):void
        {
            var swf:ByteArray = createSWFFromMP3(fr.data);
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.INIT, SoundLoaded);
            loader.loadBytes(swf);
        }
        
        public function SoundLoaded(e:Event):void
        {
            initPoints();
            
            var SoundClass:Class = LoaderInfo(e.currentTarget).applicationDomain.getDefinition("MP3Wrapper_soundClass") as Class;

            soundSource = new SoundClass() as Sound;
            currentSong = soundSource.play();
            currentSong.addEventListener(Event.COMPLETE,songEnded);
        }
        
        public function songEnded(e:Event):void 
        {
            currentSong = null;            
        }

        
        public function createSWFFromMP3(mp3:ByteArray):ByteArray
        {
            // Create an empty SWF
            // Defaults to v10, 550x400px, 50fps, one frame (works fine for us)
            var swf:SWF = new SWF();

            // Add FileAttributes tag
            // Defaults: as3 true, all other flags false (works fine for us)
            swf.tags.push(new TagFileAttributes());

            // Add SetBackgroundColor tag
            // Default: white background (works fine for us)
            swf.tags.push(new TagSetBackgroundColor());

            // Add DefineSceneAndFrameLabelData tag 
            // (with the only entry being "Scene 1" at offset 0)
            var defineSceneAndFrameLabelData:TagDefineSceneAndFrameLabelData = new TagDefineSceneAndFrameLabelData();
            defineSceneAndFrameLabelData.scenes.push(new SWFScene(0, "Scene 1"));
            swf.tags.push(defineSceneAndFrameLabelData);

            // Add DefineSound tag
            // The ID is 1, all other parameters are automatically
            // determined from the mp3 itself.
            swf.tags.push(TagDefineSound.createWithMP3(1, mp3));

            // Add DoABC tag
            // Contains the AS3 byte code for the document class and the 
            // class definition for the embedded sound
            swf.tags.push(TagDoABC.create(abc));

            // Add SymbolClass tag
            // Specifies the document class and binds the sound class
            // definition to the embedded sound
            var symbolClass:TagSymbolClass = new TagSymbolClass();
            symbolClass.symbols.push(SWFSymbol.create(1, "MP3Wrapper_soundClass"));
            symbolClass.symbols.push(SWFSymbol.create(0, "MP3Wrapper"));
            swf.tags.push(symbolClass);

            // Add ShowFrame tag
            swf.tags.push(new TagShowFrame());

            // Add End tag
            swf.tags.push(new TagEnd());

            // Publish the SWF
            var swfData:SWFData = new SWFData();
            swf.publish(swfData);

            return swfData;
        }
        
        private static var abcData:Array = [
            0x10, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x07, 0x6d, 0x78, 0x2e, 0x63, 0x6f, 0x72, 0x65, 
            0x0a, 0x49, 0x46, 0x6c, 0x65, 0x78, 0x41, 0x73, 0x73, 0x65, 0x74, 0x0a, 0x53, 0x6f, 0x75, 0x6e, 
            0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x0b, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x6d, 0x65, 0x64, 
            0x69, 0x61, 0x05, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x6d, 0x78, 0x2e, 0x63, 0x6f, 0x72, 0x65, 
            0x3a, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x00, 0x15, 0x4d, 0x50, 0x33, 
            0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6c, 0x61, 
            0x73, 0x73, 0x0a, 0x4d, 0x50, 0x33, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x0d, 0x66, 0x6c, 
            0x61, 0x73, 0x68, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x06, 0x53, 0x70, 0x72, 0x69, 
            0x74, 0x65, 0x0a, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x05, 0x43, 0x6c, 
            0x61, 0x73, 0x73, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 
            0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x32, 0x30, 0x30, 0x36, 0x2f, 0x66, 0x6c, 
            0x65, 0x78, 0x2f, 0x6d, 0x78, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x07, 0x56, 
            0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x07, 0x33, 0x2e, 
            0x30, 0x2e, 0x30, 0x2e, 0x30, 0x0b, 0x6d, 0x78, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 
            0x6c, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0c, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x65, 
            0x76, 0x65, 0x6e, 0x74, 0x73, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x70, 0x61, 
            0x74, 0x63, 0x68, 0x65, 0x72, 0x0d, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x62, 0x6a, 
            0x65, 0x63, 0x74, 0x11, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 
            0x62, 0x6a, 0x65, 0x63, 0x74, 0x16, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x62, 0x6a, 
            0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x16, 0x01, 0x16, 
            0x04, 0x18, 0x06, 0x16, 0x07, 0x18, 0x08, 0x16, 0x0a, 0x18, 0x09, 0x08, 0x0e, 0x16, 0x14, 0x03, 
            0x01, 0x01, 0x01, 0x04, 0x14, 0x07, 0x01, 0x02, 0x07, 0x01, 0x03, 0x07, 0x02, 0x05, 0x09, 0x02, 
            0x01, 0x07, 0x04, 0x08, 0x07, 0x04, 0x09, 0x07, 0x06, 0x0b, 0x07, 0x04, 0x0c, 0x07, 0x04, 0x0d, 
            0x07, 0x08, 0x0f, 0x07, 0x04, 0x10, 0x07, 0x01, 0x12, 0x09, 0x03, 0x01, 0x07, 0x04, 0x13, 0x07, 
            0x09, 0x15, 0x09, 0x08, 0x02, 0x07, 0x06, 0x16, 0x07, 0x06, 0x17, 0x07, 0x06, 0x18, 0x0d, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
            0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x03, 0x09, 0x03, 0x01, 
            0x04, 0x05, 0x00, 0x05, 0x02, 0x09, 0x05, 0x00, 0x08, 0x00, 0x06, 0x07, 0x09, 0x07, 0x00, 0x0b, 
            0x01, 0x08, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x04, 0x01, 0x0a, 0x06, 0x01, 0x0b, 0x11, 0x01, 
            0x07, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x01, 0x0c, 0x06, 0x00, 0x00, 0x08, 0x08, 0x03, 0x01, 0x01, 
            0x04, 0x00, 0x00, 0x06, 0x01, 0x02, 0x04, 0x00, 0x01, 0x09, 0x01, 0x05, 0x04, 0x00, 0x02, 0x0c, 
            0x01, 0x06, 0x04, 0x01, 0x03, 0x0c, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0xd0, 0x30, 0x47, 0x00, 
            0x00, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x47, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x02, 0x0a, 
            0xd0, 0x30, 0x5d, 0x04, 0x20, 0x58, 0x00, 0x68, 0x01, 0x47, 0x00, 0x00, 0x04, 0x02, 0x01, 0x05, 
            0x06, 0x09, 0xd0, 0x30, 0x5e, 0x0a, 0x2c, 0x11, 0x68, 0x0a, 0x47, 0x00, 0x00, 0x05, 0x01, 0x01, 
            0x06, 0x07, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, 0x06, 0x02, 0x01, 0x01, 0x05, 
            0x17, 0xd0, 0x30, 0x5d, 0x0d, 0x60, 0x0e, 0x30, 0x60, 0x0f, 0x30, 0x60, 0x03, 0x30, 0x60, 0x03, 
            0x58, 0x01, 0x1d, 0x1d, 0x1d, 0x68, 0x02, 0x47, 0x00, 0x00, 0x07, 0x01, 0x01, 0x06, 0x07, 0x03, 
            0xd0, 0x30, 0x47, 0x00, 0x00, 0x08, 0x01, 0x01, 0x07, 0x08, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 
            0x47, 0x00, 0x00, 0x09, 0x02, 0x01, 0x01, 0x06, 0x1b, 0xd0, 0x30, 0x5d, 0x10, 0x60, 0x0e, 0x30, 
            0x60, 0x0f, 0x30, 0x60, 0x03, 0x30, 0x60, 0x02, 0x30, 0x60, 0x02, 0x58, 0x02, 0x1d, 0x1d, 0x1d, 
            0x1d, 0x68, 0x05, 0x47, 0x00, 0x00, 0x0a, 0x01, 0x01, 0x08, 0x09, 0x03, 0xd0, 0x30, 0x47, 0x00, 
            0x00, 0x0b, 0x02, 0x01, 0x09, 0x0a, 0x0b, 0xd0, 0x30, 0xd0, 0x60, 0x05, 0x68, 0x08, 0xd0, 0x49, 
            0x00, 0x47, 0x00, 0x00, 0x0c, 0x02, 0x01, 0x01, 0x08, 0x23, 0xd0, 0x30, 0x65, 0x00, 0x60, 0x0e, 
            0x30, 0x60, 0x0f, 0x30, 0x60, 0x11, 0x30, 0x60, 0x12, 0x30, 0x60, 0x13, 0x30, 0x60, 0x07, 0x30, 
            0x60, 0x07, 0x58, 0x03, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x68, 0x06, 0x47, 0x00, 0x00
        ];

        private static function abcDataToByteArray():ByteArray {
            var ba:ByteArray = new ByteArray();
            for (var i:uint = 0; i < abcData.length; i++) {
                ba.writeByte(abcData[i]);
            }
            return ba;
        }
        
        private static var abc:ByteArray = abcDataToByteArray();      
        
        
        
        /* Sound Mixer */
        ///////////////////////////////////////////////////////////////////////
        
        private var _bArr:ByteArray = new ByteArray();
        private var _pArr:Array = [];
        private var _stg:Sprite;
        private var _bg:Bitmap;
        private var color:Number;
        private function initPoints():void
        {
            color = 0;
            for(var i:int=0; i<512; i++){
                _pArr[i] = new Point();
            }
        }

        
        private function playSoundMixer():void
        {            
            _bg = new Bitmap();
            _bg.bitmapData = new BitmapData(stage.stageWidth, stage.stageHeight );
            addChild(_bg);
            
            _stg = new Sprite();
            _stg.x = stage.stageWidth/2;
            _stg.y = stage.stageHeight/2;
            addChild(_stg);                               
        }
        
        private function beatCheck2(e:Event):void
        {
            if(currentSong==null)
                return;
            
            SoundMixer.computeSpectrum(_bArr, false, 0);    // byteArr(length=512), FFT, rate 0->44.1 KHz, 1->22.05KHz...
            _bArr.position = 0;
            
            var byteTotal:Number = 0;    // 両音
            var totalR:Number    = 0;    // 右パン
            var totalL:Number    = 0;    // 左パン
            var byte:Number      = 0;
            var sum:Number = 0;
            for(var i:int = 0; i < 512; i++)
            {
                
                byte =_bArr.readFloat();
                sum += byte;
                byte = Math.abs(byte);
                
                byteTotal += byte;
                
                if(i<256) totalR += byte;
                else totalL += byte;
                                
                if(byte>0.01)
                {
                    Tweener.addTween( _pArr[i], { 
                        x:Math.cos((i*360/512-90)*Math.PI/180)*400*(byte-0.005),
                        y:Math.sin((i*360/512-90)*Math.PI/180)*400*(byte-0.005),
                        time:0.2, transition:'easeOutQuad'
                    });
                };
            };            
            
            color+=sum/500;

            
            _stg.graphics.clear();
            _stg.graphics.lineStyle(0.5,0x000000);
            _stg.graphics.beginFill(HSLtoRGB(1,color*360,1,(Math.sin(color)+1)*0.25+0.25));
            _stg.graphics.moveTo(_pArr[0].x,_pArr[0].y);
            for(var m:int=0; m<_pArr.length-1; m++){
                var px:Number = (_pArr[m].x + _pArr[m+1].x)/2;
                var py:Number = (_pArr[m].y + _pArr[m+1].y)/2;                
                _stg.graphics.curveTo(_pArr[m].x, _pArr[m].y, px, py);
            }
            _stg.graphics.lineTo(_pArr[_pArr.length-1].x, _pArr[_pArr.length-1].y );
            _stg.graphics.lineTo(_pArr[0].x,_pArr[0].y);   
            //_stg.graphics.drawCircle(0,0,200);
            _stg.graphics.endFill();
            
            // 音の平均値
            byteTotal /= 512;
            
            // 左右パン平均値
            totalR /= 256; 
            totalL /= 256;             

            if(byteTotal>0.1){
                _bg.bitmapData.draw( stage);
            }
            _bg.bitmapData.colorTransform(_bg.bitmapData.rect,new ColorTransform(1,1,1,1,3,3,3));         
        }
        
        
        
        private function HSLtoRGB(a:Number=1,hue:Number=0,saturation:Number=1,lightness:Number=0.5):uint
        {
            a = Math.max(0,Math.min(1,a));
            saturation = Math.max(0,Math.min(1,saturation));
            lightness = Math.max(0,Math.min(1,lightness));
            hue = hue%360;
            if(hue<0)hue+=360;
            hue/=60;
            var C:Number = (1-Math.abs(2*lightness-1))*saturation;
            var X:Number = C*(1-Math.abs((hue%2)-1));
            var m:Number = lightness-0.5*C;
            C=(C+m)*255;
            X=(X+m)*255;
            m*=255;
             if(hue<1) return (C<<16) + (X<<8) + m;
             if(hue<2) return (X<<16) + (C<<8) + m;
             if(hue<3) return (m<<16) + (C<<8) + X;
             if(hue<4) return (m<<16) + (X<<8) + C;
             if(hue<5) return (X<<16) + (m<<8) + C;
             return (C<<16) + (m<<8) + X;
        }        
        
        
            
        
        
        
        
        
        
        
        
        
        /* Error Handler */
        //////////////////////////////////////////////////////////////////
        
        private function errorHandler(e:IOErrorEvent):void
        {
            //MonsterDebugger.trace( 'Error...', e );
        }
        
        
        /* stage set */
        //////////////////////////////////////////////////////////////////
        
        private function setStage():void
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.addEventListener(Event.RESIZE, resizeEvent);
            resizeHandler();
        }
        private function resizeEvent(e:Event = null):void
        {
            resizeHandler();
        }        
        public function resizeHandler():void
        {
            
        }

    }
}