forked from: sound visualize Test002
///////////
注意
Flash Player 10.0 r22以降じゃないと
なぜかプレーヤが落ちる
////////////
// forked from mtok's sound visualize Test002
// forked from mtok's flash on 2009-4-14
/////////////
//注意
//Flash Player 10.0 r22以降じゃないと
//なぜかプレーヤが落ちる
//////////////
package
{
[SWF(width="465", height="465", backgroundColor="#000000", frameRate=60)]
import flash.display.Sprite;
import flash.events.Event;
import flash.media.SoundLoaderContext;
import flash.net.URLRequest;
import org.libspark.thread.EnterFrameThreadExecutor;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.media.SoundLoaderThread;
import org.libspark.thread.utils.Progress;
/**
* ...
* @author Motoki Matsumoto
*/
public class SouncPosition extends Sprite
{
public function SouncPosition()
{
Thread.initialize(new EnterFrameThreadExecutor());
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(e:Event):void
{
var mainThread:MainThread = new MainThread(this);
mainThread.start();
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.utils.Timer;
import flash.errors.IOError;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.geom.Point;
import flash.display.BlendMode;
import org.libspark.thread.utils.Progress;
import org.libspark.thread.utils.events.ProgressEvent;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.media.SoundLoaderThread;
internal class MainThread extends Thread {
private var container:DisplayObjectContainer;
private var soundLoaderThread:SoundLoaderThread;
private var sound:Sound;
private var channel:SoundChannel;
private var position:Number;
private var visualizer:SoundVisualizer;
public function MainThread(container:DisplayObjectContainer) {
super();
this.container = container;
}
override protected function run():void
{
super.run();
var context:flash.media.SoundLoaderContext = new flash.media.SoundLoaderContext(1000, true);
var req:flash.net.URLRequest = new flash.net.URLRequest("http://www.matzmtok.com/wonderfl/sound/spoon_revenge.mp3");
soundLoaderThread = new SoundLoaderThread(req, context);
var bar:ProgressBar;
try {
soundLoaderThread.start();
soundLoaderThread.join();
bar = new ProgressBar();
container.addChild(bar);
soundLoaderThread.progress..addEventListener(ProgressEvent.UPDATE, function():void {
bar.percent = soundLoaderThread.progress.percent;
});
soundLoaderThread.progress..addEventListener(ProgressEvent.COMPLETED, function():void {
container.removeChild(bar);
});
visualizer = new SoundVisualizer();
container.addChild(visualizer);
next(initSound);
}catch (e:IOError) {
}
}
private function initSound():void {
var sf:SoundVisualizer;
if ( soundLoaderThread.progress.isCompleted) {
sound = soundLoaderThread.sound;
//trace(sound.id3.songName, sound.id3.artist, sound.length);
channel = sound.play();
channel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
container.stage.addEventListener(MouseEvent.MOUSE_DOWN, stopSound);
//next(loop);
}
}
private function stopSound(e:MouseEvent = null):void
{
container.stage.removeEventListener(e.type, arguments.callee);
//trace(channel.position);
position = channel.position;
channel.stop();
channel = null;
container.stage.addEventListener(MouseEvent.MOUSE_DOWN, startSound);
}
private function startSound(e:MouseEvent = null):void
{
container.stage.removeEventListener(e.type, arguments.callee);
container.stage.addEventListener(MouseEvent.MOUSE_DOWN, stopSound);
channel = sound.play(position);
channel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
}
private function soundCompleteHandler(e:Event):void
{
channel = null;
container.stage.removeEventListener(MouseEvent.MOUSE_DOWN, stopSound);
}
private function loop():void {
//trace(channel.position);
next(loop);
}
}
internal class SoundVisualizer extends Sprite {
private var bitmap:Bitmap;
private var data:ByteArray;
private var center:Point;
private var vR:Number; //virtical radius
private var hR:Number; //horizontal radius
private var h:Number = 0;
private var s:Number = 1;
private var v:Number = 1;
private var canvas:Shape;
public function SoundVisualizer() {
super();
canvas = new Shape();
addChild(canvas);
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
data= new ByteArray();
center = new Point(0, 0);
}
private function addedToStage(e:Event):void
{
if (bitmap != null) {
bitmap.bitmapData.dispose();//必要、不要?
}
bitmap = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x000000));
addChild(bitmap);
addEventListener(Event.ENTER_FRAME, enterframeHandler)
center.x = stage.stageWidth - 50;
center.y = stage.stageHeight;
//removeEventListener(e.type, arguments.callee);
}
private function enterframeHandler(e:Event):void
{
SoundMixer.computeSpectrum(data, true, 1);
var c:uint = HSVtoRGB(h, s, v);
c= 0xAAEEFF;
h += 1;
var mxBox:Matrix = new Matrix();
mxBox.createGradientBox(200, 400);
var g:Graphics = canvas.graphics;
g.clear();
g.lineStyle(1, c);
g.lineGradientStyle("linear", [0xFFFF00, 0xAACCFF, 0xAAAAA], [0, 20, 100], [0x00, 0x99,0xFF], mxBox, "reflect", "linearRGB");
var amp:Number;
var i:int;
for (i = 0; i < 256; i++) {
amp = data.readFloat();
g.drawRect( -128 + center.x + i, center.y - amp * 50,1, amp * 50);
}
g.moveTo( -128 + center.x, center.y);
for (i = 0; i < 256; i++) {
amp = data.readFloat();
g.drawRect( -128 + center.x -i, center.y - amp * 50,1, amp * 50);
// g.lineTo( -128 + center.x -i, center.y - amp * 50);
}
var bd:BitmapData = bitmap.bitmapData;
var mat:Matrix = new Matrix();
mat.translate( -center.x, -center.y);
//mat.scale(1.1, 1.1);
mat.translate(center.x, center.y);
// bd.draw(bd, mat, new ColorTransform(1.01,1.01,1.81), BlendMode.NORMAL);
bd.scroll(0,4);
// bitmap.bitmapData.applyFilter(bitmap.bitmapData, bitmap.bitmapData.rect, new Point(0, 0), new BlurFilter(2, 1, 3));
bitmap.bitmapData.draw(canvas, new Matrix(), null, BlendMode.NORMAL);
}
private function HSVtoRGB(h:Number, s:Number, v:Number):uint {
var r:Number=0, g:Number=0, b:Number=0;
var i:Number, x:Number, y:Number, z:Number;
if (s < 0) s = 0; if (s > 1) {
s=1;
}
if (v < 0) v = 0; if (v > 1) {
v=1;
}
h = h % 360; if (h < 0) h += 360; h /= 60;
i = h >> 0;
x = v * (1 - s); y = v * (1 - s * (h - i)); z = v * (1 - s * (1 - h + i));
switch(i){
case 0 : r=v; g=z; b=x; break;
case 1 : r=y; g=v; b=x; break;
case 2 : r=x; g=v; b=z; break;
case 3 : r=x; g=y; b=v; break;
case 4 : r=z; g=x; b=v; break;
case 5 : r=v; g=x; b=y; break;
}
var c:uint;
c = (r * 255 >> 0) << 16 | (g * 255 >> 0) << 8 | (b * 255 >> 0);
return c;
}
}
internal class ProgressBar extends Sprite {
private var _percent:Number
public function ProgressBar() {
graphics.lineStyle(1, 0x4f4f4f);
graphics.drawRect(0, 0, 100, 10);
}
public function get percent():Number { return _percent; }
public function set percent(value:Number):void
{
_percent = value;
graphics.beginFill(0xff0000);
graphics.drawRect(1, 1, _percent * 100, 9);
graphics.endFill();
}
}