In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: あの楽器っぽいスクリプト(鍵盤にしてみました)

あの楽器っぽいスクリプトのセルフフォーク

鍵盤にしてみましたが、タッチパネルならではのシームレスな音程のつなぎ方ができなくて落ち込み中。
多分「あの楽器」的には前のバージョンのほうがよかったんだろうなぁ。

白鍵黒鍵関係なくX軸でシームレスにすることはできますけど、EとF、BとCの半音間がどう計算すればいいのやら。
強引にやればできなくもないんでしょうけど・・・。もうちょっとあがいてみます。

あと、writeFloatの説明ありがとうございます。
試しに片方の数値を0にしてみたら、もう片方からしか聞こえてきませんでした。
必ず2つ書いていないとだめなんですね。そこらへんの仕組みがわからない・・・。
そもそもByteArrayすらわからない・・・。

あと、知人からエフェクトがワンパターンなのを指摘されたんで、そこもどうしようか悩み中。

いろいろ使ってないメンバとかありますが、気にしないでください。試行錯誤の名残です。
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);
            }
		}
		

		
	}
	
}