Spectrum MP3 Player
Just a simple spectrum player that references MonsterCat's YouTube demo.
/**
* Copyright JLChnToZ ( http://wonderfl.net/user/JLChnToZ )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7ym6
*/
package {
import flash.display.*;
import flash.media.*;
import flash.geom.*;
import flash.net.*;
import flash.events.*;
import flash.utils.*;
import flash.ui.*;
import flash.text.*;
public class FlashTest extends Sprite {
var s:Sound;
var rectAnalysis:Shape;
var ba:ByteArray = new ByteArray();
var a:Array = new Array(512);
var barSize:Number = 10;
var trot:Number = Math.pow(2, 1/12);
var fr = new FileReference();
var textTitle:TextField;
var textInfo:TextField;
var textTitleFormat:TextFormat;
var textInfoFormat:TextFormat;
var colors:Array = new Array(3);
var sc:SoundChannel;
var lastUpdateTime:Number;
var gradientSettings:Object = {
fType: GradientType.LINEAR,
colors: [ 0, 0, 0, 0 ],
alphas: [ 0.8, 0.2, 0.4, 0.7 ],
ratios: [ 0, 170, 170, 255 ],
sprMethod: SpreadMethod.PAD,
matr: new Matrix()
};
function clamp(value:Number, min:Number, max:Number):Number {
return Math.min(Math.max(value, min), max);
}
function lerp(start:Number, end:Number, amount:Number):Number {
if(!start) start = 0;
if(!end) end = 0;
return start + (end - start) * amount;
}
function readSpectrum(e:Event) {
var i:Number, l:Number, t:Number, n:Number, m:Number = getTimer();
var w:Number = stage.stageWidth, h:Number = stage.stageHeight;
var f:Number = (m - lastUpdateTime) / 25, v:Number;
SoundMixer.computeSpectrum(ba, true, 2);
for(i = 0; i < 512; i++) {
v = ba.readFloat();
a[i] = v > a[i] ? v : lerp(a[i], v, clamp(0.1 * f, 0, 1));
}
rectAnalysis.graphics.clear();
for(i = 0; i < 3; i++) {
l = calcIndex((i - 1) / 4);
t = calcIndex(i / 4);
n = calcIndex((i + 1) / 4);
colors[i] = clamp(lerp(colors[i],
(calcValue(l, t, n, 0, false) + calcValue(l, t, n, 256, false)) / 48, 0.01 * f), 0, 0.9);
}
rectAnalysis.graphics.beginFill(calcColor(colors[2], colors[1], colors[0]));
rectAnalysis.graphics.drawRect(0, 0, w, h);
rectAnalysis.graphics.endFill();
rectAnalysis.graphics.beginFill(0xFFFFFF, 0.8);
for(i = 0; i < w - barSize; i += barSize * 1.5) {
l = calcIndex((i - 1) / w);
t = calcIndex(i / w);
n = calcIndex((i + 1) / w);
drawBar(i + barSize / 2, -(calcValue(l, t, n, 0, true) + 0.01), h);
drawBar(i + barSize / 2, (calcValue(l, t, n, 256, true) + 0.01) / 2, h);
}
rectAnalysis.graphics.endFill();
gradientSettings.matr.createGradientBox(w, h, Math.PI / 2);
rectAnalysis.graphics.beginGradientFill(gradientSettings.fType,
gradientSettings.colors, gradientSettings.alphas, gradientSettings.ratios,
gradientSettings.matr, gradientSettings.sprMethod);
rectAnalysis.graphics.drawRect(0, 0, w, h);
rectAnalysis.graphics.endFill();
lastUpdateTime = m;
}
function calcIndex(pos:Number):Number {
pos = Math.log(clamp(pos, 0, 1) + 1) / Math.LN2 / 2;
return clamp(pos * 256, 0, 255);
}
function calcValue(lastIndex:Number, thisIndex:Number, nextIndex:Number, offset:int, log:Boolean):Number {
var accu:Number = 0;
if(nextIndex - lastIndex > 2)
for(var j:int = Math.ceil(lastIndex + thisIndex / 2); j < Math.floor(nextIndex + thisIndex / 2); j++)
accu += a[j + offset];
else
accu = lerp(a[Math.floor(thisIndex) + offset],
a[Math.ceil(thisIndex) + offset], thisIndex - Math.floor(thisIndex)) * (nextIndex - lastIndex) * 2;
return log ? Math.sqrt(accu) : accu;
}
function calcColor(r:Number, g:Number, b:Number):uint {
return (Math.floor(clamp(r, 0, 1) * 255) << 16)
| (Math.floor(clamp(g, 0, 1) * 255) << 8)
| Math.floor(clamp(b, 0, 1) * 255);
}
function drawBar(x:Number, h:Number, sh:Number) {
rectAnalysis.graphics.drawRect(x,
((h < 0 ? -Math.abs(h) : 0)) / 3 * sh + 171 / 255 * sh,
barSize, Math.abs(h) * sh / 3);
}
function onLoadButtonClick(e:ContextMenuEvent) {
fr.browse([new FileFilter("MP3 Files (*.mp3)","*.mp3")]);
}
function onReplayClick(e:ContextMenuEvent) {
sc.stop();
if(s) sc = s.play(0);
}
function onStopClick(e:ContextMenuEvent) {
sc.stop();
}
function onFileSelected(e:Event) {
fr.load();
}
function onFileLoad(e:Event) {
var f:FileReference = e.target as FileReference;
var data:ByteArray = f.data;
textTitle.text = "Unknown Artist - Unknown Song";
textInfo.text = "";
s = new Sound();
s.addEventListener(Event.ID3, onID3Loaded);
s.loadCompressedDataFromByteArray(data, data.length);
sc.stop();
sc = s.play();
}
function onID3Loaded(e:Event) {
textTitle.text = s.id3.artist + " - " + s.id3.songName;
textInfo.text = s.id3.album;
onStageResize(e);
}
function onStageResize(e:Event) {
var w:Number = stage.stageWidth, h:Number = stage.stageHeight;
textTitle.x = w / 8;
textInfo.x = w / 8;
textTitle.y = h / 4;
textTitleFormat = textTitle.getTextFormat();
textTitleFormat.size = Math.floor((w + h) / 48);
textTitle.setTextFormat(textTitleFormat);
textInfoFormat = textInfo.getTextFormat();
textInfoFormat.size = int(Math.floor((w + h) / 96));
textInfo.setTextFormat(textInfoFormat);
textInfo.y = h / 4 + textTitleFormat.size + 5;
}
public function FlashTest() {
stage.scaleMode = "noScale";
stage.align = "TL";
sc = new SoundChannel();
var my_menu = new ContextMenu();
my_menu.hideBuiltInItems();
var loadFileMenuItem = new ContextMenuItem("Load File...");
loadFileMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onLoadButtonClick);
my_menu.customItems.push(loadFileMenuItem);
var replayMenuItem = new ContextMenuItem("Replay");
replayMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onReplayClick);
my_menu.customItems.push(replayMenuItem);
var stopMenuItem = new ContextMenuItem("Stop");
stopMenuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onStopClick);
my_menu.customItems.push(stopMenuItem);
rectAnalysis = new Shape();
addChild(rectAnalysis);
textTitle = new TextField();
textTitle.autoSize = "left";
textTitle.textColor = 0xFFFFFF;
textTitleFormat = new TextFormat();
textTitle.defaultTextFormat = textTitleFormat;
textTitle.text = "Please right click to select a mp3 file.";
addChild(textTitle);
textInfo = new TextField();
textInfo.autoSize = "left";
textInfo.textColor = 0xFFFFFF;
textInfoFormat = new TextFormat();
textInfo.defaultTextFormat = textInfoFormat;
textInfo.text = "";
addChild(textInfo);
lastUpdateTime = getTimer();
this.addEventListener(Event.ENTER_FRAME, readSpectrum);
stage.addEventListener(Event.RESIZE, onStageResize);
fr.addEventListener(Event.SELECT, onFileSelected);
fr.addEventListener(Event.COMPLETE, onFileLoad);
contextMenu = my_menu;
onStageResize(null);
}
}
}