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

Tweet + forked from: SiON Tenorion

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

// forked from keim_at_Si's SiON Tenorion
// SiON TENORION
package {
    import com.bit101.components.Label;
    import com.bit101.components.Panel;
    import com.bit101.components.PushButton;
    import com.bit101.components.Window;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.net.navigateToURL;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.utils.escapeMultiByte;
    import org.si.sion.*;
    import org.si.sion.events.*;
    import org.si.sion.sequencer.SiMMLTrack;
    import org.si.sion.utils.SiONPresetVoice;
    
    /**
     * いい音ができたら友達に Twitter で知らせる機能つけた。
     * デバッグプレイヤーのみ対応。
     */
    [SWF(width = "465", height = "465", backgroundColor = "#ffffff", frameRate = 30)]
    public class Tenorion extends Sprite {
        // driver
        public var driver:SiONDriver = new SiONDriver();
        
        // preset voice
        public var presetVoice:SiONPresetVoice = new SiONPresetVoice();
        
        // voices, notes and tracks
        public var tracks:Vector.<SiMMLTrack> = new Vector.<SiMMLTrack>(16);
        public var voices:Vector.<int> = Vector.<int>([ 0, 1, 2, 3,  4, 4, 4, 4,  4, 4, 4, 4,  4, 4, 4, 4]);
        public var notes:Vector.<int>  = Vector.<int>([36,48,60,72, 43,48,55,60, 65,67,70,72, 77,79,82,84]);
        
        // beat counter
        public var beatCounter:int;
        
        // control pad
        public var matrixPad:MatrixPad;
        private var bit:Bit;
        private var label:Label;
        private var panel:Panel;
        private var cnt: uint;
        private var waitCnt: uint;
        private var sendBtn:PushButton;
        
        // constructor
        function Tenorion() {
            driver.setVoice(0, presetVoice["valsound.percus1"]);  // bass drum
            driver.setVoice(1, presetVoice["valsound.percus28"]); // snare drum
            driver.setVoice(2, presetVoice["valsound.percus17"]); // close hihat
            driver.setVoice(3, presetVoice["valsound.percus23"]); // open hihat
            driver.setVoice(4, presetVoice["valsound.bass18"]);
            
            // listen click
            driver.setTimerInterruption(1, _onTimerInterruption);
            driver.setBeatCallbackInterval(1);
            driver.addEventListener(SiONTrackEvent.BEAT, _onBeat);
            driver.addEventListener(SiONEvent.STREAM_START, _onStreamStart);
            
            // control pad
            matrixPad = new MatrixPad(stage);
            matrixPad.x = 72;
            matrixPad.y = 72;
            addChild(matrixPad);

            // start streaming
            driver.play();
            var btn: PushButton = new PushButton(this);
            btn.label = "Tweet";
            btn.x = (465 - btn.width) / 2;
            btn.y = 465 - btn.height;
            btn.buttonMode = true;
            btn.addEventListener(MouseEvent.CLICK, onClick);
            bit = new Bit("http://wonderfl.net/c/hEMO"); // めんどくさくて手打ち
            bit.addEventListener(Event.COMPLETE, onBitComp);
            bit.addEventListener(IOErrorEvent.IO_ERROR, onBitIOError);
            panel = new Panel(this);
            panel.width = panel.height = 465;
            panel.visible = false;
            panel.alpha = 0.5;
            label = new Label(this);
            label.scaleX = label.scaleY = 3;
            label.visible = false;
            sendBtn = new PushButton(this);
            sendBtn.label = "send";
            sendBtn.buttonMode = true;
            sendBtn.x = (465 - btn.width) / 2;
            sendBtn.y = (465 - btn.height) / 2;
            sendBtn.visible = false;
            sendBtn.addEventListener(MouseEvent.CLICK, onClickSend);
            if (WQuery.available) 
            {
                var q: String = WQuery.getQuery("seq");
                if (q == "") return;
                var qs: Array = q.split("_");
                for (var i:int = 0; i < qs.length; i++) 
                {
                    matrixPad.add(i, parseInt(qs[i], 36));
                }
            }
        }
        
        private function onBitIOError(e: IOErrorEvent ): void 
        {
            label.text = "ERROR...";
            waitCnt = cnt + 90;
        }
        
        private function onBitComp(e: Event): void 
        {
            label.text = "COMPLETE!!";
            waitCnt = cnt + 90;
        }
        
        private function onClick(e: MouseEvent ): void 
        {
            var seq: Vector.<int> = matrixPad.sequences;
            var n: int = seq.length;
            var query: String = "?seq=";
            for (var i:int = 0; i < n; i++) 
            {
                query += seq[i].toString(36);
                if (i < n - 1) query += "_";
            }
            waitCnt = uint(-1);
            label.text = "NOW COMPRESSING...";
            panel.visible = label.visible = true;
            matrixPad.enabled = false;
            bit.getURL(query);
            addEventListener(Event.ENTER_FRAME, loop);
        }
        
        private function loop(e: Event ): void 
        {
            label.x = (465 - label.width * label.scaleX) / 2;
            label.y = (465 - label.height * label.scaleY) / 2;
            label.alpha = (cnt % 8);
            cnt ++;
            if (waitCnt < cnt) 
            {
                removeEventListener(Event.ENTER_FRAME, loop);
                label.visible = false;
                cnt = 0;
                if (bit.result == "") 
                {
                    panel.visible = false;
                    matrixPad.enabled = true;
                }
                else 
                {
                    sendBtn.visible = true;
                }
            }
        }
        
        private function onClickSend(e: MouseEvent ): void 
        {
            sendBtn.visible = panel.visible = false;
            matrixPad.enabled = true;
            var url: String = "http://twitter.com/home/?status=" + escapeMultiByte("いい音できた。") + bit.result;
            navigateToURL(new URLRequest(url), "_blank");
        }
        
        
        // _onStreamStart (SiONEvent.STREAM_START) is called back first of all after SiONDriver.play().
        private function _onStreamStart(e:SiONEvent) : void
        {
            // create new controlable tracks and set voice
            for (var i:int=0; i<16; i++) {
                tracks[i] = driver.sequencer.newControlableTrack();
                tracks[i].setChannelModuleType(6, 0, voices[i]);
                tracks[i].velocity = 64;
            }
            beatCounter = 0;
        }
        
        
        // _onBeat (SiONTrackEvent.BEAT) is called back in each beat at the sound timing.
        private function _onBeat(e:SiONTrackEvent) : void 
        {
            matrixPad.beat(e.eventTriggerID & 15);
        }
        
        
        // _onTimerInterruption (SiONDriver.setTimerInterruption) is called back in each beat at the buffering timing.
        private function _onTimerInterruption() : void
        {
            var beatIndex:int = beatCounter & 15;
            for (var i:int=0; i<16; i++) {
                if (matrixPad.sequences[i] & (1<<beatIndex)) tracks[i].keyOn(notes[i]);
            }
            beatCounter++;
        }
    }
}



