SiON 88 Key Keyboard
...
@author tkinjo
/**
* Copyright tkinjo ( http://wonderfl.net/user/tkinjo )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/izi3
*/
package
{
import flash.display.*;
import flash.events.*;
import flash.media.Sound;
import org.si.sion.SiONDriver;
import org.si.sion.SiONVoice;
import org.si.sion.utils.SiONPresetVoice;
[SWF(width="465", height="465", backgroundColor="0xffffff", frameRate="60")]
/**
* ...
* @author tkinjo
*/
public class Main extends Sprite
{
private var driver:SiONDriver = new SiONDriver();
private var presetVoice:SiONPresetVoice = new SiONPresetVoice();
private var sineVoice:SiONVoice;
private var keyboard:MusicalKeyboard;
public function Main():void
{
keyboard = new MusicalKeyboard( 8, 40 );
addChild( keyboard );
keyboard.x = ( stage.stageWidth - keyboard.width ) / 2;
keyboard.y = ( stage.stageHeight - keyboard.height ) / 2;
keyboard.addEventListener(MusicalKeyEvent.PRESS, keybaordPressHandler);
//keyboard.addEventListener(MusicalKeyEvent.RELEASE, keybaordReleaseHandler);
sineVoice = presetVoice["sine"];
driver.play();
//stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function keybaordPressHandler( event:MusicalKeyEvent ):void {
var keyType:MusicalKeyType = event.keyType;
driver.noteOn( keyType.note, sineVoice );
}
/*
private function keybaordReleaseHandler( event:MusicalKeyEvent ):void {
var keyType:MusicalKeyType = event.keyType;
driver.noteOff( keyType.note );
}
private function mouseUpHandler( event:MouseEvent ):void {
for ( var i:uint = 0; i < 128; i++ )
driver.noteOff( i );
}
//*/
private function enterFrameHandler( event:Event ):void {
var pressedKeyNotes:Vector.<Boolean> = keyboard.pressedKeyNotes;
var pressedKeyNotesLength:int = pressedKeyNotes.length;
for ( var i:uint = 0; i < pressedKeyNotesLength; i++ )
if( !pressedKeyNotes[ i ] )
driver.noteOff( i );
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
class MusicalKey extends Sprite {
/**
* ...
* @eventType MusicalKeyEvent.PRESS
*/
[Event(name = "press", type = "MusicalKeyEvent")]
/**
* ...
* @eventType MusicalKeyEvent.RELEASE
*/
[Event(name = "release", type = "MusicalKeyEvent")]
private var _type:MusicalKeyType;
public function get type():MusicalKeyType { return _type; }
private var _width:Number = 0;
override public function set width(value:Number):void
{
_width = value;
paint();
}
override public function get width():Number { return _width; }
private var _height:Number = 0;
override public function set height(value:Number):void
{
_height = value;
paint();
}
override public function get height():Number { return _height; }
private var mouseOver:Boolean = false;
private var mouseDown:Boolean = false;
public function MusicalKey( type:MusicalKeyType, width:Number, height:Number ):void {
_type = type;
this.width = width;
this.height = height;
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function paint():void {
if ( !( width && height ) )
return;
graphics.clear();
graphics.lineStyle( 1 );
if ( mouseDown )
graphics.beginFill( 0xffcccc );
else if ( mouseOver )
graphics.beginFill( 0xccccff );
else if ( type.color == MusicalKeyType.COLOR_WHITE )
graphics.beginFill( 0xffffff );
else
graphics.beginFill( 0x666666 );
graphics.drawRect( 0, 0, width, height );
graphics.endFill();
}
private function mouseOverHandler( event:MouseEvent ):void {
if ( event.buttonDown )
mouseDown = true;
mouseOver = true;
paint();
if( event.buttonDown )
dispatchEvent( new MusicalKeyEvent( MusicalKeyEvent.PRESS, type ) );
}
private function mouseOutHandler( event:MouseEvent ):void {
mouseOver = false;
mouseDown = false;
paint();
if( event.buttonDown )
dispatchEvent( new MusicalKeyEvent( MusicalKeyEvent.RELEASE, type ) );
}
private function mouseDownHandler( event:MouseEvent ):void {
mouseDown = true;
paint();
dispatchEvent( new MusicalKeyEvent( MusicalKeyEvent.PRESS, type ) );
}
private function mouseUpHandler( event:MouseEvent ):void {
mouseDown = false;
paint();
dispatchEvent( new MusicalKeyEvent( MusicalKeyEvent.RELEASE, type ) );
}
}
class MusicalKeyEvent extends Event {
public static const PRESS:String = "press";
public static const RELEASE:String = "release";
private var _keyType:MusicalKeyType;
public function get keyType():MusicalKeyType { return _keyType; }
public function MusicalKeyEvent( type:String, keyType:MusicalKeyType, bubbles:Boolean = false, cancelable:Boolean = false ):void {
super( type, bubbles, cancelable );
_keyType = keyType;
}
}
class MusicalKeyboard extends Sprite {
/**
* ...
* @eventType MusicalKeyEvent.PRESS
*/
[Event(name = "press", type = "MusicalKeyEvent")]
/**
* ...
* @eventType MusicalKeyEvent.RELEASE
*/
[Event(name = "release", type = "MusicalKeyEvent")]
private var numKey:uint;
private var keyOffset:uint;
private var keyWidth:uint;
private var keyHeight:uint;
private function get numWhiteKey():uint {
var numWhiteKey:uint = 0;
for ( var i:uint = 0; i < numKey; i++ )
if ( MusicalKeyType.getKeyColor( ( i + keyOffset ) % 12 ) == MusicalKeyType.COLOR_WHITE )
numWhiteKey++;
return numWhiteKey;
}
private var _pressedKeyNotes:Vector.<Boolean> = new Vector.<Boolean>( 128 );
public function get pressedKeyNotes():Vector.<Boolean> { return _pressedKeyNotes; }
public function MusicalKeyboard( keyWidth:uint, keyHeight:uint, numKey:uint = 88, keyOffset:uint = 9 ):void
{
this.numKey = numKey;
this.keyOffset = keyOffset;
this.keyWidth = keyWidth;
if ( keyWidth % 2 )
keyWidth--;
this.keyHeight = keyHeight;
if ( keyHeight % 2 )
keyHeight--;
paint();
}
protected function paint():void {
graphics.lineStyle( 1 );
var keyOffsetX:uint = getKeyOffsetX( keyOffset );
var octaveNum:uint;
var scaleNum:uint;
var octaveX:Number
var i:uint;
var key:MusicalKey;
for ( i = 0; i < numKey; i++ ) {
scaleNum = ( i + keyOffset ) % 12;
if ( MusicalKeyType.getKeyColor( scaleNum ) != MusicalKeyType.COLOR_WHITE )
continue;
octaveNum = ( i + keyOffset ) / 12;
key = new MusicalKey( new MusicalKeyType( scaleNum, octaveNum ), keyWidth, keyHeight );
octaveX = octaveNum * keyWidth * 7;
key.x = octaveX + getWhiteKeyX( MusicalKeyType.getKeyColorNum( scaleNum ) ) - keyOffsetX;
addChild( key );
key.addEventListener(MusicalKeyEvent.PRESS, keyPressHandler);
key.addEventListener(MusicalKeyEvent.RELEASE, keyReleaseHandler);
}
for ( i = 0; i < numKey; i++ ) {
scaleNum = ( i + keyOffset ) % 12;
if ( MusicalKeyType.getKeyColor( scaleNum ) != MusicalKeyType.COLOR_BLACK )
continue;
octaveNum = ( i + keyOffset ) / 12;
key = new MusicalKey( new MusicalKeyType( scaleNum, octaveNum ), keyWidth, keyHeight / 2 );
octaveX = octaveNum * keyWidth * 7;
key.x = octaveX + getBlackKeyX( MusicalKeyType.getKeyColorNum( scaleNum ) ) - keyOffsetX;
addChild( key );
key.addEventListener(MusicalKeyEvent.PRESS, keyPressHandler);
key.addEventListener(MusicalKeyEvent.RELEASE, keyReleaseHandler);
}
}
private function getKeyOffsetX( offset:uint ):Number {
var keyColorNum:uint = MusicalKeyType.getKeyColorNum( offset );
return MusicalKeyType.getKeyColor( offset ) == MusicalKeyType.COLOR_WHITE ? getWhiteKeyX( keyColorNum ) : getBlackKeyX( keyColorNum );
}
protected function getWhiteKeyX( scaleNum:uint ):Number {
return keyWidth * scaleNum;
}
protected function getBlackKeyX( scaleNum:uint ):Number {
if( scaleNum <= 1 )
return keyWidth * scaleNum + keyWidth / 2;
return keyWidth * ( scaleNum + 1 ) + keyWidth / 2;
}
private function keyPressHandler( event:MusicalKeyEvent ):void {
pressedKeyNotes[ event.keyType.note ] = true;
dispatchEvent( new MusicalKeyEvent( event.type, event.keyType ) );
}
private function keyReleaseHandler( event:MusicalKeyEvent ):void {
pressedKeyNotes[ event.keyType.note ] = false;
dispatchEvent( new MusicalKeyEvent( event.type, event.keyType ) );
}
}
class MusicalKeyType extends Object {
public static const COLOR_WHITE:String = "white";
public static const COLOR_BLACK:String = "black";
public static const SCALE_C:String = "c";
public static const SCALE_D:String = "b";
public static const SCALE_E:String = "e";
public static const SCALE_F:String = "f";
public static const SCALE_G:String = "g";
public static const SCALE_A:String = "a";
public static const SCALE_B:String = "a";
private var _scale:String;
public function get scale():String { return _scale; }
private var _scaleNum:uint;
public function get scaleNum():uint { return _scaleNum; }
private var _color:String;
public function get color():String { return _color; }
private var _keyColorNum:uint;
public function get keyColorNum():uint { return _keyColorNum; }
private var _octave:int;
public function get octave():int { return _octave; }
public function get note():uint { return octave * 12 + 12 + scaleNum; }
public function MusicalKeyType( scaleNum:uint, octave:uint ):void {
_scaleNum = scaleNum;
_octave = octave;
switch( scaleNum ) {
case 0:
_color = COLOR_WHITE;
_scale = SCALE_C;
_keyColorNum = 0;
break;
case 1:
_color = COLOR_BLACK;
_scale = SCALE_C;
_keyColorNum = 0;
break;
case 2:
_color = COLOR_WHITE;
_scale = SCALE_D;
_keyColorNum = 1;
break;
case 3:
_color = COLOR_BLACK;
_scale = SCALE_D;
_keyColorNum = 1;
break;
case 4:
_color = COLOR_WHITE;
_scale = SCALE_E;
_keyColorNum = 2;
break;
case 5:
_color = COLOR_WHITE;
_scale = SCALE_F;
_keyColorNum = 3;
break;
case 6:
_color = COLOR_BLACK;
_scale = SCALE_F;
_keyColorNum = 2;
break;
case 7:
_color = COLOR_WHITE;
_scale = SCALE_G;
_keyColorNum = 4;
break;
case 8:
_color = COLOR_BLACK;
_scale = SCALE_G;
_keyColorNum = 3;
break;
case 9:
_color = COLOR_WHITE;
_scale = SCALE_A;
_keyColorNum = 5;
break;
case 10:
_color = COLOR_BLACK;
_scale = SCALE_A;
_keyColorNum = 4;
break;
case 11:
_color = COLOR_WHITE;
_scale = SCALE_B;
_keyColorNum = 6;
break;
}
}
public static function getKeyColor( scaleNum:uint ):String {
switch( scaleNum ) {
case 0:
case 2:
case 4:
case 5:
case 7:
case 9:
case 11:
return COLOR_WHITE;
}
return COLOR_BLACK;
}
public static function getKeyColorNum( scaleNum:uint ):uint {
switch( scaleNum ) {
case 0:
return 0;
case 1:
return 0;
case 2:
return 1;
case 3:
return 1;
case 4:
return 2;
case 5:
return 3;
case 6:
return 2;
case 7:
return 4;
case 8:
return 3;
case 9:
return 5;
case 10:
return 4;
case 11:
return 6;
}
return null;
}
}