forked from: Music Atom
/**
* Copyright es335dotr ( http://wonderfl.net/user/es335dotr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/eW5W
*/
// forked from wonderwhyer's Music Atom
package {
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextField;
import com.codeazur.as3swf.SWF;
import com.codeazur.as3swf.SWFData;
import com.codeazur.as3swf.data.SWFScene;
import com.codeazur.as3swf.data.SWFSymbol;
import com.codeazur.as3swf.data.consts.SoundCompression;
import com.codeazur.as3swf.data.consts.SoundRate;
import com.codeazur.as3swf.data.consts.SoundSize;
import com.codeazur.as3swf.data.consts.SoundType;
import com.codeazur.as3swf.tags.TagDefineSceneAndFrameLabelData;
import com.codeazur.as3swf.tags.TagDefineSound;
import com.codeazur.as3swf.tags.TagDoABC;
import com.codeazur.as3swf.tags.TagEnd;
import com.codeazur.as3swf.tags.TagFileAttributes;
import com.codeazur.as3swf.tags.TagSetBackgroundColor;
import com.codeazur.as3swf.tags.TagShowFrame;
import com.codeazur.as3swf.tags.TagSymbolClass;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import net.hires.debug.Stats;
/**
* MP3 Loading based on this code:
* http://code.google.com/p/makc/source/browse/trunk/flash/fp10_fft/ClientMP3Loader.as
*/
[SWF(width=465,height=465,backgroundColor=0x000000, frameRate = 30)]
public class MusicalCircles extends Sprite {
public var fr:FileReference;
public var soundSource:Sound;
public var currentSong:SoundChannel;
public var visualizer:Visualizer;
public function MusicalCircles() {
stage.addEventListener(MouseEvent.MOUSE_UP,up);
addEventListener(Event.ENTER_FRAME,update);
var txt:TextField = new TextField();
txt.defaultTextFormat = new TextFormat(null,12,0xffffff);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.selectable=false;
txt.text = "Click anywhere to select an mp3 file";
txt.x = 120;
visualizer = new Visualizer();
addChild(visualizer);
//addChild(new Stats());
addChild(txt);
}
public function update(e:Event):void {
if(currentSong)
visualizer.update();
}
public function up(e:Event):void {
fr = new FileReference();
fr.addEventListener(Event.SELECT, onFileSelected);
fr.addEventListener(Event.COMPLETE, parse);
var mp3Filter:FileFilter = new FileFilter("mp3","*.mp3");
fr.browse([mp3Filter]);
if (currentSong)
{
currentSong.stop();
currentSong = null;
visualizer.clean();
}
}
public function onFileSelected(e:Event):void
{
fr.load();
}
public function parse(e:Event):void
{
var swf:ByteArray = createSWFFromMP3(fr.data);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, SoundLoaded);
loader.loadBytes(swf);
}
public function SoundLoaded(e:Event):void
{
var SoundClass:Class = LoaderInfo(e.currentTarget).applicationDomain.getDefinition("MP3Wrapper_soundClass") as Class;
soundSource = new SoundClass() as Sound;
currentSong = soundSource.play();
currentSong.addEventListener(Event.COMPLETE,songEnded);
}
public function songEnded(e:Event):void
{
currentSong = null;
}
public function createSWFFromMP3(mp3:ByteArray):ByteArray
{
// Create an empty SWF
// Defaults to v10, 550x400px, 50fps, one frame (works fine for us)
var swf:SWF = new SWF();
// Add FileAttributes tag
// Defaults: as3 true, all other flags false (works fine for us)
swf.tags.push(new TagFileAttributes());
// Add SetBackgroundColor tag
// Default: white background (works fine for us)
swf.tags.push(new TagSetBackgroundColor());
// Add DefineSceneAndFrameLabelData tag
// (with the only entry being "Scene 1" at offset 0)
var defineSceneAndFrameLabelData:TagDefineSceneAndFrameLabelData = new TagDefineSceneAndFrameLabelData();
defineSceneAndFrameLabelData.scenes.push(new SWFScene(0, "Scene 1"));
swf.tags.push(defineSceneAndFrameLabelData);
// Add DefineSound tag
// The ID is 1, all other parameters are automatically
// determined from the mp3 itself.
swf.tags.push(TagDefineSound.createWithMP3(1, mp3));
// Add DoABC tag
// Contains the AS3 byte code for the document class and the
// class definition for the embedded sound
swf.tags.push(TagDoABC.create(abc));
// Add SymbolClass tag
// Specifies the document class and binds the sound class
// definition to the embedded sound
var symbolClass:TagSymbolClass = new TagSymbolClass();
symbolClass.symbols.push(SWFSymbol.create(1, "MP3Wrapper_soundClass"));
symbolClass.symbols.push(SWFSymbol.create(0, "MP3Wrapper"));
swf.tags.push(symbolClass);
// Add ShowFrame tag
swf.tags.push(new TagShowFrame());
// Add End tag
swf.tags.push(new TagEnd());
// Publish the SWF
var swfData:SWFData = new SWFData();
swf.publish(swfData);
return swfData;
}
private static var abcData:Array = [
0x10, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x07, 0x6d, 0x78, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x0a, 0x49, 0x46, 0x6c, 0x65, 0x78, 0x41, 0x73, 0x73, 0x65, 0x74, 0x0a, 0x53, 0x6f, 0x75, 0x6e,
0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x0b, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x6d, 0x65, 0x64,
0x69, 0x61, 0x05, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x6d, 0x78, 0x2e, 0x63, 0x6f, 0x72, 0x65,
0x3a, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x65, 0x74, 0x00, 0x15, 0x4d, 0x50, 0x33,
0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x5f, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6c, 0x61,
0x73, 0x73, 0x0a, 0x4d, 0x50, 0x33, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x0d, 0x66, 0x6c,
0x61, 0x73, 0x68, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x06, 0x53, 0x70, 0x72, 0x69,
0x74, 0x65, 0x0a, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x05, 0x43, 0x6c,
0x61, 0x73, 0x73, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61,
0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x32, 0x30, 0x30, 0x36, 0x2f, 0x66, 0x6c,
0x65, 0x78, 0x2f, 0x6d, 0x78, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x07, 0x56,
0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x07, 0x33, 0x2e,
0x30, 0x2e, 0x30, 0x2e, 0x30, 0x0b, 0x6d, 0x78, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
0x6c, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x0c, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x2e, 0x65,
0x76, 0x65, 0x6e, 0x74, 0x73, 0x0f, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x73, 0x70, 0x61,
0x74, 0x63, 0x68, 0x65, 0x72, 0x0d, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x11, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x16, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x0a, 0x16, 0x01, 0x16,
0x04, 0x18, 0x06, 0x16, 0x07, 0x18, 0x08, 0x16, 0x0a, 0x18, 0x09, 0x08, 0x0e, 0x16, 0x14, 0x03,
0x01, 0x01, 0x01, 0x04, 0x14, 0x07, 0x01, 0x02, 0x07, 0x01, 0x03, 0x07, 0x02, 0x05, 0x09, 0x02,
0x01, 0x07, 0x04, 0x08, 0x07, 0x04, 0x09, 0x07, 0x06, 0x0b, 0x07, 0x04, 0x0c, 0x07, 0x04, 0x0d,
0x07, 0x08, 0x0f, 0x07, 0x04, 0x10, 0x07, 0x01, 0x12, 0x09, 0x03, 0x01, 0x07, 0x04, 0x13, 0x07,
0x09, 0x15, 0x09, 0x08, 0x02, 0x07, 0x06, 0x16, 0x07, 0x06, 0x17, 0x07, 0x06, 0x18, 0x0d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x03, 0x09, 0x03, 0x01,
0x04, 0x05, 0x00, 0x05, 0x02, 0x09, 0x05, 0x00, 0x08, 0x00, 0x06, 0x07, 0x09, 0x07, 0x00, 0x0b,
0x01, 0x08, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x04, 0x01, 0x0a, 0x06, 0x01, 0x0b, 0x11, 0x01,
0x07, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x01, 0x0c, 0x06, 0x00, 0x00, 0x08, 0x08, 0x03, 0x01, 0x01,
0x04, 0x00, 0x00, 0x06, 0x01, 0x02, 0x04, 0x00, 0x01, 0x09, 0x01, 0x05, 0x04, 0x00, 0x02, 0x0c,
0x01, 0x06, 0x04, 0x01, 0x03, 0x0c, 0x00, 0x01, 0x01, 0x01, 0x02, 0x03, 0xd0, 0x30, 0x47, 0x00,
0x00, 0x01, 0x00, 0x01, 0x03, 0x03, 0x01, 0x47, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x02, 0x0a,
0xd0, 0x30, 0x5d, 0x04, 0x20, 0x58, 0x00, 0x68, 0x01, 0x47, 0x00, 0x00, 0x04, 0x02, 0x01, 0x05,
0x06, 0x09, 0xd0, 0x30, 0x5e, 0x0a, 0x2c, 0x11, 0x68, 0x0a, 0x47, 0x00, 0x00, 0x05, 0x01, 0x01,
0x06, 0x07, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00, 0x47, 0x00, 0x00, 0x06, 0x02, 0x01, 0x01, 0x05,
0x17, 0xd0, 0x30, 0x5d, 0x0d, 0x60, 0x0e, 0x30, 0x60, 0x0f, 0x30, 0x60, 0x03, 0x30, 0x60, 0x03,
0x58, 0x01, 0x1d, 0x1d, 0x1d, 0x68, 0x02, 0x47, 0x00, 0x00, 0x07, 0x01, 0x01, 0x06, 0x07, 0x03,
0xd0, 0x30, 0x47, 0x00, 0x00, 0x08, 0x01, 0x01, 0x07, 0x08, 0x06, 0xd0, 0x30, 0xd0, 0x49, 0x00,
0x47, 0x00, 0x00, 0x09, 0x02, 0x01, 0x01, 0x06, 0x1b, 0xd0, 0x30, 0x5d, 0x10, 0x60, 0x0e, 0x30,
0x60, 0x0f, 0x30, 0x60, 0x03, 0x30, 0x60, 0x02, 0x30, 0x60, 0x02, 0x58, 0x02, 0x1d, 0x1d, 0x1d,
0x1d, 0x68, 0x05, 0x47, 0x00, 0x00, 0x0a, 0x01, 0x01, 0x08, 0x09, 0x03, 0xd0, 0x30, 0x47, 0x00,
0x00, 0x0b, 0x02, 0x01, 0x09, 0x0a, 0x0b, 0xd0, 0x30, 0xd0, 0x60, 0x05, 0x68, 0x08, 0xd0, 0x49,
0x00, 0x47, 0x00, 0x00, 0x0c, 0x02, 0x01, 0x01, 0x08, 0x23, 0xd0, 0x30, 0x65, 0x00, 0x60, 0x0e,
0x30, 0x60, 0x0f, 0x30, 0x60, 0x11, 0x30, 0x60, 0x12, 0x30, 0x60, 0x13, 0x30, 0x60, 0x07, 0x30,
0x60, 0x07, 0x58, 0x03, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x68, 0x06, 0x47, 0x00, 0x00
];
private static function abcDataToByteArray():ByteArray {
var ba:ByteArray = new ByteArray();
for (var i:uint = 0; i < abcData.length; i++) {
ba.writeByte(abcData[i]);
}
return ba;
}
private static var abc:ByteArray = abcDataToByteArray();
}
}
import flash.display.BlendMode;
import flash.display.Graphics;
import flash.geom.Rectangle;
import flash.filters.BlurFilter;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.ColorTransform;
import flash.utils.ByteArray;
import flash.display.Sprite;
import flash.media.SoundMixer;
import org.si.utils.FFT;
class Dot {
public var x:Number;
public var y:Number;
public var dx:Number = 0;
public var dy:Number = 0;
public var direction:Number;
public var color:uint = 0;
public var alpha:Number = 0;
public function Dot(x:Number,y:Number,direction:Number) {
this.x = x;
this.y = y;
this.direction = direction;
}
}
class Visualizer extends Sprite{
private var wave:ByteArray;
private var xx:Number;
private var yy:Number;
private var direction:Number = 0;
private var color:Number = 0;
private var view:BitmapData;
private var bmp:Bitmap;
public var c:uint=0;
public var steps:uint = 8;
public var sp:Sprite;
public var dots:Vector.<Dot>;
public var bf:BlurFilter = new BlurFilter(1.5,1.5,1);
public function Visualizer()
{
wave = new ByteArray();
view = new BitmapData(450,450,false,0);
bmp = new Bitmap(view);
addChild(bmp);
bmp.x=0;
bmp.y=0;
xx = view.width/2;
yy = view.height/2;
dots = new Vector.<Dot>();
for(var i:uint=0;i<steps;i++)
{
dots.push(new Dot(0,0,Math.random()*Math.PI*2));
}
sp = new Sprite();
}
public function update():void {
SoundMixer.computeSpectrum(wave,false);
var spVal:Number;
var i:uint;
var inRe:Vector.<Number> = new Vector.<Number>();
var g:Graphics = sp.graphics;
c++;
if(c%20==0){
var ct:ColorTransform = new ColorTransform(1,1,1,0.999);
view.colorTransform(view.rect,ct);
}
var halfPos:uint = wave.length/2;
for(i=0;i<256;i++)
{
wave.position = i*4;
var sp1:Number = wave.readFloat();
wave.position = i*4+halfPos;
var sp2:Number=wave.readFloat();
inRe.push((sp1+sp2)/2);
}
var fft:FFT = new FFT(256);
fft.setData(inRe);
var spec:FFT = fft.calcRealFFT();
var res:Vector.<Number> = spec.getData();
var part:uint = 256/steps;
var shift:uint = 600/(steps+1);
var pow:Number = -1.8;
for(var j:uint=0;j<steps;j++){
var sec1:Vector.<Number> = res.splice(0,part);
var fft2:FFT = new FFT(part);
fft2.setData(sec1);
fft2.calcRealIFFT();
var wave1:Vector.<Number> = fft2.getData();
var m:Number = (Math.pow(j+1,pow)+0.004)*10;
var dot:Dot = dots[j];
dot.alpha*=0.5;
var d:Number = Math.sin(dot.y*0.05);
var xx:Number = view.width/2+Math.sin(dot.x*0.05)*200*d;
var yy:Number = view.height/2+Math.cos(dot.x*0.05)*200*d;
g.clear();
g.moveTo(xx,yy);
for(i=1;i<part;i++)
{
spVal = wave1[i]/m;
dot.alpha = dot.alpha*0.9 + Math.min(1,Math.abs(spVal*0.5))*0.1;
dot.direction+=spVal*0.1;
dot.x+=Math.sin(dot.direction);//*0.5;
dot.y+=Math.cos(dot.direction);//*0.5;
g.lineStyle(dot.alpha*0.5,HSLtoRGB(1,dot.direction*4,1,0.0001+dot.alpha*0.5));
d = Math.sin(dot.y*0.05);
xx = view.width/2+Math.sin(dot.x*0.05)*200*d;
yy = view.height/2+Math.cos(dot.x*0.05)*200*d;
g.lineTo(xx,yy);
}
view.draw(sp,null,null,BlendMode.ADD);
}
view.applyFilter(view,view.rect,view.rect.topLeft,bf);
}
public function clean():void
{
view.fillRect(view.rect,0);
dots = new Vector.<Dot>();
for(var i:uint=0;i<steps;i++)
{
dots.push(new Dot(0,0,Math.random()*Math.PI*2));
}
}
private function HSLtoRGB(a:Number=1,hue:Number=0,saturation:Number=1,lightness:Number=0.5):uint
{
a = Math.max(0,Math.min(1,a));
saturation = Math.max(0,Math.min(1,saturation));
lightness = Math.max(0,Math.min(1,lightness));
hue = hue%360;
if(hue<0)hue+=360;
hue/=60;
var C:Number = (1-Math.abs(2*lightness-1))*saturation;
var X:Number = C*(1-Math.abs((hue%2)-1));
var m:Number = lightness-0.5*C;
C=(C+m)*255;
X=(X+m)*255;
m*=255;
if(hue<1) return (C<<16) + (X<<8) + m;
if(hue<2) return (X<<16) + (C<<8) + m;
if(hue<3) return (m<<16) + (C<<8) + X;
if(hue<4) return (m<<16) + (X<<8) + C;
if(hue<5) return (X<<16) + (m<<8) + C;
return (C<<16) + (m<<8) + X;
}
}