Recipe 15.13.
Reading the Sound Spectrum
Problem
You want
to visually represent the
sound wave of the sounds playing in your .swf.
Solution
Use
SoundMixer.computeSpectrum( ) to fill a byte array with the
spectrum data of the sound playing in the .swf. Read the
values of this array to create a visualization of that data.
Discussion
One of the most exciting additions to the sound
capabilities in ActionScript 3.0 is the ability to access sound
spectrum data. Throughout the years and versions of Flash,
developers have yearned to get at this data. Some third-party tools
read this data in and created a separate text file containing the
values of the sound spectrum data. This file could be read in and
synchronized to the sound. However, these solutions were complex to
work with and not very efficient. Now that this feature is built
into the SoundMixer
class, and with the addition of the new ByteArray class, you
can easily display this data with just a few lines of code.
First, let's cover the ByteArray class. This new special
class in ActionScript 3.0 is used to handle blocks of binary data
in a highly compact, efficient, and optimized way. It is part of
the flash.utils package. Essentially, it is what it sounds
like: an array of bytes. But its methods allow for fast
manipulation and access of its datamuch faster than a traditional
ActionScript array.
For use in computing the sound spectrum, you
first need to create an empty ByteArray, as shown in the
following example:
var spectrum:ByteArray = new ByteArray( );
This ByteArray is then passed into
SoundMixer.computeSpectrum( ). This method takes a snapshot
of the sound as it's playing and calculates the current sound wave
on both the left and right channels. It breaks this into 256 values
on each channel, each from -1.0 to 1.0. It stores these values in
the empty ByteArray you just passed in.
This data is now available for you to use
however you want. You just need to loop through the
ByteArray 512 times, calling getFloat( ). The first
256 calls give you the values for the left channel; the next 256
are for the right channel.
The following example uses these values, along
with a BitmapData object and setPixel32( ) to create
a visual representation of both channels' sound waves:
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.utils.ByteArray;
public class Spectrum extends Sprite {
private var _sound:Sound;
private var _channel:SoundChannel;
private var _spectrumGraph:BitmapData;
public function Spectrum( ) {
// Create bitmap for spectrum display
_spectrumGraph = new BitmapData(256, 60,
true,
0x00000000);
var bitmap:Bitmap = new Bitmap(_spectrumGraph);
addChild(bitmap);
bitmap.x = 10;
bitmap.y = 10;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
_sound = new Sound(new URLRequest("song.mp3"));
_channel = _sound.play( );
}
public function onEnterFrame(event:Event):void
{
// Create the byte array and fill it with data
var spectrum:ByteArray = new ByteArray( );
SoundMixer.computeSpectrum(spectrum);
// Clear the bitmap
_spectrumGraph.fillRect(_spectrumGraph.rect,
0x00000000);
// Create the left channel visualization
for(var i:int=0;i<256;i++) {
_spectrumGraph.setPixel32(i,
20 + spectrum.readFloat( ) * 20,
0xffffffff);
}
// Create the right channel visualization
for(var i:int=0;i<256;i++) {
_spectrumGraph.setPixel32(i,
40 + spectrum.readFloat( ) * 20,
0xffffffff);
}
}
}
}
See Also
Recipe 15.14
|