forked from: Sound Font
...
* @author mattodesign
*
* 音素材は友人にもらいました。
* http://www.myspace.com/vancouvered
*
/**
* Copyright akisute ( http://wonderfl.net/user/akisute )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eJW5
*/
// forked from mattodesign's Sound Font
/**
* ...
* @author mattodesign
*
* 音素材は友人にもらいました。
* http://www.myspace.com/vancouvered
*
*/
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.*;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.text.*;
import flash.media.*;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.system.Security;
//import com.flashdynamix.utils.SWFProfiler;
[SWF(backgroundColor = 0x000000, width = "465", height = "465", frameRate = 60)]
public class SoundFont extends Sprite
{
private var _bmd:BitmapData;
private var _tf:TextField;
private var _btn:Sprite;
private var _canvas:BitmapData;
private var _pt:Point;
private var _filter:GlowFilter;
private var _outputSound:Sound;
private var _cannel:SoundChannel;
private var _sourceSound:Sound;
private var _particleArray:Array;
private const STAGE_WIDTH:int = stage.stageWidth;
private const STAGE_HEIGHT:int = stage.stageHeight;
private const COLOR_TRANSFORM:ColorTransform = new ColorTransform(1, 1, 1, 0.45, 0, 0, 0, 0);
//========================================================================
// コンストラクタ
//========================================================================
public function SoundFont():void
{
// プロファイラの表示
//SWFProfiler.init(stage, this);
// 初期化
init();
// テキストフィールドを配置
setText();
// ボタンを配置
setBtn();
}
//========================================================================
// 初期化処理
//========================================================================
private function init():void
{
// 描画用のビットマップデータを作成
_canvas = new BitmapData(STAGE_WIDTH, STAGE_HEIGHT, true, 0x00FFFFFF);
_pt = new Point(0, 0);
_filter = new GlowFilter(0xFFFFFF, 0.8, 10, 10, 1, BitmapFilterQuality.MEDIUM, false, false);
_canvas.applyFilter(_canvas, _canvas.rect, _pt, _filter);
addChild(new Bitmap(_canvas));
// 一時格納用のビットマップデータを作成
_bmd = new BitmapData(STAGE_WIDTH, STAGE_HEIGHT, false, 0x000000);
// 音を読み込み
// ※crossdomain.xmlなしでも動くかテスト、SoundLoaderContext(false)を使う
//Security.loadPolicyFile("http://mattodesign.com/crossdomain.xml");
_sourceSound = new Sound();
var context:SoundLoaderContext = new SoundLoaderContext(1000, false);
_sourceSound.load(new URLRequest("http://sites.google.com/site/akisutesama/files/guitar.mp3?attredirects=0&d=1"),context);
_cannel = new SoundChannel();
_cannel = _sourceSound.play(0,100);
}
//========================================================================
// テキストフィールドをステージに生成
// 文字数が多すぎると(多分)ステージサイズの関係でエラーとなります
//========================================================================
private function setText():void
{
_tf = new TextField();
_tf.border = true;
_tf.borderColor = 0x00AAFF;
_tf.background = true;
_tf.backgroundColor = 0x2D2D2D;
_tf.alpha = 0.5;
_tf.text = "Wonderfl";
_tf.width = 240;
_tf.height = 22;
_tf.x = 90;
_tf.y = STAGE_HEIGHT - 30;
_tf.type = TextFieldType.INPUT;
_tf.setTextFormat(new TextFormat("_sans", 15, 0xFFFFFF));
addChild(_tf);
// フォーカス時にテキストを消すイベント
_tf.addEventListener(MouseEvent.CLICK, onFocus);
}
//========================================================================
// テキストフィールドへのフォーカス時にテキストを消す
//========================================================================
private function onFocus(e:MouseEvent):void
{
e.target.text = "";
_bmd.fillRect(_bmd.rect, 0x000000);
_canvas.fillRect(_canvas.rect, 0x000000);
}
//========================================================================
// ボタン作成
//========================================================================
private function setBtn():void
{
_btn = new Sprite();
_btn.graphics.beginFill(0x00AAFF);
_btn.graphics.drawRect(0, 0, 30, _tf.height);
_btn.graphics.endFill();
_btn.x = _tf.x + _tf.width + 10;
_btn.y = _tf.y;
addChild(_btn);
var tf:TextField = new TextField();
tf.text = "OK";
tf.selectable = false;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.x = _btn.width / 2 - tf.width / 2;
tf.y = _btn.height / 2 - tf.height / 2;
tf.setTextFormat(new TextFormat("_sans", null, 0xFFFFFF, true));
_btn.addChild(tf);
_btn.buttonMode = true;
_btn.mouseChildren = false;
// ボタンを押すとテキストをビットマップ化
_btn.addEventListener(MouseEvent.CLICK, onClickToBmp);
}
//========================================================================
// ビットマップへの変換
//========================================================================
private function onClickToBmp(e:MouseEvent):void
{
// テキストが未入力の場合は"文字を入力してください"を表示
if (_tf.length == 0)
{
_tf.text = "Wonderfl";
}
// 入力したテキストをビットマップ変換用のテキストフィールドに入れる
var tf:TextField = new TextField();
tf.text = _tf.text;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.setTextFormat(new TextFormat("_sans", 10, 0xFFFFFF));
// 入力したテキストを一時格納用ビットマップデータにdraw
var matScale:Number = 50 / tf.length;
var mat:Matrix = new Matrix(matScale, 0, 0, matScale, (STAGE_WIDTH - tf.width * matScale) >> 1, (STAGE_HEIGHT - tf.height * matScale) >> 1);
_bmd.draw(tf, mat);
// ビットマップの各ピクセルの色を走査
_particleArray = new Array();
var margin:int = 2;
for (var i:int = 0; i < _canvas.width; i = i + margin)
{
for (var j:int = 0; j < _canvas.height; j = j + margin)
{
if (_bmd.getPixel(i, j) != 0x000000)
{
var p:Particle = new Particle();
p.x = i;
p.y = j;
p.c = 0xFF00AAFF;
_particleArray.push(p);
}
}
}
// タイマーイベントで音の波形を取得するループ処理
var timer:Timer = new Timer(1);
timer.addEventListener(TimerEvent.TIMER, loop);
timer.start();
}
//========================================================================
// ループ処理
//========================================================================
private function loop(e:TimerEvent):void
{
const PLOT_HEIGHT:int = STAGE_HEIGHT/2;
const CHANNEL_LENGTH:int = 256;
const BUFFER_LENGHT:Number = 4096;
var alpha:Number = 0.1;
var bytes:ByteArray = new ByteArray();
var xrf:Number;
var yrf:Number;
var n:Number = 0;
var p:Particle;
var setX:Number;
var setY:Number;
// 波形データを取得
SoundMixer.computeSpectrum(bytes, false, 0);
// 波形データをパーティクルの動きに変換
_canvas.lock();
_canvas.colorTransform(_canvas.rect, COLOR_TRANSFORM);
_canvas.applyFilter(_canvas, _canvas.rect, _pt, _filter);
for (var i:int = 0; i < CHANNEL_LENGTH; i++)
{
xrf = bytes.readFloat();
yrf = bytes.readFloat();
for (i = 0; i < _particleArray.length; i++)
{
p = _particleArray[i];
setX = p.x + Math.round(xrf * Math.random() * 300);
setY = p.y + Math.round(yrf * Math.random() * 300);
_canvas.setPixel32(setX, setY, p.c);
}
}
_canvas.unlock();
}
}
}
//========================================================================
// Particleクラス
//========================================================================
class Particle {
public var x:Number = 0;
public var y:Number = 0;
public var c:int = 0;
public function Particle()
{
}
}