fire test
// forked from makc3d's FUCK YEAH RADIO!!!1
package {
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.media.*;
import flash.system.*;
import flash.net.*;
import flash.utils.*;
[SWF(width=465, height=465, backgroundColor=0x0, frameRate=30)]
// ripped off http://wonderfl.net/c/rolo :)
public class Fire extends Sprite {
private var sound:Sound;
private var channel:SoundChannel;
private var bytes:ByteArray;
private var samples:Array;
private var fft:FastFourierTransform;
private static const ZERO_POINT:Point = new Point();
private var _fireColor:BitmapData;
private var _currentFireColor:int;
private var _canvas:Sprite;
private var _grey:BitmapData;
private var _spread:ConvolutionFilter;
private var _cooling:BitmapData;
private var _color:ColorMatrixFilter;
private var _offset:Array;
private var _fire:BitmapData;
private var _palette:Array;
private var _zeroArray:Array;
public function Fire() {
this.stage.scaleMode = StageScaleMode.NO_SCALE;
this.stage.quality = StageQuality.LOW;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this._onLoaded);
loader.load(new URLRequest('http://saqoo.sh/a/labs/Moyasu/srcview/source/fire-color.png'), new LoaderContext(true));
}
private function _onLoaded(e:Event):void {
this._fireColor = Bitmap(LoaderInfo(e.target).loader.content).bitmapData;
this._canvas = new Sprite();
this._grey = new BitmapData(465, 465, false, 0x0);
this._spread = new ConvolutionFilter(3, 3, [0, 1, 0, 1, 1, 1, 0, 1, 0], 5);
this._cooling = new BitmapData(465, 465, false, 0x0);
this._offset = [new Point(), new Point()];
this._fire = new BitmapData(465, 465, false, 0x0);
this.addChild(new Bitmap(this._fire));
this._createCooling(0.16);
this._createPalette(this._currentFireColor = 0);
this.addEventListener(Event.ENTER_FRAME, this._update);
this.stage.addEventListener (MouseEvent.CLICK, this._onClick);
bytes = new ByteArray; samples = new Array; fft = new FastFourierTransform;
for (var i:int = 0; i < 1024; i++) samples [i] = 0;
sound = new Sound;
sound.load (new URLRequest ('http://filth.tisys.org:8000/deathfm'));
channel = sound.play ();
}
private function _onClick(e:MouseEvent):void {
if (++this._currentFireColor == int(this._fireColor.height / 32)) {
this._currentFireColor = 0;
}
this._createPalette(this._currentFireColor);
}
private function _createCooling(a:Number):void {
this._color = new ColorMatrixFilter([
a, 0, 0, 0, 0,
0, a, 0, 0, 0,
0, 0, a, 0, 0,
0, 0, 0, 1, 0
]);
}
private function _createPalette(idx:int):void {
this._palette = [];
this._zeroArray = [];
for (var i:int = 0; i < 256; i++) {
this._palette.push(this._fireColor.getPixel(i, idx * 32));
this._zeroArray.push(0);
}
}
private function _update(e:Event):void {
// get bytes of 1024 samples
bytes.position = 0;
if (sound.extract (bytes, 1024, channel.position * 44.1) < 1024) {
// ??
//return;
}
// get samples of left channel
bytes.position = 0;
while (bytes.bytesAvailable > 0) {
samples [int (bytes.position / 8)] = bytes.readFloat (); bytes.readFloat ();
}
// analyze samples
fft.analyze (samples);
// fft.magnitudes contain full spectrum, we want 1st 5KHz
var limitHz:Number = 5000;
var i:int, n:int = fft.magnitudes.length * limitHz / (44100 / 2), w:int = 465 / n;
// draw spectrum
this._canvas.graphics.clear ();
this._canvas.graphics.beginFill(0x0, 0);
this._canvas.graphics.drawRect(0, 0, 465, 465);
this._canvas.graphics.endFill();
this._canvas.graphics.lineStyle ();
this._canvas.graphics.beginFill (0xFFFFFF);
for (i = 0; i < n; i++) {
var h:int = 400 * fft.magnitudes [i];
this._canvas.graphics.drawRect (w*i, 465 - h, w, h);
}
this._canvas.graphics.endFill ();
this._grey.draw(this._canvas);
this._grey.applyFilter(this._grey, this._grey.rect, ZERO_POINT, this._spread);
this._cooling.perlinNoise(50, 50, 2, 982374, false, false, 0, true, this._offset);
this._offset[0].x += 2.0;
this._offset[1].y += 2.0;
this._cooling.applyFilter(this._cooling, this._cooling.rect, ZERO_POINT, this._color);
this._grey.draw(this._cooling, null, null, BlendMode.SUBTRACT);
this._grey.scroll(0, -3);
this._fire.paletteMap(this._grey, this._grey.rect, ZERO_POINT, this._palette, this._zeroArray, this._zeroArray, this._zeroArray);
}
}
}
/**
* Port of java FFT class.
* @author Dr Iain A Robin iain@xunil.uklinux.net
* @see http://www.dsptutor.freeuk.com/analyser/SpectrumAnalyser.html
*/
class FastFourierTransform {
/**
* Magnitudes (corresponding frequency ranges from 0 to half of sampling frequency).
*/
public var magnitudes:Array = [];
/**
* Analyzes samples and fills <code>magnitudes</code> array.
* @param samples Array of numbers to analyze (length must be power of 2).
*/
public function analyze (samples:Array):void {
// minimal sanity check
if ((samples == null) || (samples.length < 2)) {
magnitudes.length = 0; return;
}
// find power of 2 not exceeding samles length
var n:int = 2; while (n * 2 <= samples.length) n *= 2;
// transform samples
var n2:int = n >> 1;
nu = int (Math.log (n) * Math.LOG2E);
var nu1:int = nu - 1;
var tr:Number, ti:Number, p:Number, arg:Number, c:Number, s:Number;
var i:int, k:int = 0;
for (i = 0; i < n; i++) {
xre [i] = samples [i]; xim [i] = 0.0;
}
for (var l:int = 1; l <= nu; l++) {
while (k < n) {
for (i = 1; i <= n2; i++) {
p = bitrev (k >> nu1);
arg = 2 * Math.PI * p / n;
c = Math.cos (arg);
s = Math.sin (arg);
tr = xre [k + n2] * c + xim [k + n2] * s;
ti = xim [k + n2] * c - xre [k + n2] * s;
xre [k + n2] = xre [k] - tr;
xim [k + n2] = xim [k] - ti;
xre [k] += tr;
xim [k] += ti;
k++;
}
k += n2;
}
k = 0;
nu1--;
n2 = n2 >> 1;
}
k = 0;
var r:int;
while (k < n) {
r = bitrev (k);
if (r > k) {
tr = xre [k];
ti = xim [k];
xre [k] = xre [r];
xim [k] = xim [r];
xre [r] = tr;
xim [r] = ti;
}
k++;
}
n2 = n >> 1;
var n2i:Number = 2 / n, xr:Number, xi:Number;
for (i = 0; i < n2; i++) {
xr = xre [i]; xi = xim [i];
magnitudes [i] = Math.sqrt (xr * xr + xi * xi) * n2i;
}
magnitudes [0] *= 0.5;
magnitudes.length = n2;
}
private var xre:Array = [];
private var xim:Array = [];
private var nu:int;
private function bitrev (j:int):int {
var j2:int;
var j1:int = j;
var k:int = 0;
for (var i:int = 1; i <= nu; i++) {
j2 = j1 >> 1;
k = 2 * k + j1 - 2 * j2;
j1 = j2;
}
return k;
}
}