ivan@161
|
1 function reconstructed=AMT_reconstruct(V, Problem)
|
ivan@161
|
2 %% Reconstruction of midi file from representation in the given dictionary
|
ivan@161
|
3 %
|
ivan@161
|
4 % SMALL_midiGenerate is a part of SMALLbox and can be use to reconstruct
|
ivan@161
|
5 % a midi file given representation of the training set (V) in the
|
ivan@161
|
6 % dictionary Problem.A.
|
ivan@161
|
7 % Output is reconstructed structure with two fields:
|
ivan@161
|
8 % - reconstructed.notes - matrix with transcribed notes
|
ivan@161
|
9 % - reconstructed.midi - midi representation of transcription
|
ivan@161
|
10
|
ivan@161
|
11 %
|
ivan@161
|
12 % Centre for Digital Music, Queen Mary, University of London.
|
ivan@161
|
13 % This file copyright 2009 Ivan Damnjanovic.
|
ivan@161
|
14 %
|
ivan@161
|
15 % This program is free software; you can redistribute it and/or
|
ivan@161
|
16 % modify it under the terms of the GNU General Public License as
|
ivan@161
|
17 % published by the Free Software Foundation; either version 2 of the
|
ivan@161
|
18 % License, or (at your option) any later version. See the file
|
ivan@161
|
19 % COPYING included with this distribution for more information.
|
ivan@161
|
20 %%
|
ivan@161
|
21 U=Problem.A; % Dictionary used for representation
|
ivan@161
|
22 fs=Problem.fs; % Sampling rate
|
ivan@161
|
23 f=Problem.f; % vector of frequencies at wihch spectrogram is computed
|
ivan@161
|
24
|
ivan@161
|
25 ts=(Problem.windowSize*(1-Problem.overlap))/fs; %size of an analysis frame in seconds
|
ivan@161
|
26
|
ivan@161
|
27 %%
|
ivan@161
|
28 % Components pitch estimation using modified SWIPE algorithm by Arthuro
|
ivan@161
|
29 % Camacho
|
ivan@161
|
30 %
|
ivan@161
|
31 % Columns of matrix U are spectrograms of the notes learned from the
|
ivan@161
|
32 % training set. We are estimating pitches of these notes by also
|
ivan@161
|
33 % restricting pitch values to the one of the 88 piano notes.
|
ivan@161
|
34
|
ivan@161
|
35 pitch=zeros(size(U,2),1);
|
ivan@161
|
36
|
ivan@161
|
37 for i=1:size(U,2)
|
ivan@161
|
38
|
ivan@161
|
39 pitch(i) = SMALL_swipe(U(:,i),fs, f, [27.50 8192], 1/12);
|
ivan@161
|
40
|
ivan@161
|
41 end
|
ivan@161
|
42
|
ivan@161
|
43 %%
|
ivan@161
|
44 % If some of columns of U have the same pitch, their contribution to the
|
ivan@161
|
45 % score (matrix V) is summed.
|
ivan@161
|
46
|
ivan@161
|
47 [Ps,idx]=sort(pitch);
|
ivan@161
|
48 ndp=1;
|
ivan@161
|
49 Pd(ndp)=Ps(1);
|
ivan@161
|
50 Vnew(ndp,:)=V(idx(1),:);
|
ivan@161
|
51 for i=2:88
|
ivan@161
|
52 if Ps(i)> Ps(i-1)
|
ivan@161
|
53
|
ivan@161
|
54 ndp=ndp+1;
|
ivan@161
|
55 Vnew(ndp,:)=V(idx(i),:);
|
ivan@161
|
56 Pd(ndp)=Ps(i);
|
ivan@161
|
57
|
ivan@161
|
58 else
|
ivan@161
|
59 Vnew(ndp,:)=Vnew(ndp,:)+V(idx(i),:);
|
ivan@161
|
60 end
|
ivan@161
|
61 end
|
ivan@161
|
62 %%
|
ivan@161
|
63 % Generate midi matrix
|
ivan@161
|
64
|
ivan@161
|
65 midx=0;
|
ivan@161
|
66 for i=1:ndp
|
ivan@161
|
67
|
ivan@161
|
68 % Threshold for finding onsets and offsets of notes
|
ivan@161
|
69
|
ivan@161
|
70 thr=mean(Vnew(i,:));%+std(Vnew(i,:));
|
ivan@161
|
71
|
ivan@161
|
72 if(Pd(i)~=0)
|
ivan@161
|
73 for j=1:size(Vnew,2)
|
ivan@161
|
74 if Vnew(i,j)<thr
|
ivan@161
|
75 Vnew(i,j)=0;
|
ivan@161
|
76 if(j>1)
|
ivan@161
|
77 if (Vnew(i,j-1)==1)
|
ivan@161
|
78 try
|
ivan@161
|
79 M(midx,6)=(j-1)*ts;
|
ivan@161
|
80 if (M(midx,6)-M(midx,5))<2*ts
|
ivan@161
|
81 midx=midx-1;
|
ivan@161
|
82 end
|
ivan@161
|
83 catch
|
ivan@161
|
84 pause;
|
ivan@161
|
85 end
|
ivan@161
|
86 end
|
ivan@161
|
87 end
|
ivan@161
|
88 else
|
ivan@161
|
89 Vnew(i,j)=1;
|
ivan@161
|
90 if(j>1)
|
ivan@161
|
91 if (Vnew(i,j-1)==0)
|
ivan@161
|
92 midx=midx+1;
|
ivan@161
|
93 M(midx,1)=1;
|
ivan@161
|
94 M(midx,2)=1;
|
ivan@161
|
95 M(midx,3)=69 +round( 12 *log2(Pd(i)/440));
|
ivan@161
|
96 M(midx,4)=80;
|
ivan@161
|
97 M(midx,5)=(j-1)*ts;
|
ivan@161
|
98 end
|
ivan@161
|
99 else
|
ivan@161
|
100 midx=midx+1;
|
ivan@161
|
101 M(midx,1)=1;
|
ivan@161
|
102 M(midx,2)=1;
|
ivan@161
|
103 M(midx,3)=69 + round(12 *log2(Pd(i)/440));
|
ivan@161
|
104 M(midx,4)=80;
|
ivan@161
|
105 M(midx,5)=0;
|
ivan@161
|
106 end
|
ivan@161
|
107 end
|
ivan@161
|
108 end
|
ivan@161
|
109 if M(midx,6)==0
|
ivan@161
|
110 M(midx,6)=(j-1)*ts;
|
ivan@161
|
111 end
|
ivan@161
|
112 end
|
ivan@161
|
113 end
|
ivan@161
|
114
|
ivan@161
|
115 M=sortrows(M,5);
|
ivan@161
|
116 reconstructed.notes=M;
|
ivan@161
|
117 reconstructed.midi = matrix2midi(M);
|