// forked from Hiiragi's forked from: あの楽器っぽいスクリプト(鍵盤にしてみました) package { /* * あの楽器っぽいスクリプトのセルフフォーク * * 鍵盤にしてみましたが、タッチパネルならではのシームレスな音程のつなぎ方ができなくて落ち込み中。 * 多分「あの楽器」的には前のバージョンのほうがよかったんだろうなぁ。 * * 白鍵黒鍵関係なくX軸でシームレスにすることはできますけど、EとF、BとCの半音間がどう計算すればいいのやら。 * 強引にやればできなくもないんでしょうけど・・・。もうちょっとあがいてみます。 * * あと、writeFloatの説明ありがとうございます。 * 試しに片方の数値を0にしてみたら、もう片方からしか聞こえてきませんでした。 * 必ず2つ書いていないとだめなんですね。そこらへんの仕組みがわからない・・・。 * そもそもByteArrayすらわからない・・・。 * * あと、知人からエフェクトがワンパターンなのを指摘されたんで、そこもどうしようか悩み中。 * * いろいろ使ってないメンバとかありますが、気にしないでください。試行錯誤の名残です。 */ import flash.display.MovieClip; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.events.SampleDataEvent; import flash.media.Sound; import flash.media.SoundChannel; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; [SWF(width="465", height="465", frameRate="30", backgroundColor="#ffffff")] public class Main extends Sprite { //ステージ上描画関連 private var _baseSp:Sprite; private var _baseSpGrid:Sprite; private var _blackKeyArray:Array = new Array(); private var tF:TextField; private var button:Sprite; private var buttonText:TextField; private var _dragFlag:Boolean; //サウンドオブジェクト関連 private var _soundCh:SoundChannel; private var _soundObj:Sound; //音関連 private var _phase:Number = 0; private var _buffSize:Number = 4096 private var _targetFreq:Number; private var _freq:Number = 0; private var _baseFreq:Number = 440; private const PI2:Number = Math.PI * 2; private var _mouseX:Number; private var _mouseY:Number; private var keyArray:Array = [130.8,146.8,164.8,174.6,196.0,220.0,246.9,261.6, 293.7, 329.6, 349.2, 392.0, 440, 493.9,523.3]; private var _keyBaseFreq:uint; private var _movCnt:uint; //図形を出すためのカウント変数 private const POWER:Number = Math.pow(2, 1 / 13); //X軸で音階を変えるのに必要 private var num:uint = 24; //音階の数 private var _flag:int; //現在の図形の種類 private var _waveTone:uint = 0; //現在の音の種類 public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); //ステージ上の描画 _baseSp = new Sprite(); _baseSp.x = _baseSp.y = 0; _baseSp.graphics.beginFill(0x000000, 1); _baseSp.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); _baseSp.graphics.endFill(); addChild(_baseSp); //鍵盤描画(縦線) _baseSp.graphics.lineStyle(0.5, 0x222222); for (var i:uint = 0; i <= 16; i++) { _baseSp.graphics.moveTo(i * 31, 0); _baseSp.graphics.lineTo(i * 31, 465); } //鍵盤描画(黒鍵) for (var j:uint = 0; j < 4; j++) { _blackKeyArray[j] = new Array(); drawBlackKey(21, j * 116, 138.6,_blackKeyArray[j]); drawBlackKey(52, j * 116, 155.5,_blackKeyArray[j]); drawBlackKey(114, j * 116, 185,_blackKeyArray[j]); drawBlackKey(145, j * 116, 207.7,_blackKeyArray[j]); drawBlackKey(176, j * 116, 233.1,_blackKeyArray[j]); drawBlackKey(238, j * 116, 277.2,_blackKeyArray[j]); drawBlackKey(269, j * 116, 311.2,_blackKeyArray[j]); drawBlackKey(331, j * 116, 370,_blackKeyArray[j]); drawBlackKey(362, j * 116, 415.3,_blackKeyArray[j]); drawBlackKey(393, j * 116, 466.2,_blackKeyArray[j]); } //鍵盤描画(横線) _baseSpGrid = new Sprite(); _baseSpGrid.graphics.lineStyle(0.5, 0x333333); _baseSpGrid.graphics.moveTo(0, 0); _baseSpGrid.graphics.lineTo(465, 0); _baseSpGrid.graphics.moveTo(0, 116); _baseSpGrid.graphics.lineTo(465, 116); _baseSpGrid.graphics.moveTo(0, 232); _baseSpGrid.graphics.lineTo(465, 232); _baseSpGrid.graphics.moveTo(0, 348); _baseSpGrid.graphics.lineTo(465, 348); _baseSpGrid.graphics.moveTo(0, 465); _baseSpGrid.graphics.lineTo(465, 465); addChild(_baseSpGrid); //波形情報表示関連 tF = new TextField(); tF.autoSize = TextFieldAutoSize.LEFT; tF.defaultTextFormat = new TextFormat(null, 40, 0xFFFFFF); tF.text = "SineWave"; _baseSp.addChild(tF); button = new Sprite(); button.buttonMode = true; button.mouseChildren = false; button.graphics.beginFill(0x6666FF); button.graphics.drawRoundRect(0, 0, 100, 30,10); button.graphics.endFill(); button.x = 10; button.y = 50; addChild(button); buttonText = new TextField(); buttonText.autoSize = TextFieldAutoSize.CENTER; buttonText.defaultTextFormat = new TextFormat(null, 20, 0xFFFFFF); buttonText.text = "Change"; buttonText.selectable = false; button.addChild(buttonText); button.addEventListener(MouseEvent.CLICK, onButtonClick); //サウンド関連 _soundCh = new SoundChannel(); _soundObj = new Sound(); //いろいろ _dragFlag = false; _baseSp.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); _baseSp.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler); _baseSp.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); _baseSp.mouseChildren = false; _mouseX = stage.mouseX; _mouseY = stage.mouseY; } //Draw系Function private function drawBlackKey(tx:Number,ty:Number,hz:Number,arr:Array):void { var sp:Sprite = new Sprite(); sp.graphics.beginFill(0x000000); sp.graphics.lineStyle(0.5,0x222222); sp.graphics.moveTo(0, 0); sp.graphics.lineTo(20, 0); sp.graphics.lineTo(20, 70); sp.graphics.lineTo(0, 70); sp.graphics.lineTo(0, 0); sp.graphics.endFill(); sp.name = hz.toString(); sp.x = tx; sp.y = ty; _baseSp.addChild(sp); arr.push(sp); } private function onButtonClick(e:MouseEvent = null):void { _waveTone += 1; if (_waveTone > 5) _waveTone = 0; switch (_waveTone) { case 0: tF.text = "SineWave"; break; case 1: tF.text = "SquareWave(50:50)?"; break; case 2: tF.text = "SquareWave(25:75)?"; break; case 3: tF.text = "TriangleWave"; break; case 4: tF.text = "Saw Wave"; break; case 5: tF.text = "Noise"; break; } } private function drawBitmap(flagNum:int,e:MouseEvent):void { var drawSp:MovieClip = new MovieClip(); if (flagNum == -1) _flag = Math.floor(Math.random() * 5); else _flag = flagNum; drawSp.graphics.beginFill(0x66FF66); switch (_flag) { case 0: drawSp.graphics.drawCircle( 0, 0, 50); drawSp.graphics.drawCircle( 0, 0, 47.5); break; case 1: drawStar(drawSp,0, 0, 50); drawStar(drawSp,0, 0, 45); break; case 2: drawSp.graphics.drawRect(-50,-50,100,100); drawSp.graphics.drawRect( -47.5, -47.5, 95, 95); break; case 3: drawLineBmp(); break; case 4: drawTriangle(drawSp); } drawSp.graphics.endFill(); drawSp.x = e.stageX; drawSp.y = e.stageY; drawSp.rotation = Math.random() * 360; _baseSp.addChild(drawSp); drawSp.addEventListener(Event.ENTER_FRAME, bmpFadeOut); } private function drawLineBmp():void { var drawLineSp:MovieClip = new MovieClip(); drawLineSp.x = _mouseX; drawLineSp.y = _mouseY; drawLineSp.graphics.lineStyle(Math.random() * 30 + 5, 0x66FF66); drawLineSp.graphics.moveTo(-657, 0); drawLineSp.graphics.lineTo(657, 0); drawLineSp.rotation = Math.random() * 360; _baseSp.addChild(drawLineSp); drawLineSp.addEventListener(Event.ENTER_FRAME, bmpFadeOutNoRotation); } private function drawTriangle(drawSp:Sprite):void { drawSp.graphics.beginFill(0x66FF66); drawSp.graphics.moveTo(0, -43.4); drawSp.graphics.lineTo(50, 43.4); drawSp.graphics.lineTo(-50, 43.4); drawSp.graphics.lineTo(0, -43); drawSp.graphics.moveTo(0, -39.05); drawSp.graphics.lineTo(45, 41); drawSp.graphics.lineTo(-45, 41); drawSp.graphics.lineTo(0, -39.05); } private function drawStar(sp:Sprite,drawX:Number = 0,drawY:Number = 0,drawScale:Number = 50):void { var scale:Number = drawScale / 50; sp.graphics.lineStyle(0.5,0x66FF66,0.5); sp.graphics.moveTo(0.3*scale , -47.65*scale); sp.graphics.lineTo(12.5*scale, -12.2*scale); sp.graphics.lineTo(50*scale, -10.95*scale); sp.graphics.lineTo(20.05*scale, 11.6*scale); sp.graphics.lineTo(30.45*scale, 47.65*scale); sp.graphics.lineTo( -0.3*scale , 26.15*scale); sp.graphics.lineTo( -31.35*scale , 47.15*scale); sp.graphics.lineTo( -20.4*scale , 11.3*scale); sp.graphics.lineTo(-50*scale, -11.75*scale); sp.graphics.lineTo( -12.45*scale , -12.4*scale); sp.graphics.lineTo(0.3*scale, -47.65*scale); } private function bmpFadeOutNoRotation(e:Event):void { var mc:MovieClip = e.target as MovieClip; mc.alpha -= 0.08; if (mc.alpha <= 0) { mc.removeEventListener(Event.ENTER_FRAME, bmpFadeOutNoRotation); _baseSp.removeChild(mc); } } private function bmpFadeOut(e:Event):void { var mc:MovieClip = e.target as MovieClip; mc.alpha -= 0.08; mc.rotation += 10; mc.scaleX = mc.scaleY += 0.4; if (mc.alpha <= 0) { mc.removeEventListener(Event.ENTER_FRAME, bmpFadeOut); _baseSp.removeChild(mc); } } //Intaractive系Function private function mouseDownHandler(e:MouseEvent):void { _dragFlag = true; _mouseX = stage.mouseX; _mouseY = stage.mouseY; changeFreqency(); _soundObj.addEventListener(SampleDataEvent.SAMPLE_DATA, toneGenerate); _soundCh = _soundObj.play(); drawBitmap( -1, e); stage.addEventListener(Event.ENTER_FRAME, changeFreqency); } private function mouseUpHandler(e:MouseEvent):void { _dragFlag = false; _movCnt = 0; _soundObj.removeEventListener(SampleDataEvent.SAMPLE_DATA, toneGenerate); _soundCh.stop(); _flag = -1; stage.removeEventListener(Event.ENTER_FRAME, changeFreqency); } private function mouseMoveHandler(e:MouseEvent):void { if (_dragFlag) { _movCnt++; if (_movCnt >= 20) { _movCnt = 0; //drawLine(); drawBitmap(_flag,e); } //changeFreqency(); } } //sound系Function private function changeFreqency(e:Event = null):void { _mouseX = stage.mouseX; _mouseY = stage.mouseY; if (_mouseX < 0) _mouseX = 0; else if (_mouseX > 465) _mouseX = 465; if (_mouseY < 0) _mouseY = 0; else if (_mouseY > 465) _mouseY = 465; var position:uint = Math.floor(stage.mouseX / 31); var centerPoint:Number = 31 * position + 16; _keyBaseFreq = 0; var posY:uint = Math.floor(_mouseY / 116); _blackKeyArray[posY].forEach(blackKeyCheck); if (_keyBaseFreq == 0) { _keyBaseFreq = keyArray[position]; } if (_mouseY < 116) { _targetFreq = _keyBaseFreq * 4; } else if (_mouseY < 232) { _targetFreq = _keyBaseFreq * 2; } else if (_mouseY < 348) { _targetFreq = _keyBaseFreq; } else { _targetFreq = _keyBaseFreq / 2; } _freq = _targetFreq; //_freq += (_targetFreq - _freq) / 10; } private function blackKeyCheck(element:*,i:int,arr:Array):void { if (element.hitTestPoint(_mouseX, _mouseY, true)) { _keyBaseFreq = Number(element.name); } } private function toneGenerate(e:SampleDataEvent):void { for (var i:int = 0; i < 2048; ++i) { var smpl:Number; var w:Number = PI2 * _freq / 44100; _phase += w; if (_phase > PI2) { _phase -= PI2; } switch (_waveTone) { case 0: smpl = Math.sin(_phase); break; case 1: smpl = (_phase < Math.PI) ? 1 : -1; break; case 2: smpl = (Math.sin(_phase) > 0.5) ? 1 : -1; break; case 3: smpl = (_phase < Math.PI) ? -2 / Math.PI * _phase + 1 : 2 / Math.PI * _phase - 3; break; case 4: smpl = - _phase / Math.PI + 1; break; case 5: smpl = Math.random() * 2 - 1; break; } if (smpl >= 1) smpl = 1; else if (smpl <= -1) smpl = -1; e.data.writeFloat(smpl); e.data.writeFloat(smpl); } } } } forked from: forked from: あの楽器っぽいスクリプト(鍵盤にしてみました)