views:

2683

answers:

6

Hi it'd like to know if it's at all possible create a "parametric" equalizer in flash. Not just the usual graphic effects but a tool to modify the output of the sound that pass trough the application. Any reference, tips idea welcomed. Thanks

A: 

Check out Andre Michelle's labs page. He does a bunch of work with audo in Flash...probably one of the best. I'm not sure what a parametric eq is, but you should be able to find some good information on that page.

Alex Jillard
+3  A: 

It's not going to be terribly easy... but here might be a way:

var parameters:Array = [1,1,1,1,0.5]
var sound:Sound = new Sound();
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, filter); 
sound.load(soundURLRequest);
sound.play();

private function filter(event:SampleDataEvent):void
{
    var freqDomain:Array = FFT(event.data, parameters.length); // You will need to find a FFT(Fast Fourier Transform) function to generate an array. 
    for(var i:int = 0; i < freqDomain.length; i++)
    {
        freqDomain[i] = freqDomain[i] * parameters[i]; // This is where your EQ parameters get applied.
    }
    var timeDomain:Array = IFFT(freqDomain, event.data.length); // Inverse FFT

    for(value:Number in timeDomain) 
    {
        event.data.writeFloat(value);
    }
}

Some on the FFT and IFFT functions, FFT usually outputs complex values (real + complex components), which can be converted to magnitude and phase components. What you really need is only the magnitude, which has a formula = (sqrt(real^2 + complex^2)). Humans ears are NOT sensitive to the phase (As opposed to the eyes, which are VERY sensitive to phase), so when you do the inverse FFT, you can insert a random or flat phase with little difference. Note that my approach is very low level in terms of filter implementation.

Here is a Fourier Transform function (not Fast though, it's just a convolution (O(n^2)) vs FFT O(nlogn)) just for reference (err.. it's off the top of my head so if might be wrong with the constants):

// Note that this only returns the magnitude, I am discarding the phase.
function FFT(sample:Array, size):Array
{
    var frequencies = new Array(size);
    for(int i = 0; i < sample.size; i++)
    {
        for(int j = 0; i < frequencies.size; j++)
        {
            var real:Number = sample[i] * Math.cos(Math.PI/2 * i * j);
            var complex:Number = sample[i] * Math.sin(Math.PI/2 * i * j);
            frequencies[j] += Math.sqrt(real * real + complex * complex);
        }
    }
    return frequencies;
}
CookieOfFortune
the event.data object passed by SampleDataEvent is a bytearray, not an array. Any recommendations for updating the code to handle a bytearray. Also, what is needed to make the IFFT?
medigerati
ByteArrays allow indexing (using the [i] to grab parts), so you essentially use it like an array. You can find IFFT algorithms online, but it's essentially running the FFT again but with different magnitude and phase factors.
CookieOfFortune
A: 

Probably a set of digital filters would be your best bet. Unlike the FFT, with the digital filter you don't need to hold the entire waveform in memory, since the digital filters are causal and just look at few points into the past and/or future. Also, if you can stream the sound, you can just apply these on the fly. Simple filters can be easily chained together to make more complicated filters.

There's a free book on digital filters that has some basic theory, but where one can also just page through and lift formulas. For example, a quick perusal of Ch. 19 lists simple formulas for high-pass, low-pass, and band pass recursive filters that will probably do the trick, but if you want to get fancier, there are plenty of other filters throughout the book.

tom10
The problem with FIR and IIR filters is that it is non-trivial to have them work on arbitrary frequency parameters.
CookieOfFortune
@Cookie - This is true for some digital filters but not all. The reference I mentioned lists multiple filters that are easy to calculate on the fly, in just a few very simple lines of code.
tom10
+2  A: 

Check this out: SoundFX, out-of-the-box audio filters with actionscript 3

grapefrukt
A: 

Update: I found an example of a 3-band equalizer using Flash 10. It uses different math than CookieOfFortune mentioned, but it works (well, it did). Using that, I updated the example for 5-bands and converted it to run in Flex. You can read my post about it, or see the 5-band equalizer in action (with source view).

If anyone has any suggestions to how the math is run, I'd be more than happy to hear about it. I really don't know much in terms of sound modificaiton.


Original post: I'm not sure how much this will help, but this is a stopgap to get the effect of the sound equalizer without the pain of FFT's and such.

http://www.webdesign.org/web/flash/tutorials/sound-equalizer.5020.html

Basically, you create several versions of the sound file, each set to a pre-made equalizer setting. Then, when the user adjusts the bass or treble, just adjust the sound volume of the respective file.

You might also find the extract() function helpful on the sound variable: http://livedocs.adobe.com/flex/3/langref/flash/media/Sound.html#extract

medigerati
It seems they are using FFT. You can pretty easily generalize those statements to create arbitrary bands (At the cost of having to increase your buffer length).
CookieOfFortune
A: 

I was looking to find a equalizer logo any available? For my free mp3 downloads site

mp3 downloads