I am trying to understand how you use an FFT in matlab to measure/retrieve the magnitude of the input signal.
For my understanding I have put this script together, creating a 15Hz sine wave with a sampling frequency of 1kHz.
fftsize = 2048; % How many samples for FFT
fs = 1000; % Sampling frequency (Hz)
sim_length = fftsize/fs ; % run sim for this time
t = 0:1/fs:sim_length-1/fs;
x = (0.5)*sin(2*pi*15*t); % 15 Hz component, 0.5 magnitude
Window and FFT:
%% Windowed FFT
data = x'; % Assign input data
window = blackman(fftsize);
windowed_data = window.*data;
% Perform FFT and take magnitude (of complex result)
fftd_data = abs( fft(windowed_data, fftsize) );
The input frequency was not coherent, add in the windowing and there is going to be some spectral leakage, therefore I need to sum the power over a few bins around where I expect the fundamental to be.
% Each bin represents
bin_freq = fs/fftsize ;
% 15 Hz fundamental is centred in bin
fundamental_bin = ceil( 15/bin_freq );
% Allow spectral spreading of +-4 bins
lower_limit = fundamental_bin - 4;
upper_limit = fundamental_bin + 4;
Sum of values from fft:
sum( fftd_data(lower_limit:upper_limit) )
ans =
512.3738
Which is not the 0.5 I was looking for. What is the best way to get the (0.5) input magnitude from the fft result.
After some digging about I have come up with the following but not quite sure why it works or if I have named the calculations appropriately.
incoherent_power_gain = sum(window.^2);
power_spectrum = fftd_data.^2 ;
power_fftd_data = (4 * power_spectrum) / (incoherent_power_gain * fftsize);
sum_fundamental_power = sum( power_fftd_data(lower_limit:upper_limit) )
sum_fundamental_power =
0.2500
We converted to Power so we can take the square root to get back to a signal level.
sqrt( sum_fundamental_power )
ans =
0.5000
Great, but is there a better way or can some one explain:
If power spectrum is the correct name for fftd_data.^2
.
I am also unsure what is happening in (4 * power_spectrum) / (incoherent_power_gain * fftsize)
.