Browse DevX
Sign up for e-mail newsletters from DevX


Create Sound Synchronization Magic in Flash, Part 1 : Page 2

Remember the speaker cabinets from the '70s, with lights that throbbed to the music? Using a powerful third-party utility for Flash, you can create games and animations that use rapid audio synchronization to drive assets with sound instead of programming.

Enter FlashAmp
Okay, okay, enough examples. All of these ideas and more can be realized with a powerful tool called FlashAmp, by Marmalade Multimedia It allows developers to pre-process audio files to get an array of the sound's amplitudes, or an array of the sound's frequencies divided into 2 to 16 ranges, or bands.

The FlashAmp application is very easy to use. Its power is surprising considering its small number of settings, which I'll discuss in detail later on. For now, it's only important to know that FlashAmp works by analyzing a sound and storing amplitude or frequency data at regular intervals. Because you can determine the intervals, choosing an interval that matches your Flash file's frame rate, such as 12 fps, makes synchronizing to sound playback a simple prospect.

Similarly, you can choose the scale to which the data will conform. For example, if you wanted to change a MovieClip's transparency with a sound's amplitude, you can choose a scale of 100. This scale results in values from 0 to 100—perfect for assigning a value to the _alpha (transparency) property. If, instead, you wanted to send a MovieClip to a particular frame, a scale of 10 might be more practical.

Amplitude Analysis
In the "amplitude.fla" example source file (included in the download with this article), I want to show a speaker that changes size to the beat of the music. When the music is very quiet, the speaker will be approximately normal size, whereas when the music is very loud, the speaker will be 50% bigger.

Figure 1. The amplitude source file example uses a speaker that throbs (gets larger and smaller) to the beat.
To accomplish this, I need to use FlashAmp to measure the sound's amplitude as many times per second as my Flash file's frame rate requires—in the case of Flash's default frame rate, 12 times per second—scaling the data to a range of 0-50.

Creating this data requires little more knowledge than what I've already discussed. Working in FlashAmp, I need to create an amplitude list, using a scale of 50, and a frame rate of 12. I am only displaying one speaker, so I don't need stereo data (a value for both the left channel and the right channel at every interval), and I don't need to worry about any other settings during this first FlashAmp use.

After choosing the mono MP3 sound file using the Input pane, and copying the data from the Output pane after processing, we end up with this array:
amplitude = [0, 23, 35, 49, 45, 27, 21, 30, 11, 0, 0, 3, 33, 12, 
29, 45, 35, 38, 24, 2, 0, 22, 16, 0] 
As you can see, there are 24 amplitude values (2 seconds x 12 values per second) and each value ranges from 0 to 50. Making a picture of a speaker throb to this music would be as simple as adding the above scale values to its existing scale of 100. That is, when no sound is coming out of the speaker it will be normal size (100% + 0%), but when the amplitude is maxed, it will increase the speaker size of 150% (100% + 50%, see Figure 1).

Author's Note: Notice that the array index is not just _root._currentframe. This is because when a sound starts, you want the first value in the array to be used. Because ActionScript uses zero-based arrays, the first array index is zero. Thus, if you start playing a sound in frame 1, you must subtract 1 from the _currentframe property. This technique changes when you want to use external sounds, and I'll elaborate on this subject later.

The script on the speaker would be as simple as the code below.
onClipEvent(enterframe) {
    this._xscale = 100 + amplitude[_root._currentframe-1]
    this._yscale = 100 + amplitude[_root._currentframe-1]
Spectrum Analysis
You can use the sound's frequency data similarly. The frequency data of a sound is usually referred to as spectral data, or a look at the frequency spectrum of the file. FlashAmp can output this data in your choice of 2 to 16 ranges, or bands. You've probably seen this represented in an audio equalizer in a stereo or in a software application like iTunes. Equalizers allow you to boost the low frequencies, temper the high frequencies, or anything in between. FlashAmp doesn't modify the sound like an equalizer, but it does show you the frequency data at any point during playback.

The principle is the same as amplitude analysis with one difference. Instead of returning a single value at each interval, it returns a value for each frequency band requested at each interval. Here is an example of a six-band spectrum analysis, for a 2-second sound, using a scale of 100, at a rate of 1 fps. (The very short sound and very slow frame rate are both impractical for this purpose, but it simplifies the example.)
spectrum = [[0, 0, 2, 10, 10, 1], [45, 53, 30, 38, 22, 2]] 
Figure 2. The spectrum source code example uses a six-band frequency visualization that also throbs to the beat—six times per interval.
As you can see, there are two array values (2 seconds x 1 value per second), six frequency bands per value (low frequencies first, moving on to higher frequencies), and each frequency value ranges from 0 to 100. If you imagine an equalizer visualization, this might represent a bass hit. The lowest frequency jumps from 0 to 45, the midranges each move 12 to 53 units, and the highest frequency only changes from 1 to 2 (see Figure 2).

Making a six-band peak meter to show this data, would be as simple as setting each of six MovieClips (in this case called "bar0", "bar1", etc.) to the scale specified in the array. The MovieClip's simple script is shown below. This can be seen in the "spectrum.fla" source file, included in the download with this article.
onClipEvent (enterFrame) {
    //determine frame offset outside of loop
    //  to avoid recalculating 6 times
    myFrame = _root._currentframe-1
    // change 6 MovieClips for each enterFrame
    for (i = 0; i < 6; i++) {
        // identify each peak meter 'bar'
        myMC = eval("_root.bar" + i);
        // set its vertical scale to array value
        // at the index matching the sound frame
        myMC._yscale = spectrum[myFrame][i];

Thanks for your registration, follow us on our social networks to keep up-to-date