I have a problem with a basic time/frequency property implemented in a Matlab script. The property is:

I've tried to implement this in a Matlab script. 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. 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. This means that all the signal parts from 2.2s to 4.0s will be copied to the beginning of the output. 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. Small calculation: your input signal is 1 x 3201, i.e. it will be zero-padded with 895 zeros. In seconds, this is 1.1187 seconds of zeros. The circular shift will insert the last 1.8s at the beginning, i.e. 1.8 - 1.1187 = 0.86 seconds will not be zeros but contain a sine. 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

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With