I would like to limit the noise after the FFT. I have used this strategy:
- Divide the signal in segments using a Hann window
- Perform
abs(FFT(segment))
- Ensemble average
- Apply the gain factor of the Hann window.
This ends up being the same as doing the square root of the PSD obtained with the Welch method. I am satisfied in terms of reduced fluctuation with this "filtered" spectrum, but it seems to be shifted above, and in my case the magnitude of the spectra is important.
I found a similar behavior of what I am saying in Fig. 2 here.
Is there a way of avoiding or compensating this upward shift? I have noticed that avoiding the abs
at step 2 results in avoiding this upward shift, but it causes also more fluctuations, which makes the filtration useless. Are there other method to reduce fluctuations?
Here it is a sample code
clear; clc; close all;
rng default
n = 1:10000;
Sn=0.1;
Fs=1/Sn;
L=length(n)
duration = 1000;
x = pinknoise(duration*Fs);
freq_original = transpose(Fs*(0:(L)/2)/L);
W_len=500;
freq = transpose(Fs*(0:(W_len)/2)/W_len);
%Original Spectrum
xf_original=abs(fft(x))./L
xf_original= xf_original(1:L/2+1,:);
xf_original(2:end-1,:) = 2*xf_original(2:end-1,:);
%Division of the signal in segment and Henning windowing
xdiv = buffer(x(:,:),W_len,(W_len)/2, 'nodelay')
xdiv=xdiv(:,1:38)
A = hanning(W_len);
xdivHanning=A.*xdiv
%fft and absolute value of every window
xf2=abs(fft(xdivHanning))./W_len
xf2= xf2(1:W_len/2+1,:);
xf2(2:end-1,:) = 2*xf2(2:end-1,:);
xf2=transpose(mean(transpose(xf2)))
%Amplitude Gain Factor for Hanning window
CrrFac=2
figure('DefaultAxesFontSize',13)
loglog(freq_original ,(xf_original),'r')
hold on
plot(freq ,CrrFac.*abs(xf2),'b')
legend('original spectrum','Upward shifted fft')