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"; } } 音 SoundVisualizer