1 | function D = stft(x, f, w, h, sr)
|
---|
2 | % D = stft(X, F, W, H, SR) Short-time Fourier transform.
|
---|
3 | % Returns some frames of short-term Fourier transform of x. Each
|
---|
4 | % column of the result is one F-point fft (default 256); each
|
---|
5 | % successive frame is offset by H points (W/2) until X is exhausted.
|
---|
6 | % Data is hann-windowed at W pts (F), or rectangular if W=0, or
|
---|
7 | % with W if it is a vector.
|
---|
8 | % Without output arguments, will plot like sgram (SR will get
|
---|
9 | % axes right, defaults to 8000).
|
---|
10 | % See also 'istft.m'.
|
---|
11 | % dpwe 1994may05. Uses built-in 'fft'
|
---|
12 | % $Header: /home/empire6/dpwe/public_html/resources/matlab/pvoc/RCS/stft.m,v 1.4 2010/08/13 16:03:14 dpwe Exp $
|
---|
13 |
|
---|
14 | if nargin < 2; f = 256; end
|
---|
15 | if nargin < 3; w = f; end
|
---|
16 | if nargin < 4; h = 0; end
|
---|
17 | if nargin < 5; sr = 8000; end
|
---|
18 |
|
---|
19 | % expect x as a row
|
---|
20 | if size(x,1) > 1
|
---|
21 | x = x';
|
---|
22 | end
|
---|
23 |
|
---|
24 | s = length(x);
|
---|
25 |
|
---|
26 | if length(w) == 1
|
---|
27 | if w == 0
|
---|
28 | % special case: rectangular window
|
---|
29 | win = ones(1,f);
|
---|
30 | else
|
---|
31 | if rem(w, 2) == 0 % force window to be odd-len
|
---|
32 | w = w + 1;
|
---|
33 | end
|
---|
34 | halflen = (w-1)/2;
|
---|
35 | halff = f/2; % midpoint of win
|
---|
36 | halfwin = 0.5 * ( 1 + cos( pi * (0:halflen)/halflen));
|
---|
37 | win = zeros(1, f);
|
---|
38 | acthalflen = min(halff, halflen);
|
---|
39 | win((halff+1):(halff+acthalflen)) = halfwin(1:acthalflen);
|
---|
40 | win((halff+1):-1:(halff-acthalflen+2)) = halfwin(1:acthalflen);
|
---|
41 | end
|
---|
42 | else
|
---|
43 | win = w;
|
---|
44 | end
|
---|
45 |
|
---|
46 | w = length(win);
|
---|
47 | % now can set default hop
|
---|
48 | if h == 0
|
---|
49 | h = floor(w/2);
|
---|
50 | end
|
---|
51 |
|
---|
52 | c = 1;
|
---|
53 |
|
---|
54 | % pre-allocate output array
|
---|
55 | d = zeros((1+f/2),1+fix((s-f)/h));
|
---|
56 |
|
---|
57 | for b = 0:h:(s-f)
|
---|
58 | u = win.*x((b+1):(b+f));
|
---|
59 | t = fft(u);
|
---|
60 | d(:,c) = t(1:(1+f/2))';
|
---|
61 | c = c+1;
|
---|
62 | end;
|
---|
63 |
|
---|
64 | % If no output arguments, plot a spectrogram
|
---|
65 | if nargout == 0
|
---|
66 | tt = [0:size(d,2)]*h/sr;
|
---|
67 | ff = [0:size(d,1)]*sr/f;
|
---|
68 | imagesc(tt,ff,20*log10(abs(d)));
|
---|
69 | axis('xy');
|
---|
70 | xlabel('time / sec');
|
---|
71 | ylabel('freq / Hz')
|
---|
72 | % leave output variable D undefined
|
---|
73 | else
|
---|
74 | % Otherwise, no plot, but return STFT
|
---|
75 | D = d;
|
---|
76 | end
|
---|