我遇到了在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');
输出图是:
问题出在哪里?如何实现正确的时间延迟?
由于
答案 0 :(得分:1)
问题不在于实现,而在于FFT的属性(分别是DFT):你发布的时间延迟的公式是正确的,但你必须记住,你正在做的事情循环移位。这意味着从2.2s到4.0s的所有信号部分将被复制到输出的开头。这正是你所看到的:
您想要的信号从1.8秒开始,但是从0到0.6837秒,由于循环移位而插入的部分。小计算:您的输入信号为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));
这给了我们
答案 1 :(得分:0)
我相信您需要采用更大的FFT来适应移位/延迟。您可以通过使用适当数量的零(使用您提供的采样频率和延迟量,> 1440)对输入进行零填充来强制执行此操作。然后你得到了理想的结果。
你原来的情节有尾巴缠绕,因为FFT / IFFT限制在4096个分档,这不足以合并整个移位信号+前导零。
答案 2 :(得分:0)
你可以试试这个:
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
。
结果如下: