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

あの楽器っぽいスクリプト

あの楽器っぽいスクリプト。 
未熟ながら初投稿。波形計算方法とかパクリまくりました。 
一応ドラッグ中にマウスを動かすことで音が変わります。 

リバーブとかディレイとかつけたいなぁ・・・。 
鍵盤っぽくしたいと方法を模索中。コードが汚いのが悩みの種です。 

FlashDevelopで作ってるときは、発音の遅れはあんまりなかったのですが、なんか遅いっぽいですね。 
なのでゆっくりカーソルをうごかしてみてください。 

ところで、なんで2回writeFloatしてるの?(汗 

パクリ元 
http://www.kuma-de.com/blog/?cat=16 
http://www.adobe.com/jp/devnet/flash/articles/flp10_sound.html 
http://weblogs.macromedia.com/akamijo/archives/2008/08/var_mysoundsoun.html
Get Adobe Flash player
by Hiiragi 22 Apr 2009
package 
{
	// あの楽器っぽいスクリプト。 
	// 未熟ながら初投稿。波形計算方法とかパクリまくりました。 
	// 一応ドラッグ中にマウスを動かすことで音が変わります。 
	// 
	// リバーブとかディレイとかつけたいなぁ・・・。 
	// 鍵盤っぽくしたいと方法を模索中。コードが汚いのが悩みの種です。 
	// 
	// FlashDevelopで作ってるときは、発音の遅れはあんまりなかったのですが、なんか遅いっぽいですね。 
	// なのでゆっくりカーソルをうごかしてみてください。 
	// 
	// ところで、なんで2回writeFloatしてるの?(汗 
	//
	//パクリ元 
	//http://www.kuma-de.com/blog/?cat=16 
	//http://www.adobe.com/jp/devnet/flash/articles/flp10_sound.html 
	//http://weblogs.macromedia.com/akamijo/archives/2008/08/var_mysoundsoun.html 
 
	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 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 _freq:Number = 440;
		private var _baseFreq:Number = 440;
		
        private const PI2:Number = Math.PI * 2;

		private var _mouseX:Number;
		private var _mouseY:Number;
		
		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);
			
			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);
			
			_baseSp.graphics.lineStyle(0.5, 0x222222);
			_baseSp.graphics.moveTo(0, 116);
			_baseSp.graphics.lineTo(465, 116);
			_baseSp.graphics.moveTo(0, 232);
			_baseSp.graphics.lineTo(465, 232);
			_baseSp.graphics.moveTo(0, 348);
			_baseSp.graphics.lineTo(465, 348);

			
			
			//サウンド関連
			_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;
		}
		
		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 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);
		}
		
		private function drawBitmap(flagNum:int,e:MouseEvent):void
		{
			var drawSp:MovieClip = new MovieClip();
			
			if (flagNum == -1) _flag = Math.floor(Math.random() * 4);
			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;
			}
			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 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 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 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);
				
			}
		}
		
		
		private function mouseUpHandler(e:MouseEvent):void 
		{
			_dragFlag = false;
			_movCnt = 0;
			_soundObj.removeEventListener(SampleDataEvent.SAMPLE_DATA, toneGenerate);
			_soundCh.stop();
			_flag = -1;
		}
		
		private function mouseMoveHandler(e:MouseEvent):void 
		{
			if (_dragFlag) {
				_movCnt++;
				if (_movCnt >= 20) {
					_movCnt = 0;
					//drawLine();
					drawBitmap(_flag,e);
				}
				changeFreqency();
			}
		}
		
		private function changeFreqency():void
		{
			_mouseX = stage.mouseX;
			_mouseY = stage.mouseY;
			
			if (_mouseY < 116) {
				_baseFreq = 1780;
			} else if (_mouseY < 232) {
				_baseFreq = 880;
			} else if (_mouseY < 348) {
				_baseFreq = 440;
			} else {
				_baseFreq = 220;
			}

			var scale:Number = (_mouseX - stage.stageWidth/num*16) / num;
			var scaleInt:Number = Math.pow(POWER, scale);
			_freq = _baseFreq * scaleInt;
			
		}
		
		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);
            }
		}
		

		
	}
	
}