Technically, this is a really stupid thing to do, and move over it isn't the cleverest thing to do, regardless though I've done it just for the hell of it.
The aim of this post is to prevent anybody else from making the same stupid mistakes! end product isn't too bad though.
To give a quick over view, Sound.extract() gives access to raw sound data, as a ByteArray of floats; typically you setup two sound objects, the first loads the sound data from source, the second requests sound data from the first at regular intervals, extracting 2048-8192 samples per request and then playing it - idea is that in the method that requests the samples you can quickly pre-process it before its played and make some nice effects.
So my illogical train of thought was to visualize the raw sound data in real time as it plays to create some nice effects.
The Numbers Game
Music in flash is sampled at 44100 Hz Stereo - 44100 samples per second, per channel - we're getting it at intervals of either 2048, 4096 or 8192 samples - meaning our visualization can run at either 21.53fps, 10.76fps or 5.45fps - which lets be honest is hardly going to make a nice smooth effect is it.
So our only option is to somehow synchronize the "timeline" (the screen updating) with the raw sound being played.
The Approach
I decided the only real way to do this was to make a continual buffer of sound that could be read independently by both the SampleDataEvent and by my own code to do the visualizations - after some playing around with numbers I finally gathered that if one was to run at a framerate of 63fps and render the 700 samples per channel at a time then I'd be consuming (63*700 = 41000 Hz / samples per second) = the data in realtime.
To make this possible I needed some kind of fast buffer to store the data in, obvious choice was fast memory which is a ByteArray and can be read and written to directly.
More number came in to play when the size of the buffer needed calculated, had to be a multiple of both the render speed (700) and the data feed rate (2048); which is a buffer of 358400 samples, or sample requests. (358400/175 = 2048).
To get the data in to the buffer I was finding the next offset at which i should write the data to my buffer, sound.extract'ing the data in to the buffer and using a modulo to create wrap around so after 175 samples data was written back at the start.
This covers getting the sound in to a fast memory buffer without consuming too many resources, next up to get it out and render it!
The Rendering
Rendering uses the same idea of requesting samples from the buffer, however this time the magic number is (358400/700 =) 512.
I implemented a simple framecounter that increments each frame and resets to 0 every 512 frames (giving the loop on the buffer), then quickly read 700 pairs of samples from the buffer each frame.
The left channel float value is then scaled by 300 used as an X position, whilst the right channel creates the Y position - both x and y are then fed to setPixel() on BitmapData whilst a simple calculation of 0xFFFFFF*leftChannel / 2 sets the color value.
Each frame the 700 dual channel samples are rendered creating 700 realtime 2D particles (hopefully) in time with the sound, and a simple blur filter is used to clear the previous frame in a nicer way.
The Point
It's all stupid, pointless and just stick to computeSpectrum - you only get 256 samples rather than 700 but it's perfectly in time and allows you do something other than exactly 63 fps; further it'll always be in time with the music.
The Result
Well, it's here - I've got it tuned in to my other halfs radio station citybeat radio at the minute (which i wholeheartedly recommend for any electronic / trance music fans) and well.. here it is with source.
















