visualizer
beat detection from: http://wonderfl.net/c/tUY6
revised for rendering quality.
/**
* Copyright codeonwort ( http://wonderfl.net/user/codeonwort )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/b7af
*/
package {
import flash.media.SoundChannel;
import flash.media.Sound;
import flash.net.URLRequest
import flash.media.SoundLoaderContext
import flash.display.Sprite
import flash.events.Event
public class FlashTest extends Sprite {
private var s:Sound
private var vis:BezierGraph
public function FlashTest() {
// write as3 code here..
stage.addEventListener("rightClick", function($:Event):void{})
s = new Sound(new URLRequest('http://clug.kr/~codeonwort/file_pool/old_elvengard.mp3'), new SoundLoaderContext(1000, true));
s.addEventListener(Event.COMPLETE, comp)
}
private function comp(e:Event):void {
MP3Button.channel = s.play()
vis = new BezierGraph(465, 465)
addEventListener("enterFrame", loop)
addChild(vis)
}
private function loop(e:Event):void {
vis.update()
}
}
}
class MP3Button {
public static var channel:SoundChannel
}
//package lib {
import flash.utils.ByteArray
/*public*/ interface Visualizer {
function resize(w:Number, h:Number):void
function update():void
function dispose():void
}
//}
//package lib {
import flash.display.Sprite
import flash.utils.ByteArray
import flash.media.SoundChannel
import flash.media.SoundMixer
/*public*/ class SpriteVisualizer extends Sprite implements Visualizer {
private var _w:Number, _h:Number
private var _cx:Number, _cy:Number
private var _byte:ByteArray = new ByteArray
private var _autoBG:int = -1
public function SpriteVisualizer(w:Number, h:Number) {
_w = w, _h = h
_cx = w/2, _cy = h/2
}
public function resize(w:Number, h:Number):void {
width = w, height = h
_cx = w/2, _cy = h/2
if(_autoBG != -1){
graphics.clear()
graphics.beginFill(_autoBG, 1)
graphics.drawRect(0, 0, w, h)
graphics.endFill()
}
}
public function update():void {}
public function dispose():void {}
public override function get width():Number { return _w }
public override function get height():Number { return _h }
public override function set width(v:Number):void { _w = v }
public override function set height(v:Number):void { _h = v }
protected final function get cx():Number { return _cx }
protected final function get cy():Number { return _cy }
protected final function getLeftPeak():Number {
var ch:SoundChannel = MP3Button.channel
return ch ? ch.leftPeak : 0
}
protected final function getRightPeak():Number {
var ch:SoundChannel = MP3Button.channel
return ch ? ch.rightPeak : 0
}
protected final function getPeak():Number {
var ch:SoundChannel = MP3Button.channel
return ch ? Math.max(ch.leftPeak, ch.rightPeak) : 0
}
protected final function getSpectrum(fft:Boolean=false, factor:uint=0):ByteArray {
var ba:ByteArray = new ByteArray
SoundMixer.computeSpectrum(ba, fft, factor)
return ba
}
protected final function set autoBackground(color:int):void {
_autoBG = color
if(_autoBG != -1){
graphics.clear()
graphics.beginFill(_autoBG, 1)
graphics.drawRect(0, 0, width, height)
graphics.endFill()
}
}
}
//}
//package lib {
import flash.display.Graphics
import flash.display.Sprite
import flash.geom.Point
import flash.geom.Vector3D
import flash.geom.Matrix3D
import flash.filters.GlowFilter
/*public*/ class BezierGraph extends SpriteVisualizer {
private const pi2:Number = Math.PI + Math.PI
private const N:int = 16
private var xs:Array = [], ys:Array = []
private var container:Sprite
private var glow:GlowFilter
private var _transform:Matrix3D
private var _txr:Number = 0, _tyr:Number = 0
private var _xr:Number = 0, _yr:Number = 0
public function BezierGraph(w:Number, h:Number) {
super(w, h)
autoBackground = 0x0
for(var i:int=0 ; i<N ; i++){
xs[i] = Math.cos(pi2 * i/N)
ys[i] = Math.sin(pi2 * i/N)
}
_transform = new Matrix3D
_xr = Math.random() * 360
_yr = Math.random() * 360
addChild(container = new Sprite)
container.x = cx ; container.y = cy
glow = new GlowFilter(0xffff00, 1, 0, 0, 2)
}
public override function resize(w:Number, h:Number):void {
super.resize(w, h)
container.x = cx ; container.y = cy
}
private var vol:Number = 1
public override function update():void {
var peak:Number = .5 * (getLeftPeak() + getRightPeak())
if(peak > .1){
var start:int = N * Math.random()
var end:int
var power:int = 1 + int(peak * 3)
var xr:Number = Math.random()*360
var yr:Number = Math.random()*360
var zr:Number = Math.random()*360
for(var i:int=0; i<power; i++){
end = N * Math.random()
if(start == end) end = (end+1) % N
var M:Missile = new Missile(this, power*2, 0.02 + 0.1 * peak, xs[start], xs[end], ys[start], ys[end])
M.setAngle(xr, yr, zr)
container.addChild(M)
M.fire()
}
}
if(_xr > 360) { _xr -= 720 ; _txr -= 720 }
if(_yr > 360) { _yr -= 720 ; _tyr -= 720 }
if(peak > .6 * vol){
_txr = _xr + peak * 55
_tyr = _yr + 10
glow.color = Math.random() * 0xffffff
}else _tyr = _yr + 10/3
_transform.identity()
_transform.appendRotation(_xr += 0.3 * (_txr - _xr), Vector3D.X_AXIS)
_transform.appendRotation(_yr += 0.3 * (_tyr - _yr), Vector3D.Y_AXIS)
vol = Math.max(vol * 0.97, peak * 2)
glow.blurX = glow.blurY = log2(peak * 256)
container.filters = [glow]
}
private function log2(n:int):int {
var l:int = 0
while(n = n>>1) l++
return l
}
public function get R():Number { return Math.min(width, height) / 2 }
public function get T():Matrix3D { return _transform }
}
//}
import flash.display.Shape
import flash.events.Event
import flash.geom.Vector3D
import flash.geom.Matrix3D
class Missile extends Shape {
private var _x0:Number, _y0:Number, _x1:Number, _y1:Number
private var _t:Number = 0, _speed:Number
private var _thickness:int, _color:uint = 0xffffff, _alpha:Number = 1
private var _G:BezierGraph
private const N:int = 9, N3:int = 27
private var _vec:Vector.<Number>, _out:Vector.<Number>
private var _transform:Matrix3D
public function Missile(G:BezierGraph, T:int, speed:Number, x0:Number, x1:Number, y0:Number, y1:Number) {
_G = G ; _thickness = T
_speed = speed
_x0 = x0 ; _y0 = y0 ; _x1 = x1 ; _y1 = y1
_vec = new Vector.<Number>(N3, true)
_out = new Vector.<Number>(N3, true)
for(var i:int=0; i<_vec.length; i+=3) _vec[i+2] = 0
}
public function setAngle(xr:Number, yr:Number, zr:Number):void {
_transform = new Matrix3D
_transform.identity()
_transform.prependRotation(xr, Vector3D.X_AXIS)
_transform.prependRotation(yr, Vector3D.Y_AXIS)
_transform.prependRotation(zr, Vector3D.Z_AXIS)
}
public function fire():void {
addEventListener("enterFrame", loop)
}
private function loop(e:Event):void {
_t += _speed
var R:Number = _G.R, s:Number, k:Number
var x0:Number = R * _x0, y0:Number = R * _y0
var x1:Number = R * _x1, y1:Number = R * _y1
if(_t <= 1){
graphics.clear()
graphics.lineStyle(_thickness, _color, _alpha)
for(s=0; s<N3; s+=3){
k = _t * s/N3
_out[s] = bezier2(x0, 0, x1, k)
_out[s+1] = bezier2(y0, 0, y1, k)
_out[s+2] = 0
}
render()
}else if(_t <= 2){
graphics.clear()
graphics.lineStyle(_thickness, _color, _alpha)
for(s=0; s<N3; s+=3){
k = (_t - 1) + (2 - _t) * s/N3
_out[s] = bezier2(x0, 0, x1, k)
_out[s+1] = bezier2(y0, 0, y1, k)
_out[s+2] = 0
}
render()
}else{
removeEventListener("enterFrame", loop)
parent.removeChild(this)
}
_alpha -= 0.05
_thickness -= 0.05
if(_alpha <= 0 || _thickness < 0){
removeEventListener("enterFrame", loop)
parent.removeChild(this)
}
}
private function render():void {
_transform.transformVectors(_out, _vec)
_G.T.transformVectors(_vec, _out)
graphics.moveTo(_out[0], _out[1])
for(var s:int=3; s<N3; s+=3) graphics.lineTo(_out[s], _out[s+1])
}
}
/*public*/ function bezier2(x0:Number, x1:Number, x2:Number, t:Number):Number {
return linear(linear(x0, x1, t), linear(x1, x2, t), t)
}
/*public*/ function linear(x0:Number, x1:Number, t:Number):Number {
return x0 + (x1 - x0) * t
}