Firebird – a sound visualization
The other day I stumbled upon a minimalistic music video by Peter Gabriel called Der Rhythmus der Hitze. As I’ve never had the chance to experiment with the Spectrum-functionality in AS3 I thought this would be a perfect first example as I found the birdlike visuals were quite nice and mesmerizing. Here’s the result.
{
import flash.display.GradientType;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import se.xcom.math.DegreesVector;
public class Firebird extends Sprite
{
private const BAR_WIDTH:int = 1;
private var ba:ByteArray;
private var matrix:Matrix;
private var degrees:DegreesVector;
private var counter:int;
private var aColours:Array;
public function Firebird()
{
super();
counter = 0;
aColours = [0xFFFFFF,0xFFFF33,0xFF2200,0xFF0000];
ba = new ByteArray();
matrix = new Matrix();
degrees = new DegreesVector();
this.filters = [new GlowFilter(0xFF2211,1,20,30,3,2)];
this.addEventListener(Event.ENTER_FRAME,onFrameTick);
}
private function onFrameTick(e:Event)
{
var enhance:Number
var barHeight:Number
var posY:Number
// get new ByteArray from soundmixer
SoundMixer.computeSpectrum(ba,true);
// setting up gradientcolours. Using the aColours gives us the flexibility
// to switch between different colours in the future if we would like to.
var gradientColours:Array = [aColours[3], aColours[2], aColours[1], aColours[0], aColours[1], aColours[2], aColours[3]];
with(graphics)
{
clear();
for (var i:int=0; i<256; i+=BAR_WIDTH)
{
// enhance largen the shape towards the middle. The first 60 bars will be enhanced
// (simply to create the birdhead)
enhance = 60-i;
enhance = (enhance <0)?0:enhance;
// now the bar is moved in Y-axis using a normal sinus curve. (Using a faster custom Sine-class)
posY = degrees.fastSin(int(counter+i*0.65))*160;
// bar height is calculated using the sound spectrum in the ByteArray.
// It is multiplied and enhanced if close to the middle
barHeight = (ba.readFloat() * (100+enhance));
// creating the gradientbox set up gradientfill.
matrix.createGradientBox(BAR_WIDTH,2*barHeight,1.57075,0,-barHeight-posY*0.5);
beginGradientFill(GradientType.LINEAR,gradientColours,[0,1,1,1,1,1,0],[0,50,110,128,146,205,255],matrix);
// Draing 2 bars. One for each wing. Adding BAR_WIDTH on the left to avoid a gap in the middle.
drawRect(i, -barHeight-posY*0.5, BAR_WIDTH, 2*barHeight);
drawRect(-i+BAR_WIDTH, -barHeight-posY*0.5, BAR_WIDTH, 2*barHeight);
}
}
// adding counter so the Sine-curve starts one step away next frame (result: the wave motion)
counter+=1;
}
}
}
The code is quite straight forward.
Every single frame the SoundMixer creates a ByteArray containing Numbers from 0 – 1 which is used in order to create the bars/lines. The only thing that is custom is the DegreeVector class that converts all Radian to Degrees (as I’m no fan of radians). What it also does is to use a precalculated array of Sine-values that speedens up the sine-calculations a bit. This is of course not necessary and you could easily use the normal Math.sin functions to get the same result.
Just build a Firebird object in your main class, add it to stage and start playing any sound and Phoenix will manifest itself.
Tags: firebird, gabriel, peter, sound, spectrum, visualization

