Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. The property is:

im1

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 :

output plot

Where is the problem? How can I achieve the correct time delay?

Thanks

like image 268
Taglia_90 Avatar asked Oct 23 '25 08:10

Taglia_90


1 Answers

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:

before

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

result

like image 159
hbaderts Avatar answered Oct 26 '25 04:10

hbaderts