Butterfly Sound
クリックするたびに音のサンプルレートと、フーリエ変換の使用有無が切り替わるので5~10回くらいクリックで見た目的には全く違ったSound Visualizerになります。
/**
* Copyright rettuce ( http://wonderfl.net/user/rettuce )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/8xSc
*/
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.events.TimerEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import flash.system.LoaderContext;
import flash.media.SoundLoaderContext;
// library
import caurina.transitions.Tweener;
[SWF(width = 465, height = 465, backgroundColor = 0x000000, frameRate = 30)]
/**
* ...
* @author rettuce
* 音はTsabeat より拝借
* http://www.ektoplazm.com/2010/highpersonic-whomen-alternative-energysource
*/
public class Main extends MovieClip
{
private var _bg:Sprite;
private var _sound:Sound;
private var _channel:SoundChannel;
private var _byteArray:ByteArray;
private var _rectArray:Array;
private var _radius:Number; // 半径
private var _color:Number = 0xFF0000;
private var _count:int = 0; // サンプリングの解像度 クリックごとに44.1 KHzから1/2の粗さになる
private var _flg:Boolean = false; // フーリエ変換使用有無フラグ
private var _bold:Number = 10 ; // 円の太さ 5~50くらいかな?
private var _keisu:Number = 3; // 音の振動幅 1.5~5くらいかな?
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init );
}
private function init(e:Event = null ):void
{
removeEventListener(Event.ADDED_TO_STAGE, init );
_byteArray = new ByteArray();
_rectArray = new Array();
_radius = stage.stageHeight / 2.5;
//背景色用矩形
_bg = new Sprite();
addChildAt(_bg, 0);
stage.addEventListener(MouseEvent.CLICK, function():void {
_count++;
if (_flg) _flg = false;
else _flg = true;
})
soundRectSet();
soundSet();
}
private function soundSet():void
{
// LoaderContextを準備
var context:SoundLoaderContext = new SoundLoaderContext(1000, true);
// 再生用 sound クラスの 生成と sampleDataEvent 取得
_sound = new Sound();
_sound.load(new URLRequest("http://lab.rettuce.com/common/src/PieceOfCake.mp3"), context);
_channel = _sound.play( 0, 1 );
addEventListener(Event.ENTER_FRAME, soundAnimation );
}
private function soundRectSet():void
{
for (var i:int = 0; i < 1024; i++) { // 右左チャンネル交互
var rect:MovieClip = newRect();
rect.alpha = 0.5;
rect.width = stage.stageWidth / 256;
rect.height = stage.stageHeight / 512;
rect.x = _radius * Math.cos((((360 / 1024) * i+90)* Math.PI / 180)) + stage.stageWidth / 2;
rect.y = _radius * Math.sin((((360 / 1024) * i+90)* Math.PI / 180)) + stage.stageHeight / 2;
rect.rotationZ = (360 / 1024) * i ;
addChild(rect);
_rectArray.push(rect);
}
}
private function newRect():MovieClip {
var rect:MovieClip = new MovieClip()
rect.graphics.beginFill(_color);
rect.graphics.drawRect(-25,-25, _bold, _bold);
rect.graphics.endFill();
return rect
}
private function soundAnimation(e:Event):void
{
SoundMixer.computeSpectrum(_byteArray, _flg, _count );
for (var i:int = 0; i < 512; i += 2) {
var n:int = 1023 - i;
var numL:Number = _byteArray.readFloat() * _keisu +1.8;
_rectArray[i].scaleY = numL;
_rectArray[i+1].scaleY = numL;
_rectArray[n].scaleY = numL;
_rectArray[n - 1].scaleY = numL;
}
}
}
}