yading@10
|
1 function X = stft_peak(x, w, N, H, threshold)
|
yading@10
|
2 % Analysis/synthesis of a sound using the short-time fourier transform
|
yading@10
|
3 % x: input sound,
|
yading@10
|
4 % w: analysis window (odd number of samples required)
|
yading@10
|
5 % N: FFT size,
|
yading@10
|
6 % H: hop size
|
yading@10
|
7 % y: output sound
|
yading@10
|
8 lengthx = length(x); % length of sound signal
|
yading@10
|
9 w = w/sum(w); % normalize window
|
yading@10
|
10 W = length(w); % window size (odd)
|
yading@10
|
11 W2 = (W-1)/2; % half window
|
yading@10
|
12 N2 = N/2+1; % half FFT size
|
yading@10
|
13
|
yading@10
|
14 p_start = 1+W2; % first frame pointer
|
yading@10
|
15 p_end = lengthx-W2; % last frame pointer
|
yading@10
|
16 fft_buffer = zeros(N,1); % FFT buffer
|
yading@10
|
17 for g=p_start:H:p_end % advance hop size each loop
|
yading@10
|
18 % ANALYSIS
|
yading@10
|
19 xw = w(1:W)'.*x(g-W2:g+W2); % multiply window by input frame
|
yading@10
|
20 fft_buffer(1:W2+1) = xw(W2+1:W); % adjust buffer for zero-phase computation
|
yading@10
|
21 fft_buffer(N-W2+1:N) = xw(1:W2);
|
yading@10
|
22 X = fft(fft_buffer); % FFT of current buffer
|
yading@10
|
23 mX = 20*log10(abs(X(1:N2))); % magnitude spectrum
|
yading@10
|
24 pX = unwrap(angle(X(1:N2))); % phase spectrum (unwrapped)
|
yading@10
|
25 ploc = 1+find((mX(2:N2-1)>threshold).*(mX(2:N2-1)>mX(3:N2)).*(mX(2:N2-1)>mX(1:N2-2)));
|
yading@10
|
26 pmag = mX(ploc);
|
yading@10
|
27 pphase = pX(ploc);
|
yading@10
|
28 plength = length(ploc);
|
yading@10
|
29 if(mod((g-p_start)/H+1,(floor(p_end/H/5)))==0) % select only 5 equally distributed frames of the sound
|
yading@10
|
30 figure
|
yading@10
|
31 subplot(2,1,1)
|
yading@10
|
32 plot(mX) % plot magnitude and phase spectrums
|
yading@10
|
33 hold on
|
yading@10
|
34 plot(ploc(1:plength),pmag(1:plength),'xr'); % add peaks to the plot
|
yading@10
|
35 xlim([1 N2])
|
yading@10
|
36 ylim([-80 0])
|
yading@10
|
37 title('Magnitude spectrum of frame')
|
yading@10
|
38 ylabel('Magnitude spectrum (dB)')
|
yading@10
|
39 xlabel('Frequency (rad)')
|
yading@10
|
40 display(['Peak positions: ' num2str(ploc')]);
|
yading@10
|
41 hold off
|
yading@10
|
42 subplot(2,1,2)
|
yading@10
|
43 plot(pX) % same with the phase
|
yading@10
|
44 hold on
|
yading@10
|
45 plot(ploc(1:plength),pphase(1:plength),'xr');
|
yading@10
|
46 xlim([1 N2])
|
yading@10
|
47 % ylim([-pi pi])
|
yading@10
|
48 % pause()
|
yading@10
|
49 hold off
|
yading@10
|
50 end
|
yading@10
|
51 end
|