1
$\begingroup$

I am getting incorrect amplitude of my signal post FFT (90% error) and it does not improve after applying any of the window functions prior to FFT. After reading a number of articles, I believe FFT overlapping might improve the accuracy. However, I am not sure how to do it in Matlab. Please could anyone shed some light on that. I tried using spectrogram but I keep getting error on input X to be double precision vector.

Here is an example without performing FFT overlapping:

L = 1024; %signal length
Fs = 1000; %sampling frequency
t = (0:L-1)'/Fs;

NFFT = 2^nextpow2(L);
x = 11*sin(2*pi*250*t);

J = flattopwin(L);  
JX = x(:).*J(:);

P= fft(JX,NFFT)/L;
M= 2*abs(P(1:NFFT/2+1));

f = Fs/2*linspace(0,1,NFFT/2+1);

plot(f,M)

The amplitude observed from the plot is approximately 2.4 at 250Hz which is much lesser than the actual amplitude, 11. Is there any reason for the significant reduction of the amplitude on FFT of a windowed signal?

Thank you.

$\endgroup$
  • $\begingroup$ Anything else? Examples, figures what you did so far? $\endgroup$ – jojek Jan 6 '15 at 8:41
  • 1
    $\begingroup$ Hi, I have added more information to explain the problem I am having. $\endgroup$ – khel Jan 11 '15 at 21:51
1
$\begingroup$

You should not normalize by length of FFT, but you should always normalize by sum of window function samples.

In case of rectangular window we get $N$ ones, so obviously you will divide by same factor $N$ that is the sum of all values. For other window functions you must use appropriate scaling factor, i.e. sum of all flat-top window samples. Your code should become:

L = 1024; %signal length
Fs = 1000; %sampling frequency
t = (0:L-1)'/Fs;

NFFT = 2^nextpow2(L);
x = 11*sin(2*pi*250*t);

J = flattopwin(L);  
JX = x(:).*J(:);

P= fft(JX,NFFT)/sum(J);
M= 2*abs(P(1:NFFT/2+1));

f = Fs/2*linspace(0,1,NFFT/2+1);

plot(f,M)
grid on

Yielding a plot: enter image description here

For more info and better understanding I suggest you to read related questions on DSP SE and this great paper: Spectrum and spectral density estimation by the DFT.... Just keep in mind that most of the amplitude errors will occur due to leakage - non integer number of signal periods.

$\endgroup$
  • $\begingroup$ I got it now. Thank you very much for your help. $\endgroup$ – khel Jan 12 '15 at 17:37
1
$\begingroup$

Matlab normalizes in the inverse Fourier transform, so if you want to calculate the fft accurately, you have to normalize by the fft vector by the lenght of the fft itself.

This matlab script will demonstrate the normalization. There is a 1 seconds long 1000 Hz pure sine wave with amplitude 1. We will sample it with fs = 6000 Hz, and calculate the spectrum to it in 60 points.

After plotting, we expect two pure spikes at 1000 and -1000 Hz with amplitude 0.5.

fs = 6e3;
T = 1;
f = 1000;
x = sin(2*pi*f*(0:1/fs:T-1/fs));
Nfft = 60;
X = fft(x,Nfft)./Nfft;
stem((0:Nfft-1)*fs/Nfft-fs/2,abs(fftshift(X)))
title('Normalized spectrum')
xlabel('frequency')

normalized spectrum calculation result

$\endgroup$
  • $\begingroup$ Can the downvoter explain why he did that? Based on the very few information given, this might be helpful for khel, if he isn't familiar with the matlab conventions. $\endgroup$ – tiborsimon Jan 6 '15 at 13:32
  • $\begingroup$ Apologies for not clarifying the problem properly. I have added more information to explain what I am after. $\endgroup$ – khel Jan 11 '15 at 21:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.