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)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);