Delay of signal in time domain with phase change in frequency domain after FFT

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

im1

I tried to implement this in a Matlab script. I assumed a 5Hz sine wave with a sampling rate of 800Hz and I want to delay this signal by 1.8 seconds. So I 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 graph:

withdrawal schedule

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

thank

+3


source to share


3 answers


The problem is not with the implementation, but with the properties of the FFT (respectively DFT): The formula you posted for the time delay is correct, but you must keep in mind that you are doing a circular shift. This means that all parts of the waveform 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 starts at 1.8s, but there is a part from 0 to 0.6837s that is inserted due to the circular shift. A little calculation: your input signal 1 x 3201

, that is, it will be zero followed by 895 zeros. In seconds, this is 1.1187 seconds of zeros. A circular shift will insert the last 1.8s at the start, i.e. 1.8 - 1.1187 = 0.86 seconds will not be zeros but contain sine. This is exactly the amount that we see in the plot.

To avoid this effect, you must superimpose the input signal with at least the number of zeros over which you delay the signal. In your case it 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));

      

What gives us

result

+1


source


I believe you need to do a larger FFT in order to accommodate the offset / delay. You can force this by nulling the input with the correct number of zeros (> 1440 with the sample rate and delay sum provided). Then you will get the desired result.

Sine Shift with Pad



Your original plot had a tail wrap because the FFT / IFFT was limited to 4096 cells, which was not enough to include the entire shifted signal + leading zeros.

0


source


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

      

Note that with a vectorized implementation you can get rid of for-loop

.

the result will look like this:

enter image description here

0


source







All Articles