ivan@161: function reconstructed=AMT_reconstruct(V, Problem)
ivan@161: %% Reconstruction of midi file from representation in the given dictionary
ivan@161: %   
ivan@161: %   SMALL_midiGenerate is a part of SMALLbox and can be use to reconstruct
ivan@161: %   a midi file given representation of the training set (V) in the
ivan@161: %   dictionary Problem.A.
ivan@161: %   Output is reconstructed structure with two fields:
ivan@161: %   -   reconstructed.notes - matrix with transcribed notes
ivan@161: %   -   reconstructed.midi - midi representation of transcription
ivan@161: 
ivan@161: %
ivan@161: %   Centre for Digital Music, Queen Mary, University of London.
ivan@161: %   This file copyright 2009 Ivan Damnjanovic.
ivan@161: %
ivan@161: %   This program is free software; you can redistribute it and/or
ivan@161: %   modify it under the terms of the GNU General Public License as
ivan@161: %   published by the Free Software Foundation; either version 2 of the
ivan@161: %   License, or (at your option) any later version.  See the file
ivan@161: %   COPYING included with this distribution for more information.
ivan@161: %%
ivan@161: U=Problem.A;    %   Dictionary used for representation
ivan@161: fs=Problem.fs;  %   Sampling rate
ivan@161: f=Problem.f;    %   vector of frequencies at wihch spectrogram is computed
ivan@161: 
ivan@161: ts=(Problem.windowSize*(1-Problem.overlap))/fs; %size of an analysis frame in seconds
ivan@161: 
ivan@161: %%
ivan@161: % Components pitch estimation using modified SWIPE algorithm by Arthuro
ivan@161: % Camacho
ivan@161: % 
ivan@161: % Columns of matrix U are spectrograms of the notes learned from the
ivan@161: % training set. We are estimating pitches of these notes by also
ivan@161: % restricting pitch values to the one of the 88 piano notes. 
ivan@161: 
ivan@161: pitch=zeros(size(U,2),1);
ivan@161: 
ivan@161: for i=1:size(U,2)
ivan@161:     
ivan@161:     pitch(i) = SMALL_swipe(U(:,i),fs, f, [27.50 8192], 1/12);
ivan@161:     
ivan@161: end
ivan@161: 
ivan@161: %%
ivan@161: % If some of columns of U have the same pitch, their contribution to the
ivan@161: % score (matrix V) is summed.
ivan@161: 
ivan@161: [Ps,idx]=sort(pitch);
ivan@161: ndp=1;
ivan@161: Pd(ndp)=Ps(1);
ivan@161: Vnew(ndp,:)=V(idx(1),:);
ivan@161: for i=2:88
ivan@161:     if Ps(i)> Ps(i-1)
ivan@161:         
ivan@161:         ndp=ndp+1;
ivan@161:         Vnew(ndp,:)=V(idx(i),:);
ivan@161:         Pd(ndp)=Ps(i);
ivan@161:         
ivan@161:     else
ivan@161:         Vnew(ndp,:)=Vnew(ndp,:)+V(idx(i),:);
ivan@161:     end
ivan@161: end
ivan@161: %%
ivan@161: % Generate midi matrix
ivan@161: 
ivan@161: midx=0;
ivan@161: for i=1:ndp
ivan@161:     
ivan@161:     %   Threshold for finding onsets and offsets of notes
ivan@161:     
ivan@161:     thr=mean(Vnew(i,:));%+std(Vnew(i,:));
ivan@161:     
ivan@161:     if(Pd(i)~=0)
ivan@161:         for j=1:size(Vnew,2)
ivan@161:             if Vnew(i,j)<thr
ivan@161:                 Vnew(i,j)=0;
ivan@161:                 if(j>1)
ivan@161:                     if (Vnew(i,j-1)==1)
ivan@161:                         try
ivan@161:                             M(midx,6)=(j-1)*ts;
ivan@161:                             if (M(midx,6)-M(midx,5))<2*ts
ivan@161:                                 midx=midx-1;
ivan@161:                             end
ivan@161:                         catch
ivan@161:                             pause;
ivan@161:                         end
ivan@161:                     end
ivan@161:                 end
ivan@161:             else
ivan@161:                 Vnew(i,j)=1;
ivan@161:                 if(j>1)
ivan@161:                     if (Vnew(i,j-1)==0)
ivan@161:                         midx=midx+1;
ivan@161:                         M(midx,1)=1;
ivan@161:                         M(midx,2)=1;
ivan@161:                         M(midx,3)=69 +round( 12 *log2(Pd(i)/440));
ivan@161:                         M(midx,4)=80;
ivan@161:                         M(midx,5)=(j-1)*ts;
ivan@161:                     end
ivan@161:                 else
ivan@161:                     midx=midx+1;
ivan@161:                     M(midx,1)=1;
ivan@161:                     M(midx,2)=1;
ivan@161:                     M(midx,3)=69 + round(12 *log2(Pd(i)/440));
ivan@161:                     M(midx,4)=80;
ivan@161:                     M(midx,5)=0;
ivan@161:                 end
ivan@161:             end
ivan@161:         end
ivan@161:         if M(midx,6)==0
ivan@161:             M(midx,6)=(j-1)*ts;
ivan@161:         end
ivan@161:     end
ivan@161: end
ivan@161: 
ivan@161: M=sortrows(M,5);
ivan@161: reconstructed.notes=M;
ivan@161: reconstructed.midi = matrix2midi(M);