forked from: BeatDrawing + MP3 Choice
Just added loading MP3 from hard drive to see how it visualizes other songs.
Cool stuff, reminds me of one my own visualizer from here http://wonderwhy-er.deviantart.com/gallery/2601142#/d1j6l06
Will need to get to porting it to WonderFl :)
Update:
Tuned params a little to allow more quite songs to produce some change
Also removed random colors and made coloring somewhat change with the song
/**
* Copyright wonderwhyer ( http://wonderfl.net/user/wonderwhyer )
* GNU General Public License, v3 ( http://www.gnu.org/licenses/quick-guide-gplv3.html )
* Downloaded from: http://wonderfl.net/c/vFvs
*/
// forked from rettuce's BeatDrawing
package
{
import flash.geom.ColorTransform;
import flash.display.GradientType;
import caurina.transitions.Tweener;
//import com.demonsters.debugger.MonsterDebugger;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Sound;
import flash.media.SoundLoaderContext;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.utils.ByteArray;
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.media.SoundChannel;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.display.Loader;
import flash.display.LoaderInfo;
/**
* ...
* @author rettuce
*
*/
[SWF(width = 465, height = 465, backgroundColor = 0xFFFFFF, frameRate = 60)]
public class Beat extends Sprite
{
public function Beat()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init );
}
private function init(e:Event = null ):void
{
removeEventListener(Event.ADDED_TO_STAGE, init );
setStage();
stage.addEventListener(MouseEvent.MOUSE_UP,up);
var txt:TextField = new TextField();
txt.defaultTextFormat = new TextFormat(null,12,0x000000);
txt.autoSize = TextFieldAutoSize.LEFT;
txt.selectable=false;
txt.text = "Click anywhere to select an mp3 file";
txt.x = 120;
// SoundMixer
playSoundMixer();
addChild(txt);
addEventListener(Event.ENTER_FRAME,beatCheck2);
loaderInfo.addEventListener(Event.UNLOAD, function(e:Event):void {
stage.removeEventListener(Event.RESIZE, resizeEvent);
loaderInfo.removeEventListener(Event.UNLOAD, arguments.callee );
});
}
/* sound loading */
///////////////////////////////////////////////////////////////////////
public var fr:FileReference;
public var soundSource:Sound;
public var currentSong:SoundChannel;
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;
}
}
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
{
initPoints();
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();
/* Sound Mixer */
///////////////////////////////////////////////////////////////////////
private var _bArr:ByteArray = new ByteArray();
private var _pArr:Array = [];
private var _stg:Sprite;
private var _bg:Bitmap;
private var color:Number;
private function initPoints():void
{
color = 0;
for(var i:int=0; i<512; i++){
_pArr[i] = new Point();
}
}
private function playSoundMixer():void
{
_bg = new Bitmap();
_bg.bitmapData = new BitmapData(stage.stageWidth, stage.stageHeight );
addChild(_bg);
_stg = new Sprite();
_stg.x = stage.stageWidth/2;
_stg.y = stage.stageHeight/2;
addChild(_stg);
}
private function beatCheck2(e:Event):void
{
if(currentSong==null)
return;
SoundMixer.computeSpectrum(_bArr, false, 0); // byteArr(length=512), FFT, rate 0->44.1 KHz, 1->22.05KHz...
_bArr.position = 0;
var byteTotal:Number = 0; // 両音
var totalR:Number = 0; // 右パン
var totalL:Number = 0; // 左パン
var byte:Number = 0;
var sum:Number = 0;
for(var i:int = 0; i < 512; i++)
{
byte =_bArr.readFloat();
sum += byte;
byte = Math.abs(byte);
byteTotal += byte;
if(i<256) totalR += byte;
else totalL += byte;
if(byte>0.01)
{
Tweener.addTween( _pArr[i], {
x:Math.cos((i*360/512-90)*Math.PI/180)*400*(byte-0.005),
y:Math.sin((i*360/512-90)*Math.PI/180)*400*(byte-0.005),
time:0.2, transition:'easeOutQuad'
});
};
};
color+=sum/500;
_stg.graphics.clear();
_stg.graphics.lineStyle(0.5,0x000000);
_stg.graphics.beginFill(HSLtoRGB(1,color*360,1,(Math.sin(color)+1)*0.25+0.25));
_stg.graphics.moveTo(_pArr[0].x,_pArr[0].y);
for(var m:int=0; m<_pArr.length-1; m++){
var px:Number = (_pArr[m].x + _pArr[m+1].x)/2;
var py:Number = (_pArr[m].y + _pArr[m+1].y)/2;
_stg.graphics.curveTo(_pArr[m].x, _pArr[m].y, px, py);
}
_stg.graphics.lineTo(_pArr[_pArr.length-1].x, _pArr[_pArr.length-1].y );
_stg.graphics.lineTo(_pArr[0].x,_pArr[0].y);
//_stg.graphics.drawCircle(0,0,200);
_stg.graphics.endFill();
// 音の平均値
byteTotal /= 512;
// 左右パン平均値
totalR /= 256;
totalL /= 256;
if(byteTotal>0.1){
_bg.bitmapData.draw( stage);
}
_bg.bitmapData.colorTransform(_bg.bitmapData.rect,new ColorTransform(1,1,1,1,3,3,3));
}
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;
}
/* Error Handler */
//////////////////////////////////////////////////////////////////
private function errorHandler(e:IOErrorEvent):void
{
//MonsterDebugger.trace( 'Error...', e );
}
/* stage set */
//////////////////////////////////////////////////////////////////
private function setStage():void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, resizeEvent);
resizeHandler();
}
private function resizeEvent(e:Event = null):void
{
resizeHandler();
}
public function resizeHandler():void
{
}
}
}