Holy crap this is brilliant. and simple. I don't know how I didn't think of just doing this before - awesome! haha thanks! =)
Embed
/**
* Copyright architectural.synthesis ( http://wonderfl.net/user/architectural.synthesis )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/bt7C
*/
// Howto:
// 1. cut and paste everything bellow the "WONDERFL TRACE" line to the end of your script
// 2. insert inittrace(stage); to the constructor of your main class
// 3. done!
package {
import flash.display.Sprite;
import flash.events.*;
import flash.text.TextField;
public class TraceTest extends Sprite {
public function TraceTest() {
//This is all the initialization you need in your main class
inittrace(stage);
// demonstration
trace(Math.atan2(1000,0))
}
}
}
import __AS3__.vec.Vector;
///// FFT /////
class FFT
{
public static const FORWARD:Boolean = false;
public static const INVERSE:Boolean = true;
private var m_logN:uint = 0; // log2 of FFT size
private var m_N:uint = 0; // FFT size
private var m_invN:Number; // Inverse of FFT length
// Bit-reverse lookup table
private var m_bitRevLen:uint; // Length of the bit reverse table
private var m_bitRevFrom:Vector.<uint>; // "From" indices for swap
private var m_bitRevTo:Vector.<uint>; // "To" indices for swap
/**
*
*/
public function FFT()
{
}
/**
* Initialize class to perform FFT of specified size.
*
* @param logN Log2 of FFT length. e.g. for 512 pt FFT, logN = 9.
*/
public function init(
logN:uint ):void
{
m_logN = logN
m_N = 1 << m_logN;
m_invN = 1.0/m_N;
// Create the bit-reverse table
m_bitRevFrom = new Vector.<uint>;
m_bitRevTo = new Vector.<uint>;
for ( var k:uint = 0; k < m_N; k++ )
{
var kRev:uint = BitReverse(k,logN);
if (kRev > k)
{
m_bitRevFrom.push(k);
m_bitRevTo.push(kRev);
}
}
m_bitRevLen = m_bitRevFrom.length;
}
/**
* Performs in-place complex FFT.
*
* @param xRe Real part of input/output
* @param xIm Imaginary part of input/output
* @param inverse If true (INVERSE), do an inverse FFT
*/
public function run(
xRe:Vector.<Number>,
xIm:Vector.<Number>,
inverse:Boolean = false ):void
{
var numFlies:uint = m_N >> 1; // Number of butterflies per sub-FFT
var span:uint = m_N >> 1; // Width of the butterfly
var spacing:uint = m_N; // Distance between start of sub-FFTs
var wIndexStep:uint = 1; // Increment for twiddle table index
// For each stage of the FFT
for ( var stage:uint = 0; stage < m_logN; ++stage )
{
// Compute a multiplier factor for the "twiddle factors".
// The twiddle factors are complex unit vectors spaced at
// regular angular intervals. The angle by which the twiddle
// factor advances depends on the FFT stage. In many FFT
// implementations the twiddle factors are cached, but because
// vector lookup is relatively slow in ActionScript, it's just
// as fast to compute them on the fly.
var wAngleInc:Number = wIndexStep * 2.0*Math.PI/m_N;
if ( inverse == false ) // Corrected 3 Aug 2011. Previously this condition was backwards!
wAngleInc *= -1;
var wMulRe:Number = Math.cos(wAngleInc);
var wMulIm:Number = Math.sin(wAngleInc);
for ( var start:uint = 0; start < m_N; start += spacing )
{
var top:uint = start;
var bottom:uint = top + span;
var wRe:Number = 1.0;
var wIm:Number = 0.0;
// For each butterfly in this stage
for ( var flyCount:uint = 0; flyCount < numFlies; ++flyCount )
{
// Get the top & bottom values
var xTopRe:Number = xRe[top];
var xTopIm:Number = xIm[top];
var xBotRe:Number = xRe[bottom];
var xBotIm:Number = xIm[bottom];
// Top branch of butterfly has addition
xRe[top] = xTopRe + xBotRe;
xIm[top] = xTopIm + xBotIm;
// Bottom branch of butterly has subtraction,
// followed by multiplication by twiddle factor
xBotRe = xTopRe - xBotRe;
xBotIm = xTopIm - xBotIm;
xRe[bottom] = xBotRe*wRe - xBotIm*wIm;
xIm[bottom] = xBotRe*wIm + xBotIm*wRe;
// Update indices to the top & bottom of the butterfly
++top;
++bottom;
// Update the twiddle factor, via complex multiply
// by unit vector with the appropriate angle
// (wRe + j wIm) = (wRe + j wIm) x (wMulRe + j wMulIm)
var tRe:Number = wRe;
wRe = wRe*wMulRe - wIm*wMulIm;
wIm = tRe*wMulIm + wIm*wMulRe
}
}
numFlies >>= 1; // Divide by 2 by right shift
span >>= 1;
spacing >>= 1;
wIndexStep <<= 1; // Multiply by 2 by left shift
}
// The algorithm leaves the result in a scrambled order.
// Do bit-reversal to unscramble the result.
for ( var k:uint = 0; k < m_bitRevLen; k++ )
{
var brFr:uint = m_bitRevFrom[k];
var brTo:uint = m_bitRevTo[k];
var tempRe:Number = xRe[brTo];
var tempIm:Number = xIm[brTo];
xRe[brTo] = xRe[brFr];
xIm[brTo] = xIm[brFr];
xRe[brFr] = tempRe;
xIm[brFr] = tempIm;
}
// Divide everything by n for inverse
if ( inverse )
{
for ( k = 0; k < m_N; k++ )
{
xRe[k] *= m_invN;
xIm[k] *= m_invN;
}
}
}
/**
* Do bit reversal of specified number of places of an int
* For example, 1101 bit-reversed is 1011
*
* @param x Number to be bit-reverse.
* @param numBits Number of bits in the number.
*/
private function BitReverse(
x:uint,
numBits:uint):uint
{
var y:uint = 0;
for ( var i:uint = 0; i < numBits; i++)
{
y <<= 1;
y |= x & 0x0001;
x >>= 1;
}
return y;
}
}
///// WONDERFL TRACE /////
import flash.display.Sprite;
import flash.display.Stage;
import flash.text.TextField;
import flash.text.TextFormat;
function inittrace(s:Stage):void
{
WTrace.initTrace(s);
}
//global trace function
var trace:Function;
//wtreace class
class WTrace
{
private static var FONT:String = "Fixedsys";
private static var SIZE:Number = 12;
private static var TextFields:Array = [];
private static var trace_stage:Stage;
public static function initTrace(stg:Stage):void
{
trace_stage = stg;
trace = wtrace;
}
private static function scrollup():void
{
// maximum number of lines: 100
if (TextFields.length > 100)
{
var removeme:TextField = TextFields.shift();
trace_stage.removeChild(removeme);
removeme = null;
}
for(var x:Number=0;x<TextFields.length;x++)
{
(TextFields[x] as TextField).y -= SIZE*1.2;
}
}
public static function wtrace(... args):void
{
var s:String="";
var tracefield:TextField;
for (var i:int;i < args.length;i++)
{
// imitating flash:
// putting a space between the parameters
if (i != 0) s+=" ";
s+=args[i].toString();
}
tracefield= new TextField();
tracefield.autoSize = "left";
tracefield.text = s;
tracefield.y = trace_stage.stageHeight - 20;
var tf:TextFormat = new TextFormat(FONT, SIZE);
tracefield.setTextFormat(tf);
trace_stage.addChild(tracefield);
scrollup();
TextFields.push(tracefield);
}
}