[英]Delay a signal in time domain with a phase change in the frequency domain after FFT
我在Matlab脚本中实现了基本时间/频率属性的问题。 该物业是:
我试图在Matlab脚本中实现它。 我假设一个频率值为5Hz的正弦信号,采样频率等于800Hz,我想把这个信号延迟1.8秒。 所以我实现了这个脚本:
Fs = 800;
Time_max = 4; % seconds
t = 0:(1/Fs):Time_max;
delay = 1.8; % One second of delay
f = 5; %Hz
y = sin(2 * pi * f * t);
figure
subplot(2,1,1)
plot(t,y);
xlabel('time (s)')
legend('Original');
%FFT
SIZE = 2^nextpow2(length(y));
Y = fft(y,SIZE);
df = Fs/SIZE;
f= -Fs/2:df:Fs/2 - df;
for k = 1:SIZE
Y(k) = Y(k)*exp(-(1i*2*pi*f(k)*delay));
end
subplot(2,1,2)
plot(real(ifft(Y)),'r')
legend('Shifted');
输出图是:
问题出在哪儿? 如何实现正确的延时?
谢谢
问题不在于实现,而在于FFT的属性(分别是DFT):你发布的时间延迟的公式是正确的,但你必须记住,你正在进行循环移位 。 这意味着从2.2s到4.0s的所有信号部分将被复制到输出的开头。 这正是你所看到的:
您想要的信号从1.8s开始,但是从0到0.6837s,由于循环移位而插入的部分。 小计算:输入信号为1 x 3201
,即零填充895个零。 在几秒钟内,这是1.1187秒的零。 循环移位将在开头插入最后的1.8s,即1.8 - 1.1187 = 0.86秒不会为零而是包含正弦。 这正是我们在情节中看到的数量。
为了避免这种影响,您必须用至少为延迟信号的零点填充输入信号。 在你的情况下,将是
Fs = 800;
Time_max = 4; % seconds
t = 0:(1/Fs):Time_max;
delay = 1.8; % One second of delay
f = 5; %Hz
y = sin(2 * pi * f * t);
y = [y, zeros(1,delay*Fs)]; % Zero-pad the signal by the amount of delay
SIZE = 2^nextpow2(length(y));
Y = fft(y,SIZE);
df = Fs/SIZE;
f= -Fs/2:df:Fs/2 - df;
for k = 1:SIZE
Y(k) = Y(k)*exp(-(1i*2*pi*f(k)*delay));
end
td = (0:SIZE-1)/Fs;
yd = real(ifft(Y));
这给了我们
你可以试试这个:
Fs = 800;
Time_max = 4; % seconds
t = 0:(10/Fs):Time_max;
delay = 1.8; % One second of delay
f = 5; %Hz
y = sin(2 * pi * f * t);
figure;subplot(2,1,1);plot(t,y);xlabel('time (s)')
legend('Original');
w = 2*pi*f;
X=fft(y);
Y=X.*exp(-1i*w*(t+delay));
ynew = real(ifft(Y));
subplot(2,1,2);plot(ynew);
legend('Shifted');
考虑使用矢量化实现,您可以摆脱for-loop
。
结果如下:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.