
1Ratio Correction Method
close all;
clear all;
clc
Fs=1024;
N=1024;
t =(0:N-1)/Fs;
tt=0:N-1;
hanning=0.5-0.5*cos(2*pi*tt/N);
% Hanning window expression
x=5.3*cos(2*pi*253.5453*t+240*pi/180);
% Function to be analyzed
x_hanning=5.3*cos(2*pi*253.5453*t+240*pi/180).*hanning;
% Apply Hanning window
y = fft(x);
yh=fft(x_hanning);
Y=y(1:N/2)/N*2;
Yh=yh(1:N/2)/N*2;
f = Fs/2*linspace(0,1,N/2);
A=abs(Y);
Ah=abs(Yh);
subplot(221);
stem(f,A(1:N/2));
title(‘Uncorrected with Rectangular Window’);
subplot(222);
stem(f,2*Ah(1:N/2));
title(‘Uncorrected with Hanning Window’);
% The factor of 2 in the plot function is the amplitude recovery coefficient
% Apply Rectangular Window
[Amax,k]=max(A);
phmax=angle(Y(k));
if A(k-1)>A(k+1);
deltf=1/(1+A(k)/A(k-1));
f0=(k-1-deltf)*Fs/N
% Corrected frequency
am=Amax/sinc(deltf)
% Corrected amplitude
ph=(phmax+pi*deltf)*180/pi
% Corrected phase
else A(k-1)<A(k+1);
deltf=1/(1+A(k)/A(k+1));
f0=(k-1+deltf)*Fs/N
am=Amax/sinc(deltf)
ph=(phmax-pi*deltf)*180/pi
end
A(k)=am;f(k)=f0;
subplot(223);
stem(f,A(1:N/2));
title(‘Corrected with Rectangular Window’);
% Apply Hanning Window
[Amaxh,kh]=max(Ah);
phmaxh=angle(Yh(kh));
if Ah(kh-1)>Ah(kh+1);
deltfh=(Ah(kh)/Ah(kh-1)-2)/(1+Ah(kh)/Ah(kh-1));
f0h=(kh-1+deltfh)*Fs/N
amh=2/sinc(deltfh)*Amaxh*(1-deltfh^2)
phh=(phmaxh-pi*deltfh)*180/pi
else Ah(kh-1)<Ah(kh+1);
deltfh=(Ah(kh)/Ah(kh+1)-2)/(1+Ah(kh)/Ah(kh+1));
f0h=(kh-1-deltfh)*Fs/N
amh=2/sinc(deltfh)*Amaxh*(1-deltfh^2)
phh=(phmaxh+pi*deltfh)*180/pi
end
Ah(kh)=amh;
f(kh)=f0h;
subplot(224);
stem(f,Ah(1:N/2));
title(‘Corrected with Hanning Window’);
2Centroid Energy Correction Method
clear all;
clc;
n=input(‘Please enter the number of points for centroid energy correction’)
Fs=1024;N=1024;
t =(0:N-1)/Fs;
tt=0:N-1;
hanning=0.5-0.5*cos(2*pi*tt/N);
x=5.3*cos(2*pi*123.4*t+20*pi/180);
x_hanning=5.3*cos(2*pi*123.4*t+20*pi/180).*hanning;
y = fft(x);
yh = fft(x_hanning);
% The “h” added later indicates Hanning window
Y=y(1:N/2)/N*2;
Yh=yh(1:N/2)/N*2;
f = Fs/2*linspace(0,1,N/2);
A=abs(Y);
Ah=abs(Yh);
subplot(221);
stem(f,A(1:N/2));
title(‘Uncorrected with Rectangular Window’);
grid on;
subplot(222);
stem(f,2*Ah(1:N/2));
title(‘Uncorrected with Hanning Window’);
grid on
% The factor of 2 in the plot function is the amplitude recovery coefficient
G=A.^2;
Gh=Ah.^2;
% Apply Rectangular Window
[Gmax,k]=max(A);
phmax=angle(Y(k));
f0fz=0;
f0fm=0;
for i=-n:n
f0fz=f0fz+(k+i)*G(k+i);
f0fm=f0fm+G(k+i);
end
f0=((f0fz/f0fm)-1)*Fs/N
am=sqrt(1*(f0fm))
% Amplitude recovery coefficient for rectangular window is 1
ph=(phmax+pi*(k-1-f0))*180/pi
A(k)=am;
f(k)=f0;
subplot(223);
stem(f,A(1:N/2));
title(‘Corrected with Rectangular Window’);
grid on
% Apply Hanning Window
[Gmaxh,kh]=max(Ah);
phmaxh=angle(Yh(kh));
f0hfz=0;
f0hfm=0;
for i=-n:n
f0hfz=f0hfz+(kh+i)*Gh(kh+i);
f0hfm=f0hfm+Gh(kh+i);
f0h=f0hfz/f0hfm;
end
f0h=(f0h-1)*Fs/N
amh=sqrt(2.667*(f0hfm))
% 2.66 is the amplitude recovery coefficient for Hanning window
phh=(phmaxh+pi*(kh-1-f0h))*180/pi
Ah(kh)=amh;
f(kh)=f0h;
subplot(224);
stem(f,Ah(1:N/2));
title(‘Corrected with Hanning Window’);
3FFT + FT Spectrum Correction Method
clear all;
clc;
Fs=1024;
N=1024;
t =(0:N-1)/Fs;
tt=0:N-1;
hanning=0.5-0.5*cos(2*pi*tt/N);
windowtype=input(‘Please select window type 1.Rectangular Window 2.Hanning Window’);
if windowtype==1
x=4.2366*cos(2*pi*63.2*t+23.8*pi/180);
% Time domain simulation function
elseif windowtype==2
x=4.2366*cos(2*pi*63.2*t+23.8*pi/180).*hanning;
else
error(‘Invalid selection, please reselect’);
end
y = fft(x);
Y=y(1:N/2+1)/N*2;
f=(0:N/2)*Fs/N;
subplot(211);
plot(f,abs(Y(1:N/2+1)));
grid on
A=abs(Y);
[Amax,k]=max(A);
if windowtype==1
Amax_uncorrect=Amax
% Amplitude before correction
elseif windowtype==2
Amax_uncorrect=Amax*2
end
phmax_uncorrect=angle(Y(k))*180/pi
% Phase before correction
f_uncorrect=k-1
% Frequency before correction
L=80;
% Number of points to refine
deltf=((k+1-1)*Fs/N-(k-1-1)*Fs/N)/L;
% Determine the frequency resolution after refinement
YY=zeros(1,N);
ff=(k-1-1)*Fs/N;
for i=1:L
for ii=1:N
YY(i)=YY(i)+x(ii)*exp(-j*2*pi*ff*(ii-1)/Fs);
end
ff=ff+deltf;
end
if windowtype==1;
A_correct=max(abs(YY)/N*2)
% Amplitude after correction
[YYmax,YYk]=max(YY);
f_correct=(k-1-1)*Fs/N+(YYk-1)*deltf
% Frequency after correction
phmax_correct=angle(YYmax)*180/pi
% Phase after correction
Y(k)=A_correct;f(k)=f_correct;
subplot(212);
plot(f,abs(Y(1:N/2+1)));
grid on
else windowtype==2;
A_correct=2*max(abs(YY)/N*2)
% Amplitude after correction
[YYmax,YYk]=max(YY);
f_correct=(k-1-1)*Fs/N+(YYk-1)*deltf
% Frequency after correction
phmax_correct=angle(YYmax)*180/pi
% Phase after correction
Y(k)=A_correct/2;
f(k)=f_correct;
% Amplitude divided by 2 to ensure the internal values are original values
subplot(212);
plot(f,2*abs(Y(1:N/2+1)));
grid on
% The factor of 2 is the amplitude recovery coefficient
end
~~~~~~~~~~~~~~~~
Running Results:
Theoretical Value
Amplitude: 4.2366 Frequency: 63.2 Phase: 23.8 degrees
With Rectangular Window
Before Correction
Amax_uncorrect =3.962471854470429
phmax_uncorrect =59.672485657326710
f_uncorrect =63
After Correction
A_correct =4.235275753915142
f_correct =63.200000000000003
phmax_correct =23.660397117658885
With Hanning Window
Before Correction
Amax_uncorrect = 4.128431340024557
phmax_uncorrect =59.800004751788116
f_uncorrect =63
After Correction
A_correct =4.236600313219102
f_correct =63.200000000000003
phmax_correct =23.800007456676489
4Time Domain Translation Method
% Fs: Sampling frequency
% N: Number of points for spectrum
% L: Number of translation points
clear all;
clc;
Fs=1024;
N=1024;
L=100;
t =(0:N+L-1)/Fs;
tt=0:N-1;
hanning=0.5-0.5*cos(2*pi*tt/N);
windowtype=input(‘Please select window type 1.Rectangular Window 2.Hanning Window’);
x=10.343*cos(2*pi*298.30453*t+240*pi/180);%.*hanning;
% Time series of L+N points
% Extract two segments of time series
for i=1:N
x1(i)=x(i);
x2(i)=x(i+L);
end
if windowtype==1
y1=fft(x1);
% Perform FFT transformation on the first segment with rectangular window
y2=fft(x2);
% Perform FFT transformation on the second segment with rectangular window
elseif windowtype==2
y1=fft(x1.*hanning);
% Perform FFT transformation on the first segment with Hanning window
y2=fft(x2.*hanning);
% Perform FFT transformation on the second segment with Hanning window
else
error(‘Invalid selection, please reselect’);
end
Y1=abs(y1(1:N/2)/N*2);
% Amplitude of the first segment
Y2=abs(y2(1:N/2)/N*2);
% Amplitude of the second segment
f=(1:N/2)*Fs/N;
subplot(211);
if windowtype==1
plot(f,Y1);
xlabel(‘f’);
ylabel(‘A’);
title(‘Before Correction with Rectangular Window’);
grid on
elseif windowtype==2
plot(f,2*Y1);
xlabel(‘f’);
ylabel(‘A’);
title(‘Before Correction with Hanning Window’);
grid on
end
[Y1Amax,k1]=max(Y1);
[Y2Amax,k2]=max(Y2);
phase1=angle(y1(k1));
% Phase corresponding to the peak of the first segment
phase2=angle(y2(k2));
% Phase corresponding to the peak of the second segment
if windowtype==1
A_uncorrect=Y1Amax
elseif windowtype==2
A_uncorrect=Y1Amax*2
end
f_uncorrect=(k1-1)*Fs/N
% Frequency before correction
phase_uncorrect=phase1*180/pi
% Phase before correction
delt=mod(phase2-phase1,2*pi);
% Adjust delt to be between (-pi, pi)
if delt<-pi
delt1=delt+2*pi;
elseif delt>pi
delt1=delt-2*pi;
else delt1=delt;
end
deltf=delt1/(2*pi*L/N);
f_correct=(k1-1+deltf)*Fs/N
phase_correct=(phase1-deltf*pi)*180/pi
Y_correct=zeros(1,N/2);
if windowtype==1
A_correct=Y1Amax/sinc(deltf)
Y_correct(k1)=A_correct;
f(k1)=f_correct;
subplot(212);
stem(f,Y_correct);
grid on
xlabel(‘f’);
ylabel(‘A’);
title(‘After Correction with Rectangular Window’);
elseif windowtype==2
A_correct=2/sinc(deltf)*Y1Amax*(1-deltf^2)
Y_correct(k2)=A_correct;
f(k2)=f_correct;
subplot(212);
stem(f,Y_correct);
grid on
xlabel(‘f’);
ylabel(‘A’);
title(‘After Correction with Hanning Window’);
end
~~~~~~~~~~~~~~~~
Running Results:
Theoretical Value:
Amplitude: 10.343
Frequency: 298.30453
Phase: 240
With Rectangular Window
Before Correction
A_uncorrect =8.830978191997250
f_uncorrect =298
phase_uncorrect =-65.283647874590685
After Correction
A_correct =10.362781259858098
f_correct =2.983068229594135e+002
phase_correct =-1.205117805690294e+002
With Hanning Window
Before Correction
A_uncorrect =9.739025234720254
f_uncorrect =298
phase_uncorrect =-65.184599901407665
After Correction
A_correct =10.342999982203294
f_correct =2.983045299993504e+002
phase_correct =-1.199999997844760e+002
5Phase Difference Method by Changing Window Length
% Fs: Sampling frequency
% N: Number of points for spectrum
% L: Number of translation points
clear all;
clc;
Fs=1024;
N=1024;
t =(0:N-1)/Fs;
windowtype=input(‘Please select window type 1.Rectangular Window 2.Hanning Window’);
x=10.343*cos(2*pi*298.30453*t+135*pi/180);
%.*hanning;% Time series of L+N points
if windowtype==1
y1=fft(x,N);
% Perform N-point FFT transformation on the signal
y2=fft(x,N/2);
% Perform N/2-point FFT transformation on the signal
elseif windowtype==2
y1=fft(x.*hann(N)’);
% Perform N-point FFT transformation on the signal
y2=fft(x(1:N/2).*hann(N/2)’);
% Perform N/2-point FFT transformation on the signal
else
error(‘Invalid selection, please reselect’);
end
Y1=abs(y1(1:N/2)/N*2);
% Amplitude of the first segment
Y2=abs(y2(1:N/4)/N*4);
% Amplitude of the second segment
f=(1:N/2)*Fs/N;
subplot(211);
if windowtype==1
plot(f,Y1);
xlabel(‘f’);
ylabel(‘A’);
title(‘Before Correction with Rectangular Window’);
grid on
elseif windowtype==2
plot(f,2*Y1);
xlabel(‘f’);
ylabel(‘A’);
title(‘Before Correction with Hanning Window’);
grid on
end
[Y1Amax,k1]=max(Y1);
[Y2Amax,k2]=max(Y2);
phase1=angle(y1(k1));
phase2=angle(y2(k2));
if windowtype==1
A_uncorrect=Y1Amax
% Uncorrected amplitude
elseif windowtype==2
A_uncorrect=Y1Amax*2
end
f_uncorrect=(k1-1)*Fs/N
% Uncorrected frequency
phase_uncorrect=phase1*180/pi
% Uncorrected phase angle
delt=mod(phase1-phase2,2*pi);
% Adjust delt to be between (-pi, pi)
if delt<-pi
delt1=delt+2*pi;
elseif delt>pi
delt1=delt-2*pi;
else delt1=delt;
end
deltf=2*(k2-1)-(k1-1)-2*delt1/pi;
f_correct=(k1-1-deltf)*Fs/N
% Corrected frequency
phase_correct=(phase1+deltf*pi)*180/pi
% Corrected phase
Y_correct=zeros(1,N/2);
if windowtype==1
A_correct=Y1Amax/sinc(deltf)
Y_correct(k1)=A_correct;
f(k1)=f_correct;
subplot(212);
stem(f,Y_correct);
grid on
xlabel(‘f’);
ylabel(‘A’);
title(‘After Correction with Rectangular Window’);
elseif windowtype==2
A_correct=2/sinc(deltf)*Y1Amax*(1-deltf^2)
Y_correct(k2)=A_correct;
f(k2)=f_correct;
subplot(212);
stem(f,Y_correct);
grid on
xlabel(‘f’);
ylabel(‘A’);
title(‘After Correction with Hanning Window’);
end
~~~~~~~~~~~~~~~~
Running Results:
Theoretical Value
Frequency: 298.30453
Amplitude: 10.343
Phase: 135
With Rectangular Window
Before Correction
A_uncorrect =8.836556159610320
f_uncorrect =298
phase_uncorrect =-1.701829534720524e+002
After Correction
A_correct =10.346244554887681
f_correct =2.983047477837129e+002
phase_correct =-2.250375545403775e+002
With Hanning Window
Before Correction
A_uncorrect =9.730664267447002
f_uncorrect =298
phase_uncorrect =-1.702381307852827e+002
After Correction
A_correct =10.334120533701167
f_correct =2.983045300071315e+002
phase_correct =-2.250535320689407e+002
The program is for reference only, and this public account is not responsible for the correctness of the program!

This article is originally by Zhao Yixu, a member of the Sound and Vibration Forum, and the program references the book “Discrete Spectrum Correction Technology” by Ding Kang and related posts by Yang ZJ, the moderator of the Sound and Vibration Forum. The copyright belongs to the original author, and reprinting requires contacting the original author for authorization and indicating the source (Sound and Vibration Forum: vibunion.com or Sound and Vibration Home WeChat Public Account: vibunion).