topical media & game development
#graphic-flex-sound-visualisation-com-fusiox-ui-Visualization.ax
#graphic-flex-sound-visualisation-com-fusiox-ui-Visualization.ax
[swf]
[flash]
flex
package {
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import flash.events.Event;
import flash.geom.Rectangle;
import mx.core.UIComponent;
import mx.containers.Canvas;
import flash.display.Bitmap;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import flash.ui.ContextMenuBuiltInItems;
import flash.ui.ContextMenuItem;
import flash.ui.ContextMenu;
import flash.events.ContextMenuEvent;
import flash.geom.Point;
[Event("afterVisualization")]
[Event("beforeVisualization")]
[Style(name="audioLineColor",type="Number",format="Color",inherit="no")]
[Style(name="audioFillColor",type="Number",format="Color",inherit="no")]
public class @ax-graphic-flex-sound-visualisation-com-fusiox-ui-Visualization extends UIComponent {
public var type:String = "line"; // line, wave, bars
public var channel:String="mono"; // mono, left, right, stereo
public var bars:uint = 256;
private var _audioLineColor:uint = 0x000000;
private var _audioFillColor:uint = 0x000000;
//private var min:uint = 0;
//private var max:uint = 255;
private var gain:uint = 1;
private var myContextMenu:ContextMenu;
private var display:UIComponent = new UIComponent();
public var bitmapData:BitmapData = new BitmapData(1, 1, true, 0x00000000);
public var bitmap:Bitmap = new Bitmap(bitmapData);
private var spectrumData:ByteArray = new ByteArray();
private var rc:Number = 0; // relativeCenter
private var rp:Number = 0; // relativePixel
public var peak:Number = 0;
public function @ax-graphic-flex-sound-visualisation-com-fusiox-ui-Visualization() {
addEventListener(Event.ENTER_FRAME, enterFrameListener);
myContextMenu = new ContextMenu();
myContextMenu.hideBuiltInItems();
var defaultItems:ContextMenuBuiltInItems = myContextMenu.builtInItems;
defaultItems.print = true;
var item1:ContextMenuItem = new ContextMenuItem("Line");
var item2:ContextMenuItem = new ContextMenuItem("Wave");
var item3:ContextMenuItem = new ContextMenuItem("Bars");
myContextMenu.customItems.push(item1);
myContextMenu.customItems.push(item2);
myContextMenu.customItems.push(item3);
myContextMenu.customItems.push(item3);
item1.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
item2.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
item3.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuItemSelectHandler);
this.contextMenu = myContextMenu;
}
private function menuItemSelectHandler(event:ContextMenuEvent):void {
//trace("menuItemSelectHandler: " + event);
setType(event.target.caption);
}
private function setType( t:String ):void {
type = t.toLowerCase();
}
override protected function createChildren():void {
//display.addChild(bitmap);
addChild(bitmap);
}
override protected function updateDisplayList(w:Number, h:Number):void {
super.updateDisplayList(w, h);
var bt:uint = getStyle("borderThickness")*2;
if(w-bt>0 && h-bt>1) {bitmapData = new BitmapData(w-bt, h-bt, true, 0x0);}
bitmap.bitmapData = bitmapData;
_audioLineColor = getStyle("audioLineColor");
_audioFillColor = getStyle("audioFillColor");
// convenience variables to skip useless calls to getters
rc = (h-bt)/2;
rp = (w-bt)/256;
}
private function enterFrameListener(e:Event):void {
var rect:Rectangle = bitmapData.rect
SoundMixer.computeSpectrum(spectrumData, type=="bars", 0);
dispatchEvent( new Event("beforeVisualization",true) );
if(!hasEventListener( "beforeVisualization" )) { bitmapData.fillRect( rect, 0x0); }
switch (channel) {
case "mono":
toMono();
case "left":
if(type=="line" || type=="wave") { drawWave(1); }
if(type=="wave") {
spectrumData.position=0;
drawWave(-1);
}
if(type=="bars") {
drawEQ();
}
break;
case "right":
for (var i:int = 0; i < 256 ; i++) {spectrumData.readFloat();} // using spectrumData.position yields poor results
if(type=="line" || type=="wave") { drawWave(1); }
if(type=="wave") {
spectrumData.position=0;
for (var i:int = 0; i < 256 ; i++) {spectrumData.readFloat();}
drawWave(-1);
}
if(type=="bars") {
drawEQ();
}
break;
case "stereo":
if(type=="line" || type=="wave") {
drawWave(1);
drawWave(1);
}
if(type=="wave") {
spectrumData.position=0;
drawWave(-1);
drawWave(-1);
}
if(type=="bars") {
drawEQ();
drawEQ();
}
break;
}
bitmapData.applyFilter( bitmapData, rect, new Point(0,0), new BlurFilter(bitmapData.width/256,bitmapData.width/256,1));
dispatchEvent( new Event("afterVisualization",true) );
}
private function toMono():void {
spectrumData.position = 0;
if(spectrumData.length==2048) {
var leftData:ByteArray = new ByteArray();
var rightData:ByteArray = new ByteArray();
spectrumData.readBytes(leftData, 0, 1024);
spectrumData.readBytes(rightData, 0, 1024);
spectrumData = new ByteArray();
for (var i:uint = 0; i < 256 ; i++) {
spectrumData.writeFloat((leftData.readFloat()+rightData.readFloat())/2);
}
spectrumData.position = 0;
}
}
/*
private function narrowEQ():void {
var tempData:ByteArray = new ByteArray();
spectrumData.readBytes(tempData, 0, 1024);
spectrumData = new ByteArray();
var n:Number = 0;
if(min>=max) {
max=255;
min=0;
}
for (var i:uint = 0; i < min; i++) { n = tempData.readFloat(); } // gets to min
for (var i:uint = 0; i <= max-min; i++) {
n = tempData.readFloat()
for (var j:uint = 0; j < Math.floor(255/max-min+1); j++) {
spectrumData.writeFloat(n);
}
}
spectrumData.position = 0;
}
*/
private function drawWave(modifier:Number=1):void {
var v:Number;
var lastv:Number = rc;
peak = 0;
for (var i:uint = 0; i < 256; i++) {
var rf:Number = spectrumData.readFloat();
v = rc+rf*rc*modifier*-1;
if(type=="wave"){bitmapData.fillRect( new Rectangle(i*rp, Math.min(v,rc), rp, Math.abs(rc-v)), 0xFF000000 | _audioFillColor );}
bitmapData.fillRect( new Rectangle(i*rp, v, rp, 1+Math.abs(lastv-v)), 0xFF000000 | _audioLineColor );
lastv=v;
if(Math.abs(rf)>peak) { peak = Math.abs(rf); }
}
}
private function drawEQ():void {
//narrowEQ();
var v:Number;
var n:Number = 0;
var nrp:Number = rp*256/bars;
for (var i:uint = 0; i < bars; i++) {
n = 0;
for (var j:uint = 0; j < Math.floor(256/bars) ; j++) {
n += spectrumData.readFloat();
if(Math.abs(n)>peak) { peak = Math.abs(n); }
}
n = n/Math.floor(256/bars)
v = Math.max(rc*2-n*rc*2*gain,5);
bitmapData.fillRect( new Rectangle(nrp/8+i*nrp, v, nrp/2+nrp/4, rc*2-v), 0xFF000000 | _audioFillColor);
bitmapData.fillRect( new Rectangle(nrp/8+i*nrp, v, nrp/2+nrp/4, 1), 0xFF000000 | _audioLineColor );
}
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.