corbanbrook / dsp.js

Digital Signal Processing for Javascript
http://weare.buildingsky.net
MIT License
1.73k stars 236 forks source link

FFT spectrum normalization #33

Open therenotomorrow opened 6 years ago

therenotomorrow commented 6 years ago

Hello, @corbanbrook I have some question regarding the normalization of FFT results. See the link:

https://github.com/corbanbrook/dsp.js/blob/master/dsp.js#L269

Why you choose bSi = 2 / this.bufferSize? In general, to return a FFT amplitude equal to the amplitude signal which performs in FFT, need to normalize FFT data by the number of sample points. Like this:

bSi = 1 / this.bufferSize

I think it's a bug.

tekhedd commented 6 years ago

I also believe this is a bug. To test it empirically (hey why not), I calculated the RMS of the input signal and the RMS of the transformed signal. They should be ~equal. The default is simply wrong. If you change to 1 (or divide the magnitude of the output bins by 2) the results are correct within 5-6% for noise signals and look like a rounding error for a pure sine input.

PoorWeakCat commented 4 years ago

It's not a bug at all. After FFT processing, the frequency spectrum contains two parts: positive frequency and negative frequency, which are symmetrical to each other. The amplitude of each frequency component in each part is equal to half of the actual frequency amplitude, so the final result needs to be multiplied by 2 instead of 1.You can try to input a signal to test it.

therenotomorrow commented 4 years ago

Yes, if it need to multiple result by 2 it is correct. Agree with you.

tpoint75 commented 3 years ago

for me the right result is: bSi = 2 / Math.sqrt(this.bufferSize * this.sampleRate),

If you will respect the windowing you have to calculate: winMeansq = 0; for(var i=0; i < this.bufferSize; i++) { let val = window.func(this.bufferSize, i); winMeansq += val * val; } winMeansq = Math.sqrt(1 / Math.sqrt( winMeansq / this.sampleRate));

then its: winMeansq * bSi

tpoint75 commented 3 years ago

see: https://github.com/CyclotronResearchCentre/FASST/blob/master/SPTfunctions/pwelch.m#L810