import flash.display.*;
import flash.events.*;
import flash.geom.*;

class MatrixPad extends Bitmap {
    public var sequences:Vector.<int> = new Vector.<int>(16);
    private var canvas:Shape = new Shape();
    private var buffer:BitmapData = new BitmapData(320, 320, true, 0);
    private var padOn:BitmapData  = _pad(0x303050, 0x6060a0);
    private var padOff:BitmapData = _pad(0x303050, 0x202040);
    private var pt:Point = new Point();
    private var colt:ColorTransform = new ColorTransform(1,1,1,0.1)
    private var _enabled: Boolean = true;
    
    function MatrixPad(stage:Stage) {
        super(new BitmapData(320, 320, false, 0));
        var i:int;
        for (i=0; i<256; i++) {
            pt.x = (i&15)*20;
            pt.y = (i&240)*1.25;
            buffer.copyPixels(padOff, padOff.rect, pt);
            bitmapData.copyPixels(padOff, padOff.rect, pt);
        }
        for (i=0; i<16; i++) sequences[i] = 0;
        addEventListener("enterFrame", _onEnterFrame);
        stage.addEventListener("click",  _onClick);
    }
    
    public function add(track: int, value: uint): void
    {
        for (var i:int = 0; i < 16; i++) 
        {
            if (value >> i & 1) 
            {
                pt.x = i * 20;
                pt.y = (15 - track) * 20;
                buffer.copyPixels(padOn, padOn.rect, pt);
            }
        }
        trace(value);
        sequences[track] = value;
    }
    
