简体   繁体   English

在FFT之后,在时域中延迟信号,频域中的相位变化

[英]Delay a signal in time domain with a phase change in the frequency domain after FFT

I have a problem with a basic time/frequency property implemented in a Matlab script. 我在Matlab脚本中实现了基本时间/频率属性的问题。 The property is: 该物业是:

IM1

I've tried to implement this in a Matlab script. 我试图在Matlab脚本中实现它。 I've supposed a sinusoidal signal with 5Hz of frequency value, Sampling frequency equal to 800Hz and I want to delay this signal by 1.8 seconds. 我假设一个频率值为5Hz的正弦信号,采样频率等于800Hz,我想把这个信号延迟1.8秒。 So I've implemented this script: 所以我实现了这个脚本:

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');

And the output plot is : 输出图是:

输出图

Where is the problem? 问题出在哪儿? How can I achieve the correct time delay? 如何实现正确的延时?

Thanks 谢谢

The problem is not in the implementation, but lies within the properties of the FFT (respectively of the DFT): The formula you posted for a time delay is correct, but you have to keep in mind, that it you are doing a circular shift . 问题不在于实现,而在于FFT的属性(分别是DFT):你发布的时间延迟的公式是正确的,但你必须记住,你正在进行循环移位 This means that all the signal parts from 2.2s to 4.0s will be copied to the beginning of the output. 这意味着从2.2s到4.0s的所有信号部分将被复制到输出的开头。 This is exactly what you see: 这正是你所看到的:

之前

The signal you want does start at 1.8s, but from 0 to 0.6837s there is the part which is inserted due to the circular shift. 您想要的信号从1.8s开始,但是从0到0.6837s,由于循环移位而插入的部分。 Small calculation: your input signal is 1 x 3201 , ie it will be zero-padded with 895 zeros. 小计算:输入信号为1 x 3201 ,即零填充895个零。 In seconds, this is 1.1187 seconds of zeros. 在几秒钟内,这是1.1187秒的零。 The circular shift will insert the last 1.8s at the beginning, ie 1.8 - 1.1187 = 0.86 seconds will not be zeros but contain a sine. 循环移位将在开头插入最后的1.8s,即1.8 - 1.1187 = 0.86秒不会为零而是包含正弦。 This is exactly the amount we see in the plot. 这正是我们在情节中看到的数量。

To avoid this effect, you have to pad the input signal with at least the amount of zeros by which you delay the signal. 为了避免这种影响,您必须用至少为延迟信号的零点填充输入信号。 In your case that would be 在你的情况下,将是

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));

Which gives us 这给了我们

结果

I believe you need to take a larger FFT to accommodate the shift/delay. 我相信您需要采用更大的FFT来适应移位/延迟。 You could force this by zero-padding the input with the proper number of zero's (> 1440 with your provided sampling frequency and delay amount). 您可以通过使用适当数量的零(使用您提供的采样频率和延迟量>> 1440)对输入进行零填充来强制执行此操作。 Then you get the desired result. 然后你得到了想要的结果。

用垫正弦移位

Your original plot had the tail wrapping around because the FFT/IFFT were limited to 4096 bins, which was not enough to incorporate the entire shifted signal + leading zeros. 你原来的情节有尾巴缠绕,因为FFT / IFFT限制在4096个二进制位,这不足以包含整个移位信号+前导零。

You can try this: 你可以试试这个:

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');

Consider that using vectorized implementation, you can get rid of the for-loop . 考虑使用矢量化实现,您可以摆脱for-loop

the result would be such as follows: 结果如下:

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM