あの楽器っぽいスクリプト
あの楽器っぽいスクリプト。
未熟ながら初投稿。波形計算方法とかパクリまくりました。
一応ドラッグ中にマウスを動かすことで音が変わります。
リバーブとかディレイとかつけたいなぁ・・・。
鍵盤っぽくしたいと方法を模索中。コードが汚いのが悩みの種です。
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
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);
}
}
}
}