    private function _pad(border:int, face:int) : BitmapData {
        var pix:BitmapData = new BitmapData(20, 20, false, 0);
        canvas.graphics.clear();
        canvas.graphics.lineStyle(1, border);
        canvas.graphics.beginFill(face);
        canvas.graphics.drawRect(1, 1, 17, 17);
        canvas.graphics.endFill();
        pix.draw(canvas);
        return pix;
    }
    
    private function _onEnterFrame(e:Event) : void {
        bitmapData.draw(buffer, null, colt);
    }
    
    private function _onClick(e:Event) : void 
    {
        if (!_enabled) return;
        if (mouseX>=0 && mouseX<320 && mouseY>=0 && mouseY<320) {
            var track:int = 15-int(mouseY*0.05), beat:int = int(mouseX*0.05);
            sequences[track] ^= 1<<beat;
            pt.x = beat*20;
            pt.y = (15-track)*20;
            if (sequences[track] & (1<<beat)) buffer.copyPixels(padOn, padOn.rect, pt);
            else buffer.copyPixels(padOff, padOff.rect, pt);
        }
    }
    
    public function set enabled(value: Boolean): void
    {
        _enabled = value;
    }
    
    public function beat(beat16th:int) : void {
        for (pt.x=beat16th*20, pt.y=0; pt.y<320; pt.y+=20) bitmapData.copyPixels(padOn, padOn.rect, pt);
    }
}

/**
 * URL 圧縮するやつ。
 */
class Bit extends EventDispatcher
{
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    
    private const BASE: String = "http://api.bit.ly/shorten?version=2.0.1&apiKey=R_608e24fd300e458016ef6ea805c6ecd6&login=bkwon&format=xml&longUrl=";
    private var loader:URLLoader;
    private var _result: String = "";
    private var wonderflUrl: String;
    
    public function Bit(wonderflURL: String)
    {
        wonderflUrl = wonderflURL;
        loader = new URLLoader();
        loader.addEventListener(Event.COMPLETE, comp);
        loader.addEventListener(IOErrorEvent.IO_ERROR, ioerror);
    }
    
    public function getURL(query: String): void
    {
        var url: String = BASE + wonderflUrl + query;
        _result = "";
        loader.load(new URLRequest(url));
    }
    
    private function ioerror(e: IOErrorEvent ): void 
    {
        dispatchEvent(e.clone());
    }
    
    private function comp(e: Event ): void 
    {
        var res: XML = new XML(loader.data);
        _result = res.results.nodeKeyVal.shortUrl;
        dispatchEvent(e.clone());
    }
    
    public function get result(): String { return _result; }
}


/**
 * 無理やり URL を取得する。(デバッグプレイヤーオンリー)
 * http://wonderfl.net/code/854d4b5fed8c905e98aee6da935a496d79ea6213
 */
class WQuery
{
    import flash.external.ExternalInterface;
    import flash.system.Capabilities;
    
    private static var _qString: String = "///";
    
    public static function get available(): Boolean { return ExternalInterface.available && Capabilities.isDebugger; }
    
    public static function getQuery(key: String): String
    {
        if (qString == "" ) return "";
        var s: int = _qString.indexOf(key + "=");
        if (s < 0) return "";
        var e: int = _qString.indexOf("&", s);
        if (e < 0) e = _qString.length;
        return _qString.substring(s + key.length + 1, e);
    }
    
    public static function get qString():String 
    {
        if (!available) return "";
        try
        {
            if (_qString == "///") _qString = ExternalInterface.call("function() { return window.location.search; }");
        }
        catch (error: Error)
        {
            if (error.errorID == 2060) 
            {
                var msg: String = error.message;
                msg = msg.split(" は ").pop().split(" ").shift();
                if (msg.indexOf("?") < 0) _qString = "";
                else _qString = msg.substr(msg.indexOf("?"));
            }
        }
        return _qString;
    }
}