Create a Flash Equalizer (modify output sound)

audioequalizerflash

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

Best Solution

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;
}
Related Question