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; } } } } flash on 2010-3-7