【问题标题】:Delay a signal in time domain with a phase change in the frequency domain after FFT在 FFT 之后延迟时域中的信号,并在频域中发生相位变化
【发布时间】:2015-07-23 12:02:47
【问题描述】:

我对在 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');

输出图是:

问题出在哪里?如何实现正确的时间延迟?

谢谢

【问题讨论】:

  • 抱歉图片链接,但由于我的声誉,我无法发布图片。

标签: matlab signal-processing fft


【解决方案1】:

问题不在于实现,而在于 FFT(分别为 DFT)的属性:您发布的时间延迟公式是正确的,但您必须记住,您正在做循环移位。这意味着从 2.2s 到 4.0s 的所有信号部分都将被复制到输出的开头。这正是您所看到的:

您想要的信号确实从 1.8s 开始,但是从 0 到 0.6837s 存在由于循环移位而插入的部分。小计算:您的输入信号是1 x 3201,即它将用 895 个零填充零。以秒为单位,这是 1.1187 秒的零。循环移位将在开头插入最后 1.8 秒,即 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));

这给了我们

【讨论】:

  • 非常感谢,这个解决方案有效,我终于明白FFT是如何工作的了。
【解决方案2】:

我认为您需要采用更大的 FFT 来适应偏移/延迟。您可以通过使用适当数量的零(> 1440 与您提供的采样频率和延迟量)对输入进行零填充来强制执行此操作。然后你就会得到想要的结果。

由于 FFT/IFFT 被限制为 4096 个 bin,因此您的原始图有尾部缠绕,这不足以合并整个移位信号 + 前导零。

【讨论】:

    【解决方案3】:

    你可以试试这个:

    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

    结果如下:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2023-03-11
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多