2015-07-23 2 views
3

У меня возникла проблема с основным свойством времени/частоты, реализованным в скрипте Matlab. Свойство:Задержка сигнала во временной области с изменением фазы в частотной области после FFT

im1

Я пытался реализовать это в сценарии Matlab. Я предположил синусоидальный сигнал с частотой 5 Гц с частотой, частотой дискретизации 800 Гц, и я хочу задержать этот сигнал на 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'); 

И выход сюжет:

output plot

Где проблема? Как я могу достичь правильной задержки?

Благодаря

+0

К сожалению для изображений ссылки, но я не могу отправить изображения из-за мою репутацию. –

ответ

1

Проблема заключается не в реализации, а в свойствах БПФ (соответственно ДПФ): формула, которую вы опубликовали для временной задержки, верна, но вы должны иметь в виду, что это вы делая круговой сдвиг. Это означает, что все части сигнала от 2.2s до 4.0s будут скопированы в начало вывода. Это именно то, что вы видите:

before

Сигнал, вы хотите запустился на 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)); 

Который дает нам

result

+0

Большое спасибо, это решение работает, и я наконец понял, как работает FFT. –

0

Я считаю, что вам нужно сделать больше FFT для размещения сдвига/задержки. Вы можете заставить это путем нулевого ввода ввода с правильным количеством нулей (> 1440 с предоставленной частотой выборки и суммой задержки). Затем вы получите желаемый результат.

Sine shift with pad

Ваш оригинальный сюжет был хвост оборачивать вокруг, потому что FFT/IFFT были ограничены 4096 бункера, что было не достаточно, чтобы включить весь сдвинут сигнала + ведущие нули.

0

Вы можете попробовать это:

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 ,

результат был бы таким следующим образом:

enter image description here

Смежные вопросы