And now, there is need to calculate power of specific bin in the FFT result. I can do it with the following expression:
P = 2*abs(spectr(binNumber)).^2/N;
N is FFT size. I'm using multiplier by 2 because there are two parts of spectrum with negative and positive frequency and since I'm use single side spectrum, I need to multiply bin magnitude by 2.
This expression works ok for non DC bin. For example for sine signal it returns the same signal level of specific bin as a total signal level. But for DC signal it returns +6.02 dBFS at DC bin while total rmsSignal = +3.01 dBFS.
So, it seems that there is need to remove multiply by two for DC bin:
p0 = abs(spectr(1)).^2/N;
p1 = 2*abs(spectr(2)).^2/N;
p2 = 2*abs(spectr(3)).^2/N;
Is that correct?
By the way, if we use FFT normalization 1/N, it allows to eliminate divide by N for calculations in frequency domain:
spectr = fft(signal) / N;
pSignal = sum(abs(signal).^2)/N;
pSpectr = sum(abs(spectr).^2);
fprintf('rmsSignal: %f V = %f W\n', sqrt(pSignal), pSignal);
fprintf('rmsSpectr: %f V = %f W\n', sqrt(pSpectr), pSpectr);
fprintf('rmsSignal: %+.2f dBFS\n', 10*log10(pSignal*2));
fprintf('rmsSpectr: %+.2f dBFS\n', 10*log10(pSpectr*2));
p0 = abs(spectr(1)).^2;
p1 = 2*abs(spectr(2)).^2;
p2 = 2*abs(spectr(3)).^2;
p3 = 2*abs(spectr(4)).^2;
p4 = 2*abs(spectr(5)).^2;
fprintf('p0 = %f V = %+.2f dBFS\n', sqrt(p0), 10*log10(p0*2));
fprintf('p1 = %f V = %+.2f dBFS\n', sqrt(p1), 10*log10(p1*2));
fprintf('p2 = %f V = %+.2f dBFS\n', sqrt(p2), 10*log10(p2*2));
fprintf('p3 = %f V = %+.2f dBFS\n', sqrt(p3), 10*log10(p3*2));
fprintf('p4 = %f V = %+.2f dBFS\n', sqrt(p4), 10*log10(p4*2));
rmsSignal: 0.707107 V = 0.500000 W
rmsSpectr: 0.707107 V = 0.500000 W
rmsSignal: +0.00 dBFS
rmsSpectr: +0.00 dBFS
p0 = 0.000000 V = -345.45 dBFS
p1 = 0.707107 V = +0.00 dBFS
p2 = 0.000000 V = -325.27 dBFS
p3 = 0.000000 V = -326.48 dBFS
p4 = 0.000000 V = -331.67 dBFS