Hi m8’s

Here it is a tutorial that explain us how to make the new feature of actionscript 3, the Spectrum analyzer.

Quote 

Spectrum analyzer with AS3

Author:
Peter Hansén

www.abscess.se

Introduction: Spectrum analyzer with AS3
Step 1: SoundMixer class
Step 2: computeSpectrum method
Step 3: Load an MP3
Step 4: Read and display the spectrum
Step 5: More examples
Step 6: Conclusion

Introduction:
Spectrum analyzer with AS3

I have created music driven animation since Flash 5 and I must say there has not been much progress until just now. I started out by importing sounds directly to the timeline and made keyframes according to the amplitude shown, a slow and painful method. Soon people created different approaches, some better than others, but the one I have used the most is SwiftMP3 from www.swift-tools.net. It started as a free script that could be used either on a server for real-time conversion or from a dos prompt.

Now, with the release of AS3, we can use existing classes to load external mp3 files and read the spectrum variables in runtime! In this tutorial I will show how it is done.

1: SoundMixer class

The SoundMixer class is a part of the flash.media package. It contains classes for manipulation of both video and sound as well as classes for working with media in Flash Communication Server.

The SoundMixer class inherits from Object and contains properties and methods for controlling embedded streaming sounds but it can not be used together with Sound objects created with AS.

Methods defined in the SoundMixer class:

areSoundsInaccessible():Boolean
//Determines whether any sounds are not accessible due to security restrictions.

computeSpectrum(outputArray:ByteArray, FFTMode:Boolean = false, stretchFactor:int = 0):void
//Takes a snapshot of the current sound wave and places it into the specified ByteArray object.

stopAll():void
//Stops all sounds currently playing.

Methods inherited from the Object class:

hasOwnProperty(name:String):Boolean
//Indicates whether an object has a specified property defined.

isPrototypeOf(theClass:Object):Boolean
//Indicates whether an instance of the Object class is in the prototype chain of the object specified as the parameter.

propertyIsEnumerable(name:String):Boolean
//Indicates whether the specified property exists and is enumerable.

setPropertyIsEnumerable(name:String, isEnum:Boolean = true):void
//Sets the availability of a dynamic property for loop operations.

toString():String
//Returns the string representation of the specified object.

valueOf():Object
//Returns the primitive value of the specified object.

Read more at http://livedocs.macromedia.com/flex/2/langref/flash/media/SoundMixer.html

2: computeSpectrum method

Since this tutorial is about analyzing spectrums and music driven animation we will put our main focus on the computeSpectrum method:

public static function computeSpectrum(outputArray:ByteArray, FFTMode:Boolean = false, stretchFactor:int = 0):void

Every time the computeSpectrum method is called it creates a copy of the current wave and stores the data as normalized floating-points between -1 and 1 in the ByteArray (outputArray). If the sound is not running the floating.points get the value zero. The ByteArray has a fixed size of 512 where the first 256 values represent the left channel and the last 256 represent the right.

The FFTMode variable can by set to either true or false determining whether a Fast Fourier transform is performed before the sound wave data is saved. Setting this to true will create a frequency spectrum where low frequencies are shown to the left and high to the right. This is pretty much standard on music players these days, like Winamp for example.

“The Fourier transform is an integral transform that re-expresses a function in terms of sinusoidal basis functions, i.e. as a sum or integral of sinusoidal functions multiplied by some coefficients (”amplitudes”).” http://en.wikipedia.org/wiki/Fourier_transformation

The last variable, stretchFactor, is an integer that determines the sampling rate of the sound. 0 samples the sound at 44 KHz and incrementing the variable with one halves the sampling rate (1 = 22KHz, 2 = 11KHz).

Unfortunately you can not use this method together with sound streamed by the Flash Media Server and its Real Time Messaging Protocol.

3: Load an mp3

Before we can do anything we have to load some music and make it play. Start by opening a new document in Flash 9. In the first frame, we create a Sound object called “mySound”:

var mySound:Sound = new Sound();

Next we load an mp3 file into the Sound object and tell it to play:

mySound.load(new URLRequest(”track.mp3″));
mySound.play();

This is the only code we need to play an mp3 file, simple enough!

4: Read and display the spectrum

Now when we have the music playing we will continue by creating a method to calculate the spectrum of the music. First we to create a ByteArray to hold the raw data we will get from the computeSpectrum method. We will simply call this “myByteArray”:

var myByteArray:ByteArray = new ByteArray();

Next we create a function called readSpectrum:

function readSpectrum(event:Event){

SoundMixer.computeSpectrum(myByteArray, false, 0);

graphics.clear();

for(var i = 0; i < 256; i += 8){

drawSpectrum(myByteArray.readFloat(), i);

}

}

When we call the computeSpectrum method we include our ByteArray created above, this is where the method will save all the data. The Fast Fourier transform is set to false (but you can play with this to see what results you get) and the stretchFactor to 0, meaning that the sounds sampling rate is 44 KHz. After that we delete all graphics from the stage. Well, the first time there will not be any but we will get there.

Then we create a for loop so we can go though all the data we have. The condition will be i < 256 since we have 256 values for each channel in the ByteArray. I want to have 32 bars in my spectrum so I increment i with 8 (256 / 8 = 32). In the loop we will call the next method, drawSpectrum, with myByteArray.readFloat() and the current iteration (i). readFloat is the method used to get floating-point numbers from the byte stream.

