flash on 2010-3-7
/**
* Copyright terra1119 ( http://wonderfl.net/user/terra1119 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/3l7R
*/
package {
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.KeyboardEvent
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.filters.BlurFilter;
[SWF(width="400", height="300", frameRate="30", backgroundColor="#000000")]
public class Main extends Sprite {
public static const SINE:String = "sine";
public static const SAW:String = "saw";
public static const TRIANGLE:String = "triangle";
public static const PULSE:String = "pulse";
public static const NOISE:String = "noise";
private var sound:Sound;
private var channel:SoundChannel;
private var frequency:Number;
private var keyboardTable:Array;
private var waveType:String;
private var volume:Number;
private var isKeyDown:Boolean=false;
private var blurObj:BlurFilter;
private var noteNumber:uint;
private var frequencyArray:Array=[];
private var selectedKey:uint;//現在の鍵盤番号を格納する変数
public function Main() {
stage.scaleMode = StageScaleMode.NO_SCALE;
init();
}
private function init():void {
//frequencyArray=create_fs_array();
initKeyboardTable();
waveType = SAW;
volume = 0.5;
sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA,waveGenerator);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
}
private function keyDownHandler(e:KeyboardEvent):void {
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
isKeyDown=true;
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
if(getNote(e.keyCode)){
frequency =noteNumber2frequency(noteNumber);
if(isKeyDown)channel = sound.play();
isKeyDown=false;
createBall();
}
//if(isKeyDown)channel = sound.play();
//isKeyDown=false;
//createBall();
};
private function keyUpHandler(e:KeyboardEvent):void {
isKeyDown=false;
stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
channel.stop();
}
private function getNote(num:int):Boolean {
switch(num){//numの値で評価する
case 65://キーコードが65(A)の時
noteNumber=60;//音階をド(C4 MIDIノートナンバー=60)に設定する
selectedKey=0;//現在の鍵盤番号を0にする
break;
case 87://キーコードが87(W)の時
noteNumber=61;//音階をド#(C#4 MIDIノートナンバー=61)に設定する
selectedKey=1;//現在の鍵盤番号を1にする
break;
case 83://キーコードが83(S)の時
noteNumber=62;//音階をレ(D4 MIDIノートナンバー=62)に設定する
selectedKey=2;//現在の鍵盤番号を2にする
break;
case 69://キーコードが69(E)の時
noteNumber=63;//音階をレ#(D#4 MIDIノートナンバー=63)に設定する
selectedKey=3;//現在の鍵盤番号を3にする
break;
case 68://キーコードが68(D)の時
noteNumber=64;//音階をミ(E4 MIDIノートナンバー=64)に設定する
selectedKey=4;//現在の鍵盤番号を4にする
break;
case 70://キーコードが70(F)の時
noteNumber=65;//音階をファ(F4 MIDIノートナンバー=65)に設定する
selectedKey=5;//現在の鍵盤番号を5にする
break;
case 84://キーコードが84(T)の時
noteNumber=66;//音階をファ#(F#4 MIDIノートナンバー=66)に設定する
selectedKey=6;//現在の鍵盤番号を6にする
break;
case 71://キーコードが71(G)の時
noteNumber=67;//音階をソ(G4 MIDIノートナンバー=67)に設定する
selectedKey=7;//現在の鍵盤番号を7にする
break;
case 89://キーコードが89(Y)の時
noteNumber=68;//音階をソ#(G#4 MIDIノートナンバー=68)に設定する
selectedKey=8;//現在の鍵盤番号を8にする
break;
case 72://キーコードが72(H)の時
noteNumber=69;//音階をラ(A4 MIDIノートナンバー=69)に設定する
selectedKey=9;//現在の鍵盤番号を9にする
break;
case 85://キーコードが85(U)の時
noteNumber=70;//音階をラ#(A#4 MIDIノートナンバー=70)に設定する
selectedKey=10;//現在の鍵盤番号を10にする
break;
case 74://キーコードが74(J)の時
noteNumber=71;//音階をシ(B4 MIDIノートナンバー=71)に設定する
selectedKey=11;//現在の鍵盤番号を11にする
break;
case 75://キーコードが75(K)の時
noteNumber=72;//音階をド(C5 MIDIノートナンバー=72)に設定する
selectedKey=12;//現在の鍵盤番号を12にする
break;
default://それ以外の場合
return false;//falseを返す
}
return true;//trueを返す
}
private function initKeyboardTable():void {
keyboardTable =
[
[0, "F"],
[0, "F#"],
[0, "G"],
[0, "G#"],
[1, "A"],
[1, "A#"],
[1, "B"],
[1, "C"],
[1, "C#"],
[1, "D"],
[1, "D#"],
[1, "E"],
[1, "F"],
[1, "F#"],
[1, "G"],
[1, "G#"],
[2, "A"],
[2, "A#"],
[2, "B"],
[2, "C"],
[2, "C#"],
[2, "D"],
[2, "D#"],
[2, "E"]
]
}
private function setFreqency(keyNum:uint):void {
var keyStep:uint = keyNum % 12;
keyStep = keyStep < 5 ? keyStep + 7 : keyStep - 5;
var octave:Number = 110.5* Math.pow(2, keyboardTable[keyNum - 1][0]);
//frequency = octave * Math.pow(2, keyStep / 12);
frequency =noteNumber2frequency(keyNum);
}
private function noteNumber2frequency(v:uint):Number {
if (v > 127)v = 127;
return 440 * Math.pow(2, (v - 69) / 12);
}
private function waveGenerator(e:SampleDataEvent):void {
var sample:Number;
var f0:Number = frequency / 44100;
var f1:Number = 44100 / frequency;
var PI2:Number = 2 * Math.PI;
for ( var c:int=0; c < 2048; c++ ) {
switch(waveType) {
//サイン波
case SINE:
sample = Math.sin(PI2 * f0 * Number(c + e.position));
break;
//矩形波
case PULSE:
sample = (Math.sin(PI2 * f0 * Number(c + e.position)) < 0) ? 1 : -1;
break;
//のこぎり波
case SAW:
sample = 2 * f0 * ((c + e.position) % f1) - 1;
break;
//三角波
case TRIANGLE:
sample = (Math.sin(PI2 * f0 * Number(c + e.position)) < 0) ?
(4 * f0 * ((c + e.position) % (f1 / 2)) - 1) :
(-4 * f0 * ((c + e.position) % (f1 / 2)) + 1);
break;
//ホワイトノイズ
case NOISE:
sample = Math.random() * 2 - 1;
break;
default: break;
}
//音量調節
sample *= volume;
//範囲外チェック
sample = (sample < -1) ? -1 : sample;
sample = (sample > 1) ? 1 : sample;
e.data.writeFloat(sample);
e.data.writeFloat(sample);
}
}
private function createBall():void {
blurObj=new BlurFilter();
blurObj.blurX=2;
blurObj.blurY=2;
var ball:Sprite=new Sprite();
addChild(ball);
ball.graphics.beginFill(Math.random()*0xFFFFFF);
ball.graphics.drawCircle(0,0,frequency/10);
ball.graphics.endFill();
ball.blendMode="add";
ball.filters=[blurObj];
ball.x=Math.random()*400;
ball.y=Math.random()*300;
ball.addEventListener(Event.ENTER_FRAME,efHandler);
}
private function efHandler(e:Event):void {
var targetSprite:Sprite=e.target as Sprite;
targetSprite.alpha-=0.05;
blurObj.blurX+=2;
blurObj.blurY+=2;
targetSprite.filters=[blurObj];
if (targetSprite.alpha<0) {
targetSprite.removeEventListener(Event.ENTER_FRAME,efHandler);
removeChild(targetSprite);
targetSprite=null;
}
}
}
}