I'm struggling for few hours now with FFT normalization. I'm working in Matlab to prove my concept before moving to embedded application.
I have 4 sine wave signals with:
DC offset | frequency | amplitude 5V | 1Hz | 10V -2V | 3Hz | 3V 0V | 6Hz | 2V 0V | 8Hz | 2V
Sampling frequency =
Number of samples =
In theory, I have frequency resolution of
1 Hz and I can detect samples < 32Hz (Nyquist-Shannon) before spectrum gets mirrored. So far so good.
At the output of FFT I have following spikes (after normalization)
Normalization fft_out_norm = fft_out / fft_size = fft_out / 64 (sample by sample divide) index 0 = DC value = 3 (ok as one signal has 5V DC, second -2V = 3V together) 1 = 1Hz sine = 5 (but sine has 10V amplitude) 3 = 2Hz sine = 1.5 (but sine has 3V amplitude) 6 = 6Hz sine = 1 (bit sine has 2V amplitude) 8 = 8Hz ... -----------||----------
I understand that spectrum is mirrored and that part of it is on other side:
Index 0 (DC) is not mirrored Index 1 and 63 are mirrored Index 2 and 62 are mirrored Index 3 and 61 are mirrored
Now important part. Since we have mirrored spectrum on all frequencies except DC value and according to the fact that only half of spectrum is enough for useful information, can we simply normalize the signal this way:
fft_out_norm = fft_out / samples_len fft_out_norm = (fft_out + fft_out[samples_len - 1]) / samples_len fft_out_norm[i] = (fft_out[i] + fft_out[samples_len - i]) / samples_len Equation would apply if i > 0 and i < samples_len
And further optimization, if we know we have mirrored spectrum, we can do this:
fft_out_norm = fft_out / samples_len fft_out_norm = 2 * fft_out / samples_len fft_out_norm[i] = 2 * fft_out[i] / samples_len Equation would apply if i > 0 and i < (samples_len / 2)
Can we use this approach? If I do this, I have on output
index 0 = DC value = 3 1 = 1Hz sine = 10 3 = 2Hz sine = 3 6 = 6Hz sine = 2 8 = 8Hz sine = 2
Which seems perfectly ok. Is there a problem with this approach and if it is, how to eliminate it or how to proceed?
For example, Real-FFT in ARM-DSP gives you only first half of spectrum on output. If you normalize only first half, you get wrong values (as explained on top). So solution would be to multiply all values by
2 first before normalizing, except DC value (because DC is always only
1 value, it is never mirrored).
Thanks for answers.