Below you can see some traces I made with and without using readFloat and the FFTMode set to true or false:

Tracing myByteArray without readFloat() and FFTMode set to false:

Tracing myByteArray: ½ã
Tracing myByteArray: =ê€
Tracing myByteArray: =‚
Tracing myByteArray: >c°
Tracing myByteArray: <ó€

Tracing myByteArray without readFloat() and FFTMode set to true:

Tracing myByteArray: ?P=Þ?@vÊ?dS³?b *?TÌ ?ÄD>ÿ n>´>‡©©? §<–`
Tracing myByteArray: ?>à?(Á²?†À?u¼q?Rè/>Œܪ
Tracing myByteArray: ?@l?V “?|e?8 ?C3œ>Ûy•>Ü9í= ™ >—ÚÎ>y2
Tracing myByteArray: ?L ?:EÞ?‡‚Í?O˜K?^ÿo>Žã?’±Á>F>>â~Õ>òô=øƒ
Tracing myByteArray: >¦Ýj?.NN?] ‘>þXK?
Tracing myByteArray with readFloat() and FFTMode set to false:

Tracing myByteArray.readFloat(): 0.02313232421875
Tracing myByteArray.readFloat(): 0.10894775390625
Tracing myByteArray.readFloat(): -0.16021728515625
Tracing myByteArray.readFloat(): -0.028045654296875
Tracing myByteArray.readFloat(): -0.053314208984375

Tracing myByteArray with readFloat() and FFTMode set to true:

Tracing myByteArray.readFloat(): 0.055859118700027466
Tracing myByteArray.readFloat(): 0.5461686849594116
Tracing myByteArray.readFloat(): 0.05429217591881752
Tracing myByteArray.readFloat(): 0.21418170630931854
Tracing myByteArray.readFloat(): 0.44413191080093384

The drawSpectrum method is what will draw our spectrum bars. The floating-point number passed on from the readSpectrum method is multiplied with 500 to get a visible difference and then we use a simple drawRect function to draw the graphics.

function drawSpectrum(myReadFloat:Number, myIteration:Number){

var myNumber:Number = myReadFloat * 500;

graphics.lineStyle(1, 0×000000);
graphics.beginFill(0xffffff);
graphics.drawRect((16 * (myIteration / 8)) +19, 250, 16, -(myNumber / 5));

}

Finally we add an eventlistener that will call readSpectrum on enterframe:

this.addEventListener(Event.ENTER_FRAME, readSpectrum);

This is everything! The code above should provide you with something like this:
(Click button to start the music)

5: More examples

Here I used the exact same code as above but set the FFTMode to true and added a blur filter:

var filter:BitmapFilter = new BlurFilter(15, 15, BitmapFilterQuality.HIGH);
var myFilters:Array = new Array();
myFilters.push(filter);
filters = myFilters;
(Click button to start the music)

The next one is a little more complex with lines drawn to each peak instead of just using bars:
(Click button to start the music)

The code actually is not very complicated, I only changed the two functions to this:

function readSpectrum(event:Event){

graphics.clear();

SoundMixer.computeSpectrum(myByteArray, false, 0);

var myArray:Array = new Array;

for(var i = 0; i < 256; i += 8){

myArray.push(myByteArray.readFloat());

}

drawSpectrum(myArray);

}

function drawSpectrum(myFloatArray:Array){

graphics.lineStyle(5, 0×000000);

for(i = 1; i < myFloatArray.length; i++){

if(i == 1){

graphics.moveTo(20, 0);
graphics.lineTo((i+2) * 16, myFloatArray[i+1] * 60);

}else{

graphics.moveTo((i+1) * 16, myFloatArray[i] * 60);
graphics.lineTo((i+2) * 16, myFloatArray[i+1] * 60);

}

}

}

6: Conclusion

I hope you enjoyed this tutorial but please, do not give Flash a bad name again by using it everywhere! ;)

Unquote

This tutorial it was taken from http://www.ultrashock.com/ where you can find other good tutorials as also components and other things.

Brgds,

CP


  1. Ali

    Fantastic tutorial! This one finally made me start AS3ing.. AS2 is dead, long live AS3!

  2. isnain siddique

    Hi,
    Your tutorial is nice it helped me lot . But there are few things i like to know. So far i have understood its not possible to computespectrum without playing the music is that right?
    If this is true then how can i create a audio sequencer can you point me to any direction where i can get some help.
    all i want is to make the whole audio as a frequency graph but if i do that i have to play the total music first , i dont want that i want the curve to be drawn at a time please help me.
    I used this tutorial at http://www.onelivedesign.com/flashapp/RintoneEditor.aspx

  3. Yogesh Puri

    Hi isnain siddique

    Can you please share the code of graph generation for MP3? Have you stored the sound spectrum array to do this?

    Regards
    Yogesh

  4. Brent

    Is it possible to play one sound that is not using compute spectrum and then play another sound that is analyzed by compute spectrum at the same time? Because it appears that compute spectrum works for any sound that is playing at that time, you can’t make it ignore one sound.

  1. 1 diaghe.com » Blog Archive » I’VE FINALLY FOUND A WAY OF ANIMATING MUSIC IN REAL-TIME IN FLASH!!

    [...] http://flashenabled.wordpress.com/2007/06/01/tutorial-spectrum-analyzer-with-as3/ [...]



Leave a Comment