音 SoundVisualizer
SoundVisualizer作ってみました
ParticleField × Line3D × Pixel3D の乱用技
@author zawa aka dubfrog
/**
* Copyright dubfrog ( http://wonderfl.net/user/dubfrog )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iwO6
*/
package {
/*SoundVisualizer作ってみました
ParticleField × Line3D × Pixel3D の乱用技 */
import flash.display.*;
import flash.events.*;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.media.SoundTransform;
import flash.utils.ByteArray;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.core.effects.BitmapColorEffect;
import org.papervision3d.core.effects.BitmapLayerEffect;
import org.papervision3d.core.geom.Pixels;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Pixel3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.special.LineMaterial;
import org.papervision3d.materials.special.ParticleMaterial;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.special.ParticleField;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.layer.BitmapEffectLayer;
import org.papervision3d.view.Viewport3D;
[SWF(backgroundColor='0',width='465',height='465') ]
/* @author zawa aka dubfrog */
public class Main extends Sprite
{
public function Main():void
{
sound = new Sound(new URLRequest(SOUND_URL));
sound.addEventListener(Event.OPEN, sdLoadStart);
sound.addEventListener(ProgressEvent.PROGRESS, sdLoadProgress);
sound.addEventListener(Event.COMPLETE, sdLoadComplete);
sound.addEventListener(IOErrorEvent.IO_ERROR, sdIO_Error);
stage.quality = StageQuality.LOW;
var bgbmp:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
var bgObj:Bitmap = new Bitmap(bgbmp);
addChild(bgObj);
volume = 1;
pan = 1;
playBool = true;
spectrum = [];
bytes = new ByteArray();
bitMax = 255;
engine = new Sprite();
visualContainer = new Sprite();
addChild(visualContainer);
colorList = []; pixelList = []; lineList = []; fieldList = []; spectrumList = [];
numList = { px:new Array(), py:new Array(), pz:new Array(), spd:new Array(), cnt:0 };
lHgt = 180;
ltick = 3;
pSize = 5
pMax = 127;
angle = 0;
Wonderfl.capture_delay(30);
}
private function sdLoadStart(e:Event):void
{
//StreamStart...
}
private function sdLoadProgress(e:ProgressEvent):void
{
var loaded:Number = e.bytesLoaded;
var total:Number = e.bytesTotal;
var per:Number = Math.floor(loaded / total * 100);
}
private function sdLoadComplete(e:Event):void
{
//streamComplete...
sound.removeEventListener(Event.OPEN, sdLoadStart);
sound.removeEventListener(ProgressEvent.PROGRESS, sdLoadProgress);
sound.removeEventListener(Event.COMPLETE, sdLoadComplete);
sound.removeEventListener(IOErrorEvent.IO_ERROR, sdIO_Error);
init();
}
private function sdIO_Error(e:IOErrorEvent):void
{
throw new Error("ファイル入出力エラー");
}
private function play(_start:Number = 0, _loop:Number = 0, _volume:Number = 1, _pan:Number = 0):void
{
var sdTransform:SoundTransform = new SoundTransform(_volume, _pan);
channel = sound.play(_start, _loop, sdTransform);
channel.addEventListener(Event.SOUND_COMPLETE, sdPlayEnd);
callRendering();
}
private function stop():void
{
channel.stop();
stopRendering();
}
private function sdPlayEnd(e:Event):void
{
//playComplete...
channel.removeEventListener(Event.SOUND_COMPLETE, sdPlayEnd);
}
private function callRendering():void
{
engine.addEventListener(Event.ENTER_FRAME, update);
engine.addEventListener(Event.ENTER_FRAME, rendering);
}
private function stopRendering():void
{
engine.removeEventListener(Event.ENTER_FRAME, update);
engine.removeEventListener(Event.ENTER_FRAME, rendering);
}
private function update(e:Event):void
{
SoundMixer.computeSpectrum(bytes, true, 0);
var i:Number;
for (i = 0; i <= bitMax; i++) spectrum[i] = bytes.readFloat();
}
private function set setVolume(_volume:Number):void
{
if (channel)
{
var sdTransform:SoundTransform = new SoundTransform();
sdTransform.volume = _volume;
channel.soundTransform = sdTransform;
}else {
throw new Error("channelが関連付けされていません")
}
}
private function set setPan(_pan:Number):void
{
if (channel)
{
var sdTransform:SoundTransform = new SoundTransform();
sdTransform.pan = _pan;
channel.soundTransform = sdTransform;
}else {
throw new Error("channelが関連付けされていません")
}
}
private function init():void
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, parthColor);
loader.load( new URLRequest(URL), new LoaderContext(true) );
}
private function parthColor(e:Event):void
{
e.target.removeEventListener(Event.COMPLETE, parthColor);
var bmp:BitmapData = e.target.content.bitmapData;
var cnt:Number = 0;
for (var h:Number = 0; h <= pMax-1; h++)
{
for (var w:Number = 0; w <= pMax-1; w++)
{
var _color:String = bmp.getPixel(w, h).toString(16);
colorList[cnt] = "0xff" + _color;
cnt++;
}
}
createWorld();
spectrumRePush();
}
private function createWorld():void
{
scene = new Scene3D();
rootNode = new DisplayObject3D();
scene.addChild(rootNode);
viewport = new Viewport3D(0, 0, true, true);
visualContainer.addChild(viewport);
camera = new Camera3D();
CameraType.TARGET;
camera.z = -(camera.zoom * camera.focus);
renderer = new BasicRenderEngine();
renderer.renderScene(scene, camera, viewport);
//Layer...
bfx = new BitmapEffectLayer(viewport, stage.stageWidth, stage.stageHeight, true);
bfx.addEffect(new BitmapColorEffect(1, 1, 1, .6));
bfx.blendMode = BlendMode.ADD;
viewport.containerSprite.addLayer(bfx);
pixels = new Pixels(bfx);
rootNode.addChild(pixels);
//Line & Pixels
var cnt:Number = 0;
var lcnt:Number = 0;
for (var h:Number = 0; h <= pMax-1; h++)
{
for (var w:Number = 0; w <= pMax-1; w++)
{
numList.px[cnt] = w * 2 - pMax;
numList.py[cnt] = 0;
numList.pz[cnt] = (pMax * 2 - h * 2) - pMax;
numList.spd[cnt] = Math.random() * .3 + .2;
var p:Pixel3D = new Pixel3D(colorList[cnt], numList.px[cnt], numList.py[cnt], numList.pz[cnt]);
pixels.addPixel3D(p);
pixelList[cnt] = p;
if (cnt % Math.floor(pMax/10) == 0) {
var lineMat:LineMaterial = new LineMaterial(colorList[cnt], .1);
var line:Line3D;
var lineBox:Lines3D;
lineBox = new Lines3D(lineMat);
lineBox.scaleY = 0;
lineBox.addNewLine(ltick, numList.px[cnt], numList.py[cnt], numList.pz[cnt], numList.px[cnt], numList.py[cnt] + lHgt, numList.pz[cnt]);
rootNode.addChild(lineBox);
//bfx.addDisplayObject3D(lineBox);
lineList[cnt] = lineBox;
lcnt++;
}
cnt++;
}
}
//ParticleField...
var perMat:ParticleMaterial = new ParticleMaterial(0xffffff, .3, 1);
fields = new ParticleField(perMat, lcnt, pSize, 1000, 1000, 1000);
cnt = lcnt = 0;
for (h = 0; h <= pMax-1; h++)
{
for (w = 0; w <= pMax-1; w++)
{
fieldList[cnt] = null;
if (cnt % Math.floor(pMax/10) == 0) {
fieldList[cnt] = fields.geometry.vertices[lcnt];
fieldList[cnt].x = numList.px[cnt];
fieldList[cnt].y = numList.py[cnt];
fieldList[cnt].z = numList.pz[cnt];
lcnt++;
}
cnt++;
}
}
rootNode.addChild(fields);
bfx.addDisplayObject3D(fields);
trans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
renderer.renderScene(scene, camera, viewport);
play();
}
private function spectrumRePush():void
{
var cnt:Number = 0;
for (var i:Number = 0; i <= pixelList.length-1; i++)
{
if (i % bitMax-1 == 0) {cnt = 0; };
spectrumList[i] = spectrum[cnt]
cnt++;
}
}
private function rendering(e:Event):void
{
spectrumRePush();
var i:Number, gx:Number, gy:Number, gz:Number, scale:Number;
for (i = 0; i <= pixelList.length-1; i++)
{
gy = 20 * spectrumList[i];
pixelList[i].y += (gy - pixelList[i].y) * .3;
gy = spectrumList[i];
if (lineList[i] is Lines3D) lineList[i].scaleY += (gy - lineList[i].scaleY) * .3;
if (fieldList[i] != null) { fieldList[i].y += (gy * (lHgt) - fieldList[i].y) * .3; };
}
//color...
angle+=.01;
var sin:Number = Math.sin(angle)
var cos:Number = Math.cos(angle)
if (sin < .1) sin = Math.abs(sin)+.1;
if (cos < .1) cos = Math.abs(cos)+.1;
trans.redMultiplier = sin/4;
trans.greenMultiplier = cos/2;
trans.blueMultiplier = sin;
bfx.drawCommand.colorTransform = trans;
//mouseMotion...
var ry:Number = (visualContainer.mouseX / stage.stageWidth * 60 - 30) * 2;
var rx:Number = (visualContainer.mouseY / stage.stageHeight * 30 - 15) * 2;
rootNode.rotationY = ry;
rootNode.rotationX = rx - 30;
rootNode.scale = (visualContainer.mouseY / stage.stageHeight * 1) + 1.5;
//rendering...
renderer.renderScene(scene, camera, viewport);
}
/*_Vars______________________________________________________________________________________*/
private var visualContainer:Sprite;
private var sound:Sound;
private var volume:Number;
private var pan:Number;
private var playBool:Boolean;
private var channel:SoundChannel;
private var engine:Sprite;
private var spectrum:Array;
private var bytes:ByteArray;
private var bitMax:Number;
private var rootNode:DisplayObject3D;
private var viewport:Viewport3D;
private var scene:Scene3D;
private var renderer:BasicRenderEngine;
private var camera:Camera3D;
private var pixels:Pixels;
private var fields:ParticleField;
private var bfx:BitmapEffectLayer;
private var pixelList:Array;
private var lineList:Array;
private var fieldList:Array;
private var colorList:Array;
private var numList:Object;
private var spectrumList:Array;
private var pMax:Number;
private var pSize:Number;
private var lHgt:Number;
private var ltick:Number;
private var angle:Number;
private var trans:ColorTransform;
private const URL:String = "http://www.dubfrog.net/blog/images/logomark_s.jpg";
private const SOUND_URL:String = "http://www.dubfrog.net/blog/sound/bgm128k.mp3";
}
}