Sound spectrum
Happily enough, I managed to solve the problems I had! That gave me a reason to change the title from the original: "spectrum failure...at least we've got polka!". ;)
/**
* Copyright antalg ( http://wonderfl.net/user/antalg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/k3nz
*/
package
{
import flash.utils.Timer;
import flash.display.Graphics;
import flash.display.SimpleButton;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.events.TimerEvent;
import flash.geom.Rectangle;
import flash.media.*;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.net.URLRequest;
import flash.display.Sprite;
import flash.system.System;
import flash.text.*;
import flash.ui.Mouse;
import flash.utils.ByteArray;
import com.greensock.TweenLite;
import com.greensock.easing.*;
import net.hires.debug.Stats;
[SWF(backgroundColor = 0, frameRate = 60)]
public class FlashTest extends Sprite
{
private var sound :Sound = new Sound();
private var browseBtn :SimpleButton;
private var pauseBtn :SimpleButton;
private var revBtn :SimpleButton;
private var sC :SoundChannel = new SoundChannel();
private var lenstr :String;
private var curPos :Number = 0;
private var paused :Boolean = false;
private var num :TextField;
private var timeTxt :TextField;
private var urlTxt :TextField;
private var progressTxt :TextField;
private var bA :ByteArray;
private var leftVals :Vector.<Number> = new Vector.<Number>(256, true);
private var rightVals :Vector.<Number> = new Vector.<Number>(256, true);
private var lastPos :Number = 0;
// Parameters //
private var btnAlpha :Number = 0.5;
private var sColor :uint = 0xD4D0C8;
private var btnColor :uint = 0xD5FF73;
private var specColor1 :uint = 0xD5FF73;
private var specColor2 :uint = 0x6897BB;
private var fill :Boolean = false;
private var spectrum :int = 1;
// 1: Regular
// 2: Vertical lines
// 3: Circles
private var specX :int = 1;
private var specY :int = 300; // 275
private var specAmp :int = 150; // 80
private var specSc :int = 2; // 1 is normal size
private var wdt :int = 8;
private var radSc :Number = 1.02; // scale is inverse proportional e.g. 2 is double the size of 4
private var peekDistance :int = 256; // 256
////////////////
public function FlashTest()
{
addChild(new Stats());
//stage.addEventListener(Event.ENTER_FRAME, draw);
var timer:Timer = new Timer(10);
timer.addEventListener(TimerEvent.TIMER, draw);
timer.start();
// Textfields //
var format:TextFormat = new TextFormat("Courier");
timeTxt = new TextField();
timeTxt.selectable = false;
timeTxt.textColor = sColor
timeTxt.width = 140;
timeTxt.defaultTextFormat = format;
addChild(timeTxt);
timeTxt.x = 20;
timeTxt.y = 120;
timeTxt.text = "00:00 / 00:00";
num = new TextField();
num.textColor = sColor
num.type = TextFieldType.INPUT;
num.x = 120;
num.y = 149;
num.text = String(1);
addChild(num);
urlTxt = new TextField();
urlTxt.type = TextFieldType.INPUT;
urlTxt.border = true;
urlTxt.borderColor = 0x777777;
urlTxt.textColor = sColor;
addChild(urlTxt);
urlTxt.text = //"URL goes here!";
"http://music.incompetech.com/royaltyfree2/Pulse%20Rock.mp3";
//"http://music.incompetech.com/royaltyfree2/Pixel%20Peeker%20Polka%20-%20faster.mp3";
//"http://www.danosongs.com/music/danosongs.com-climb-to-elara.mp3";
urlTxt.x = 140;
urlTxt.y = 120;
urlTxt.width = 300;
urlTxt.height = urlTxt.textHeight+5;
progressTxt = new TextField();
progressTxt.textColor = sColor;
addChild(progressTxt);
progressTxt.x = 270;
progressTxt.y = 145;
progressTxt.width = 40;
progressTxt.height = 20;
////////////////
// Browse button //
var spr1:Sprite = new Sprite();
spr1.graphics.beginFill(btnColor);
spr1.graphics.drawRect(0, 0, 16, 16);
spr1.graphics.endFill();
var spr2:Sprite = new Sprite();
spr2.graphics.beginFill(btnColor, btnAlpha);
spr2.graphics.drawRect(0, 0, 16, 16);
spr2.graphics.endFill();
browseBtn = new SimpleButton(spr1, spr1, spr2, spr1);
stage.addChild(browseBtn);
browseBtn.x = 20;
browseBtn.y = 150;
browseBtn.addEventListener(MouseEvent.CLICK, load); //browse
///////////////////
// Play button //
spr1 = new Sprite();
spr1.graphics.beginFill(btnColor);
spr1.graphics.moveTo(0, 0);
spr1.graphics.lineTo(0, 16);
spr1.graphics.lineTo(16, 8);
spr1.graphics.endFill();
spr2 = new Sprite();
spr2.graphics.beginFill(btnColor, btnAlpha);
spr2.graphics.moveTo(0, 0);
spr2.graphics.lineTo(0, 16);
spr2.graphics.lineTo(16, 8);
spr2.graphics.endFill();
pauseBtn = new SimpleButton(spr1, spr1, spr2, spr1);
stage.addChild(pauseBtn);
pauseBtn.x = 50;
pauseBtn.y = 150;
pauseBtn.addEventListener(MouseEvent.CLICK, pause);
/////////////////
// Rev button //
spr1 = new Sprite();
spr1.graphics.beginFill(btnColor);
spr1.graphics.moveTo(0, 8);
spr1.graphics.lineTo(8, 0);
spr1.graphics.lineTo(8, 8);
spr1.graphics.lineTo(16, 0);
spr1.graphics.lineTo(16, 16);
spr1.graphics.lineTo(8, 8);
spr1.graphics.lineTo(8, 16);
spr1.graphics.endFill();
spr2 = new Sprite();
spr2.graphics.beginFill(btnColor, btnAlpha);
spr2.graphics.moveTo(0, 8);
spr2.graphics.lineTo(8, 0);
spr2.graphics.lineTo(8, 8);
spr2.graphics.lineTo(16, 0);
spr2.graphics.lineTo(16, 16);
spr2.graphics.lineTo(8, 8);
spr2.graphics.lineTo(8, 16);
spr2.graphics.endFill();
revBtn = new SimpleButton(spr1, spr1, spr2, spr1);
stage.addChild(revBtn);
revBtn.x = 80;
revBtn.y = 150;
revBtn.addEventListener(MouseEvent.CLICK, rev);
/////////////////
}
private function load(e:MouseEvent):void
{
//stage.removeEventListener(Event.ENTER_FRAME, draw);
sound = new Sound();
sC.stop();
sound.load(new URLRequest(urlTxt.text));
sound.addEventListener(Event.COMPLETE, playIt);
addEventListener(Event.ENTER_FRAME, progress);
}
private function progress(e:Event):void {
progressTxt.text = int(sound.bytesLoaded*100/sound.bytesTotal)+"%";
}
private function playIt(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, progress);
progressTxt.text = "";
paused = false;
bA = new ByteArray();
sound.extract(bA, int(2*sound.length*44.1));
//stage.addEventListener(Event.ENTER_FRAME, draw);
stage.addEventListener(Event.ENTER_FRAME, time);
sound.removeEventListener(Event.COMPLETE, playIt);
sC = sound.play();
var s:int;
var m:int;
s = sound.length / 1000;
m = s / 60;
s -= m * 60;
lenstr = ((m<10)?("0"+m):m) + ":" + ((s<10)?("0"+s):s);
}
private function draw(e:TimerEvent):void //e:Event):void
{
this.graphics.clear();
var g:Graphics = this.graphics;
bA.position = int(2*(sC.position)*44.1);
for (i = 0; i < peekDistance; i++) {
leftVals[i] = bA.readFloat();
rightVals[i] = bA.readFloat();
}
spectrum = int(num.text);
if(spectrum == 1) {
if (fill)
{
g.lineStyle(1, specColor1,0.5);
g.beginFill(specColor1,0.25);
g.moveTo(specX, specY);
for (var i:int = 0; i < peekDistance; i++) {
g.lineTo((specSc*i), specY-leftVals[i]*specAmp);
}
g.lineTo(788+specX, specY)
g.endFill();
g.lineStyle(1, specColor2, 0.5);
g.beginFill(specColor2, 0.25);
g.moveTo(specX, specY);
for (i = 0; i < peekDistance; i++) {
g.lineTo((specSc*i)+specX, specY-rightVals[i]*specAmp);
}
g.lineTo(788+specX, specY)
g.endFill();
}
else
{
g.lineStyle(1, specColor1,0.5);
g.moveTo(specX, specY-leftVals[0]*specAmp);
for (i = 1; i < peekDistance; i++) {
g.lineTo((specSc*i)+specX, specY-leftVals[i]*specAmp);
}
g.lineStyle(1, specColor2, 0.5);
g.moveTo(specX, specY-rightVals[0]*specAmp);
for (i = 1; i < peekDistance; i++) {
g.lineTo((specSc*i)+specX, specY-rightVals[i]*specAmp);
}
}
}
else if(spectrum == 2)
{
for (i = 0; i < peekDistance; i++) {
g.lineStyle(1, specColor1, 0.5);
g.moveTo((specSc * i) + specX, specY - specAmp * leftVals[i]);
g.lineTo((specSc * i) + specX, specY + specAmp * leftVals[i]);
}
for (i = 0; i < peekDistance; i++) {
g.lineStyle(1, specColor2, 0.5);
g.moveTo(specSc*i + 20 + specX, specY - specAmp * rightVals[i]);
g.lineTo(specSc*i + 20 + specX, specY + specAmp * rightVals[i]);
}
}
else if(spectrum == 3)
{
var maxRad:Number = (peekDistance - peekDistance % wdt) / (2*radSc); // pD - 1?
for (i = wdt; i < peekDistance; i+=wdt) {
g.lineStyle(3 * wdt * leftVals[i], specColor1, leftVals[i]);
g.drawCircle((maxRad+specX)/radSc, specY, i/(2*radSc));
g.lineStyle(3 * wdt*rightVals[i], specColor2, rightVals[i]);
g.drawCircle((3*maxRad+specX+20)/radSc, specY, i/(2*radSc));
}
}
}
private function time(e:Event):void
{
var s:int;
var m:int;
s = sC.position / 1000;
m = s / 60;
s -= m * 60;
var time:String = ((m < 10)?("0" + m):m) + ":" + ((s < 10)?("0" + s):s);
timeTxt.text = time + " / " + lenstr;
}
private function pause(e:MouseEvent):void
{
if (!paused)
{
stage.removeEventListener(Event.ENTER_FRAME, draw);
stage.removeEventListener(Event.ENTER_FRAME, time);
curPos = sC.position;
sC.stop();
paused = true;
}
else
{
stage.addEventListener(Event.ENTER_FRAME, draw);
stage.addEventListener(Event.ENTER_FRAME, time);
sC = sound.play(curPos);
paused = false;
}
}
private function rev(e:MouseEvent):void
{
if (paused) {
curPos = 0;
pause(new MouseEvent(MouseEvent.CLICK));
} else {
sC.stop();
sC = sound.play();
}
}
}
}