Pastikan komputer anda sudah terinstall octave disini.
Short-Time Fourier Transform (STFT)
Window yang digunakan adalah setengah sinus seperti pada persamaan di bawah ini.
$\omega (n) = \sin \Big(\frac{\pi}{N}(n+0.5)\Big), \ \ \ n = 0, ..., N - 1$
dimana $N$ adalah panjang window. Overlapping antar window adalah 50% dari panjang window. Nilai ini dipilih untuk mendapatkan "perfect reconstruction" saat melakukan invers. STFT diperoleh dengan cara mentransformasikan sinyal untuk masing-masing window ke domain frekuensi seperti pada persamaan di bawah ini.
$S(m,\omega) = \textrm{DTFT}\{x(n) \cdot \omega(n-m \cdot N/2)\}$
dimana $\omega$ adalah indek frekuensi dan $m$ adalah indek waktu. Simpan code berikut ini dengan nama "stft_sin.m"
==============================================
function X = stft_sin(x,N,nfft)
% vektor baris
n = [0:N-1]';
x = x';
% Zero-padding
ncol = ceil(2*(length(x)-N/2)/N);
if (ncol+1)*N/2 > length(x)
x = [x; zeros((ncol+1)*N/2-length(x),1)];
end
x = [zeros(N/2,1); x; zeros(N/2,1)];
% Window sinus
Nindex = (length(x)-N/2)*2/N;
window = repmat(sin((n+0.5)*pi/(N)),1,Nindex);
% Proses Windowing
colindex = 1+ (0:Nindex-1)*(N/2);
rowindex = n+1;
y = zeros(N,Nindex);
y(:) = x(rowindex(:,ones(1,Nindex))+ colindex(ones(N,1),:)-1);
y = y.*window;
% FFT
X = fft(y,nfft);
X = X(1:nfft/2+1,:);
==============================================
Untuk menguji "stft_sin.m" berjalan dengan baik atau tidak, kita akan membangkitkan sinyal seperti pada persamaan berikut ini
$x(n) \begin{cases} \sin(2 \pi 1000 n) & \quad \text{if } \ \ t \geq 0 \ \ \& \ \ t < 1 \\ \sin(2 \pi 2000 n) & \quad \text{if } \ \ t \geq 1 \ \ \& \ \ t < 2 \\ \sin(2 \pi 3000 n) & \quad \text{if } \ \ t \geq 2 \ \ \& \ \ t < 3 \\ \end{cases}$
==============================================
close all
clear
clc
% Sinyal
fs = 10000;
t = 0:1/fs:3;
x = zeros(size(t));
for i = 1:3
range_t = double(t>=(i-1)*max(t)/3 & t <i*max(t)/3);
x = x + sin(2*pi*1000*i*t).*range_t;
end
% STFT
nfft = 1024;
N = nfft/4;
X = stft_sin(x,N,nfft);
% plot
F = linspace(0,1,size(X,2))*fs/2;
T = linspace(min(t),max(t),size(X,1));
figure
imagesc(T,F,abs(X)/max(max(abs(X))))
colorbar()
axis xy
axis square
xlabel('waktu (sekon)')
ylabel('frekuensi (Hz)')
==============================================
Invers Short-Time Fourier Transform (ISTFT)
Berikut ini merupakan persamaan untuk ISTFT
$x(n) = \frac{\displaystyle \sum_{m} s(m,n) \cdot \omega(n-m \cdot N/2)}{\displaystyle \sum_{m} p(n-m \cdot N/2)}$
$s(m,n) = \textrm{DTFT}^{-1} \{S(m,\omega)\}$
$p(n) = \omega^2(n)$
dan Invers ini dikatakan "perfect reconstruction" jika memenuhi kondisi sebagai berikut.
$\displaystyle \sum_{m} p(n-m \cdot N/2) = 1$
Selanjutnya, Simpan code berikut ini dengan nama "istft_sin.m".
==============================================
function x = istft_sin(X,N,ndata)
% IFFT
X = [X; conj(X(end-1:-1:2,:))];
s = real(ifft(X));
s = s(1:N,:);
x = zeros(1,(size(s,2)+1)*N/2);
x = x(:);
p = x;
% Window sinus
n = 0:N-1; n=n(:);
window = repmat(sin((n+0.5)*pi/(N)),1,size(X,2));
for i = 1:size(X,2)
x(1+(i-1)*N/2:(i+1)*N/2) = x(1+(i-1)*N/2:(i+1)*N/2) + s(:,i).*window(:,i);
p(1+(i-1)*N/2:(i+1)*N/2) = p(1+(i-1)*N/2:(i+1)*N/2) + window(:,i).^2;
end
x = x./p;
x = x(N/2+1:ndata+N/2);
x = x';
==============================================
dan run program berikut ini untuk mengecek apakah sinyal sebelum dan sesudah invers adalah sama (perfect reconstruction).
==============================================
close all
clear
clc
fs = 10000;
t = 0:1/fs:3;
x = zeros(size(t));
for i = 1:3
range_t = double(t>=(i-1)*max(t)/3 & t <i*max(t)/3);
x = x + sin(2*pi*5*i*t).*range_t;
end
% STFT
nfft = 1024;
N = nfft/4;
X = stft_sin(x,N,nfft);
% ISTFT
ndata = length(t);
xnew = istft_sin(X,N,ndata);
figure
subplot(211)
plot(t,x,'LineWidth',1)
ylim([-1.1 1.1])
subplot(212)
plot(t,xnew,'LineWidth',1)
ylim([-1.1 1.1])
% Cek nilai perbedaan maksimum
max(abs(x-xnew))
==============================================
Code-nya dapat didownload di link ini.
Selamat mencoba dan semoga bermanfaat.
Ivan W. Selesnick, Short-Time Fourier Transform and Its Inverse, April 14, 2009
No comments:
Post a Comment