/**
* Copyright civet ( http://wonderfl.net/user/civet )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dQrA
*/
// forked from civet's Hello Signals
/**
* Hello Signals(AS3Signals required!!)
* -drag your mouse to play
* @author civet
* 2010-06-29 01:04:02
*/
package {
import flash.filters.BlurFilter;
import flash.display.*;
import flash.events.*;
import frocessing.color.ColorHSV;
import org.si.sion.*;
import org.si.sion.utils.*;
import org.si.sion.events.*;
import com.bit101.components.*;
[SWF(frameRate="30")]
public class HelloSignals extends Sprite
{
public var mouseDown:NativeSignal;
public var mouseUp:NativeSignal;
public var mouseMove:NativeSignal;
private var stroke:Shape;
private var circles:Array = [];
private var currentCircle:ColorCircle;
private var colorHSV:ColorHSV = new ColorHSV();
private var grid:Shape;
public function HelloSignals()
{
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void
{
mouseDown = new NativeSignal(this.stage, MouseEvent.MOUSE_DOWN, MouseEvent);
mouseUp = new NativeSignal(this.stage, MouseEvent.MOUSE_UP, MouseEvent);
mouseMove = new NativeSignal(this.stage, MouseEvent.MOUSE_MOVE, MouseEvent);
mouseDown.add(onMouseDown);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
grid = new Shape();
this.addChild(grid);
drawGrid(stage.stageWidth, stage.stageHeight);
stroke = new Shape();
this.addChild(stroke);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
initSound();
}
private function onMouseDown(e:Event):void
{
if(e.currentTarget != e.target && !(e.target is ColorCircle)) return;
colorHSV.h += 6;
colorHSV.h %= 360;
var circle:ColorCircle = new ColorCircle();
circle.x = mouseX;
circle.y = mouseY;
circle.draw(4, colorHSV.value);
this.addChild(circle);
currentCircle = circle;
mouseUp.addOnce(onMouseUp);
mouseMove.add(onMouseMove);
}
private function onMouseMove(e:Event):void
{
stroke.graphics.clear();
stroke.graphics.lineStyle(2, currentCircle.color);
stroke.graphics.moveTo(currentCircle.x, currentCircle.y);
stroke.graphics.lineTo(mouseX, mouseY);
}
private function onMouseUp(e:Event):void
{
mouseMove.remove(onMouseMove);
stroke.graphics.clear();
var dx:Number = mouseX - currentCircle.x;
var dy:Number = mouseY - currentCircle.y;
var r:Number = Math.sqrt(dx*dx+dy*dy);
currentCircle.draw(r, currentCircle.color);
circles.push(currentCircle);
//noteOn
var length:Number = r/10;
if(length == 0) return;
var note:int = 60 + int(currentCircle.x/20) -12;//bug fixed
driver.noteOn(note, voice, length, 0);
}
private function onEnterFrame(e:Event):void
{
var i:int = circles.length;
while(i--) {
var circle:ColorCircle = circles[i];
if(circle.isDead) {
circles.splice(i, 1);
this.removeChild(circle);
}
else circle.fadeOut();
}
}
private var driver:SiONDriver;
private var voice:SiONVoice;
private var presetVoice:SiONPresetVoice;
private var categoryList:ComboBox;
private var voiceList:ComboBox;
private var input:Text;
private function initSound():void
{
driver = new SiONDriver();
driver.play();
presetVoice = new SiONPresetVoice();
voice = new SiONVoice(5, 0);
categoryList = new ComboBox(this);
for each(var category:Array in presetVoice.categolies) categoryList.addItem( category[ "name" ] );
categoryList.addEventListener(Event.SELECT, onCategorySelect);
voiceList = new ComboBox(this, 100, 0);
voiceList.setSize(160, 20);
voiceList.addEventListener(Event.SELECT, onVoiceSelect);
categoryList.selectedIndex = 2;//default
//
input = new Text(this, 0, stage.stageHeight - 40);
input.setSize(240, 40);
var button:PushButton = new PushButton(this, 240, stage.stageHeight - 40, "Play", onButtonClick);
button.setSize(240, 40);
input.text = "%t0,1,1 d2f+2e2>a1&a4&a16r4<d2&d16e2f+2d1&d4.&d16r4f+2d2e2r16>a1&a8.r4r16a2&a16<e2f+2d1&d4";
}
private function onCategorySelect(e:Event):void
{
voiceList.removeAll();
var voices:Array = presetVoice[ categoryList.selectedItem ];
var length:uint = presetVoice[ categoryList.selectedItem ].length;
for(var i:int = 0; i < length; ++i) voiceList.addItem( voices[i].name )
voiceList.selectedIndex = 0;
}
private function onVoiceSelect(e:Event):void
{
voice = presetVoice[ categoryList.selectedItem ][ voiceList.selectedIndex ];
}
private function onButtonClick(e:Event=null):void
{
var mml:String = input.text;
var melody:SiONData = driver.compile(mml);
driver.play();
driver.sequenceOn(melody, voice, 0, 0, 2);
driver.addEventListener(SiONTrackEvent.NOTE_ON_FRAME, onNoteOn);
}
private function onNoteOn(e:SiONTrackEvent):void
{
if(e.eventTriggerID == 0) {
colorHSV.h += 6;
colorHSV.h %= 360;
var circle:ColorCircle = new ColorCircle();
circle.x = (e.note - 60 + 12) * 20 + 10;
circle.y = 200;
this.addChild(circle);
circle.draw(50, colorHSV.value);
circles.push(circle);
}
}
private function drawGrid(w:int, h:int):void
{
var colors:Array = [0xffffff,0xcccccc,0xffffff,0xcccccc,0xffffff,0xffffff,0xcccccc,0xffffff,0xcccccc,0xffffff,0xcccccc,0xffffff];
var gridSize:int = 20;
grid.graphics.lineStyle(1, 0x666666);
var len:int = w/gridSize;
for(var i:int=0; i<len; ++i) {
grid.graphics.moveTo(gridSize * i, 0);
grid.graphics.beginFill(colors[i%12]);
grid.graphics.drawRect(gridSize * i, 0, gridSize * i, h);
grid.graphics.endFill();
}
}
}
}
import flash.display.Sprite;
class ColorCircle extends Sprite {
private var _isDead:Boolean;
private var _radius:Number;
private var _color:uint;
public function ColorCircle() {
}
public function draw(radius:Number, color:uint):void
{
_radius = radius;
_color = color;
this.graphics.clear()
this.graphics.beginFill(_color);
this.graphics.drawCircle(0, 0, _radius);
this.graphics.endFill();
}
public function fadeOut():void
{
if(_radius < 2) {
_isDead = true;
}
else {
_radius -= 2;
this.draw(_radius, _color);
}
}
public function get isDead():Boolean {
return _isDead;
}
public function get color():uint {
return _color;
}
public function get radius():Number {
return _radius;
}
}
/**
* a part of RobertPenner's AS3Signals
* http://github.com/robertpenner/as3-signals
*/
interface IDeluxeSignal {
function get valueClasses():Array;
function get numListeners():uint;
function add(listener:Function, priority:int = 0):Function;
function addOnce(listener:Function, priority:int = 0):Function;
function remove(listener:Function):Function;
}
import flash.events.Event;
import flash.events.IEventDispatcher;
interface INativeDispatcher {
function get eventType():String;
function get eventClass():Class;
function get target():IEventDispatcher;
function dispatch(event:Event):Boolean;
}
import flash.errors.IllegalOperationError;
import flash.events.Event;
import flash.events.IEventDispatcher;
/**
* The NativeSignal class provides a strongly-typed facade for an IEventDispatcher.
* A NativeSignal is essentially a mini-dispatcher locked to a specific event type and class.
* It can become part of an interface.
*/
class NativeSignal implements IDeluxeSignal, INativeDispatcher
{
protected var _target:IEventDispatcher;
protected var _eventType:String;
protected var _eventClass:Class;
protected var listenerBoxes:Array;
/**
* Creates a NativeSignal instance to dispatch events on behalf of a target object.
* @param target The object on whose behalf the signal is dispatching events.
* @param eventType The type of Event permitted to be dispatched from this signal. Corresponds to Event.type.
* @param eventClass An optional class reference that enables an event type check in dispatch(). Defaults to flash.events.Event if omitted.
*/
public function NativeSignal(target:IEventDispatcher, eventType:String, eventClass:Class = null)
{
_target = target;
_eventType = eventType;
_eventClass = eventClass || Event;
listenerBoxes = [];
}
public function get eventType():String { return _eventType; }
public function get eventClass():Class { return _eventClass; }
public function get valueClasses():Array { return [_eventClass]; }
public function get numListeners():uint { return listenerBoxes.length; }
public function get target():IEventDispatcher { return _target; }
public function set target(value:IEventDispatcher):void { _target = value; }
public function add(listener:Function, priority:int = 0):Function
{
registerListener(listener, false, priority);
return listener;
}
public function addOnce(listener:Function, priority:int = 0):Function
{
registerListener(listener, true, priority);
return listener;
}
public function remove(listener:Function):Function
{
var listenerIndex:int = indexOfListener(listener);
if (listenerIndex == -1) return listener;
var listenerBox:Object = listenerBoxes.splice(listenerIndex, 1)[0];
// For once listeners, execute is a wrapper function around the listener.
_target.removeEventListener(_eventType, listenerBox.execute);
return listener;
}
public function removeAll():void
{
for (var i:int = listenerBoxes.length; i--; )
{
remove(listenerBoxes[i].listener as Function);
}
}
public function dispatch(event:Event):Boolean
{
if (!(event is _eventClass))
throw new ArgumentError('Event object '+event+' is not an instance of '+_eventClass+'.');
if (event.type != _eventType)
throw new ArgumentError('Event object has incorrect type. Expected <'+_eventType+'> but was <'+event.type+'>.');
return _target.dispatchEvent(event);
}
protected function registerListener(listener:Function, once:Boolean = false, priority:int = 0):void
{
// function.length is the number of arguments.
if (listener.length != 1)
throw new ArgumentError('Listener for native event must declare exactly 1 argument.');
var prevListenerIndex:int = indexOfListener(listener);
if (prevListenerIndex >= 0)
{
// If the listener was previously added, definitely don't add it again.
// But throw an exception in some cases, as the error messages explain.
var prevlistenerBox:Object = listenerBoxes[prevListenerIndex];
if (prevlistenerBox.once && !once)
{
throw new IllegalOperationError('You cannot addOnce() then add() the same listener without removing the relationship first.');
}
else if (!prevlistenerBox.once && once)
{
throw new IllegalOperationError('You cannot add() then addOnce() the same listener without removing the relationship first.');
}
// Listener was already added, so do nothing.
return;
}
var listenerBox:Object = { listener:listener, once:once, execute:listener };
if (once)
{
var signal:NativeSignal = this;
// For once listeners, create a wrapper function to automatically remove the listener.
listenerBox.execute = function(event:Event):void
{
signal.remove(listener);
listener(event);
};
}
listenerBoxes[listenerBoxes.length] = listenerBox;
_target.addEventListener(_eventType, listenerBox.execute, false, priority);
}
protected function indexOfListener(listener:Function):int
{
for (var i:int = listenerBoxes.length; i--; )
{
if (listenerBoxes[i].listener == listener) return i;
}
return -1;
}
}