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

SiON Tenorion with Union Platform

SiON TENORION
Get Adobe Flash player
by keno42 01 Mar 2010
/**
 * Copyright keno42 ( http://wonderfl.net/user/keno42 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2P1U
 */

// SiON TENORION
package {
    import flash.display.Sprite;
    import flash.events.*;
    import flash.text.TextField;
	import net.user1.reactor.IClient;
	import net.user1.reactor.Reactor;
	import net.user1.reactor.ReactorEvent;
	import net.user1.reactor.Room;
	import net.user1.reactor.RoomEvent;
    import org.si.sion.*;
    import org.si.sion.events.*;
    import org.si.sion.sequencer.SiMMLTrack;
    import org.si.sion.utils.SiONPresetVoice;
    
    
    [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;
        
		// union
		private var c:Reactor = new Reactor();
		private var r:Room;
		
        // constructor
        function Tenorion() {
            Wonderfl.capture_delay( 10 );
            
            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;
			matrixPad.addEventListener( DataEvent.CHANGE, onChange );
			
			// connect to union server
			connect();
		}
		
		// invoked when change event occurs by MatrixPad
		protected function onChange(e:DataEvent):void {
			if ( c.isReady() ) {
				if ( r.clientIsInRoom() ) {
					r.sendMessage( "I_CLICKED_SOMEWHERE", true, null, e.track, e.beat, e.bit );
				}
			}
		}
		
		// connect to union server
		protected function connect():void{
			c.addEventListener(ReactorEvent.READY, onReady);
			c.connect("tryunion.com", 9100);
		}
		
		// invoked when the connection is ready
		private function onReady(e:ReactorEvent):void {
			c.getMessageManager().addMessageListener("GIVE_ME_LOG", sendLog);
			c.getMessageManager().addMessageListener("THIS_IS_LOG", happyToReceiveLog);
			r = c.getRoomManager().createRoom("tenorion_share");
			r.addMessageListener("I_CLICKED_SOMEWHERE", someoneClicked );
			r.addEventListener(RoomEvent.SYNCHRONIZE, onSynchronize);
			r.join();
		}
		
		// invoked when received map from someone
		protected function happyToReceiveLog(from:IClient, data:String):void {
			
			matrixPad.setSequences(Vector.<int>(data.split(",")));
			start();
		}
		
		// send map to new comer
		protected function sendLog(from:IClient):void {
			var data:Array = [];
			for each( var value:int in matrixPad.sequences ) {
				data.push( value );
			}
			from.sendMessage("THIS_IS_LOG", data.join(","));
		}
		
		// invoked when joined the room
		protected function onSynchronize(e:RoomEvent):void {
			if ( r.getClients().length == 1 ) {
				start();
			} else {
				var topClient:IClient = r.getClients()[0];
				topClient.sendMessage("GIVE_ME_LOG");
			}
			
		}
		
		// invoked when received click action by someone other
		protected function someoneClicked(from:IClient, track:int, beat:int, bit:int):void {
			matrixPad.clickAction(track, beat, bit);
			var ttf:TempTF = new TempTF("id: " + from.getClientID());
			this.addChild( ttf );
			ttf.x = matrixPad.x + beat * 20 + 10;
			ttf.y = matrixPad.y + (15 - track) * 20 + 5;
		}
		
		// start playing when the map is ready
		private function start():void{
            addChild(matrixPad);
            // start streaming
            driver.play();
        }
        
        
        // _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.*;
import flash.text.engine.FontDescription;

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)
    
    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);
    }
    
	// set sequence and make the map of on/off
	public function setSequences(data:Vector.<int>):void {
		sequences = data;
		for ( var track:int = 0; track < 16; track++ ) {
			for ( var beat:int = 0; beat < 16; 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);
			}
		}
	}
	
    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);
    }
	
	// reflect someone's click action
	public function clickAction(track:int, beat:int, bit:int):void {
		if ( bit ) sequences[track] |= bit;
		else sequences[track] &= 0xFFFF ^ (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);
	}
    
    private function _onClick(e:Event) : void {
        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;
			dispatchEvent( new DataEvent( DataEvent.CHANGE, track, beat, sequences[track] & (1 << beat) ) );
        }
    }
    
    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);
    }
}
import flash.text.TextField;

class TempTF extends Sprite {
	public var tf:TextField = new TextField();
	public function TempTF(str:String) {
		tf.text = str;
		tf.textColor = 0xFF8888FF;
		this.mouseEnabled = this.mouseChildren = false;
		this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		this.alpha = 3;
		this.addChild( tf );
	}
	private function onEnterFrame(e:Event):void {
		this.alpha *= 0.95;
		if ( this.alpha < 0.1 ) {
			this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			if ( this.parent != null ) {
				this.parent.removeChild( this );
			}
		}
	}
}

class DataEvent extends Event {
	public var track:int;
	public var beat:int;
	public var bit:int;
	public static const CHANGE:String = "change";
	public function DataEvent(type:String, track:int, beat:int, bit:int, bubbles:Boolean = false, cancelable:Boolean = false ) {
		this.track = track;
		this.beat = beat;
		this.bit = bit;
		super(type, bubbles, cancelable);
	}
	public override function toString():String {
		return super.toString() + "[track:" + track + ", beat:" + beat +", bit:" + bit + "]";
	}
}