views:

395

answers:

5

I have got three screenshots below of Flash-based audio players on various websites that draw a waveform of the clip it is going to play and moves along while it is playing and also allowing the user to click on a point on the audio file and it jumps to that point.

DJ Download music player from http://www.djdownload.com

DJ Download Music Player

SoundCloud music player from http://www.soundcloud.com

SoundCloud Music Player

TrackItDown music player from http://www.trackitdown.net

TrackItDown Music Player

I have very little Flash knowledge but is this easy to achieve? I would like to just show the Flash file an mp3 and it draws the waveform. I understand this could be quite intensive on CPU so would there be a way of caching the waveform data so it doesn't redraw each time the file is loaded?

A: 

Haven't tried it, but a google search for "as3 waveform" revealed this blog post (contains a link to some source code)

http://blog.efnx.com/flash-actionscript-3-waveform-generation-class/

Chris
A: 

This Flashkit board entry also provides a number of very interesting resources:

Open Source
+2  A: 

I've never done this myself before but as far as I know the situation is as follows.

If you're working with Flash Player 10 your in luck, otherwise it would seem that you have to compute the spectrum as the sound is playing. Like in Chris's link you can get the sound data out of the sound object into a ByteArray with Sound.extract() (FP10 only). You then go through the ByteArray read the values and draw something on screen according to the values.

On FP9 you'll have to play the sound on a SoundChannel and read the left and right peaks from the channel as it plays. I found this example code for that (link)

var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("your track url");
var channel:SoundChannel;
var bytes:ByteArray = new ByteArray();

snd.load(req);
this.addEventListener(Event.ENTER_FRAME, enterFrameEvent);
channel = snd.play(0,3);    

function enterFrameEvent(event:Event):void  {
    SoundMixer.computeSpectrum(bytes, true,0);
    // bytes has 512 values 0-255 leftchannel 256-512 right channel
    for (var i:Number = 0; i < 256; i++) {
        val = bytes.readFloat();
    }
}

So in short try to stick to FP10 and if you're able to do that (no client restrictions) you should be able to take the Waveform class straight out of Chris's link and use that. It looks like the class also draws the actual waveform (on top of extracting the audio data) but you can either move the drawing to it's own class or modify the code to get your own kind of look for the waveform.

Matti
Those illustrations in his example are not spectrum displays.
Justin Smith
No they're not but the code gives you an idea on how to get the audio data from the Sound object. What you do with the data is up to you.
Matti
A: 

The way the illustrations in your examples are generated is more or less as follows:

Figure out how many seconds of audio per pixel of the width display.

For each pixel going left to right, calculate the average RMS amplitude of the corresponding segment of the file.

This gives you your peak height for that pixel. In some of the displays it is rendered symmetrically (ie. it is mirrored top to bottom), and in others it is presented bar graph style.

(by the way, it is easy to see from the amplitude displays that they are digitally produced music, likely techno of some sort)

Justin Smith
A: 

Chris - thanks for linking to my blog and here is the source for that class (just to make it easier). I'm not completely sure what state the code is in, as I wrote it 2 years ago at the time of this writing, but it should get the job done for anyone else who needs it. http://efnx.com/lab/WavePlotter/src/WavePlotter_Main_081024.src.tar.gz

efnx clckclcks