changeset 8:33850553b702

(none)
author idamnjanovic
date Mon, 22 Mar 2010 10:56:54 +0000
parents 0151f1ea080d
children 28f2b5fe3483
files util/AMT_analysis.m util/Pierre_reconstruct.m util/SL_A.m util/SMALL_AMT_plot.m util/SMALL_AudioDeNoiseResult.m util/SMALL_ImgDeNoiseResult.m util/SMALL_denoise.m util/SMALL_init_DL.m util/SMALL_init_solver.m util/SMALL_learn.m util/SMALL_midiGenerate.m util/SMALL_playAudio.m util/SMALL_plot.m util/SMALL_solve.m util/SMALL_swipe.m
diffstat 15 files changed, 744 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/AMT_analysis.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,49 @@
+function AMT_res = AMT_analysis(Problem, solver)
+%%% Automatic Music Transcription results analysis
+%   Ivan Damnjanovic 2009
+%   
+%   If wav file that is transcribed is generated from midi file (i.e. if
+%   groundtruth exists) transcription is comapred to the original notes and
+%   AMT_res structure is generated. It contains following fields:
+%   -   tp_notes - true positive notes (notes corectly transcribed)
+%   -   oe_notes - octave errors (erroes due to imperfect pitch estimation)
+%   -   fn_notes_wo_oe - false negative notes without octave errors
+%                        (notes that were not detected)
+%   -   fp_notes_wo_oe - false positive notes without octave erors
+%   -   TP - number of true positives
+%   -   FN - number of false negatives
+%   -   FP - number of false positives
+
+timeOr=Problem.notesOriginal(:,5);
+noteOr=Problem.notesOriginal(:,3);
+timeTr=solver.reconstructed.notes(:,5);
+noteTr=solver.reconstructed.notes(:,3);
+n=size(timeOr,1);
+m=size(timeTr,1);
+
+%   tolerance (ts) is set to one window before and after the reference offset
+%   time
+
+ts=(Problem.windowSize)/Problem.fs;
+
+Hits=[];
+OE=[];
+
+for i=1:n
+    Hit= find((noteTr(:)==noteOr(i))&(abs(timeOr(i)-timeTr(:))<ts));
+    if size(Hit,1)>1 Hit=Hit(1); end
+    if ~isempty(Hit) Hits=[Hits; i , Hit];
+    else
+        OctErr=find(((noteTr(:)==noteOr(i)-12)|(noteTr(:)==noteOr(i)-24))&(abs(timeOr(i)-timeTr(:))<ts), 1);
+        if ~isempty(OctErr) OE=[OE; i , OctErr]; end
+    end
+end
+
+AMT_res.tp_notes = [Problem.notesOriginal(Hits(:,1),[3 5]) solver.reconstructed.notes(Hits(:,2),[3 5])];
+AMT_res.oe_notes = [Problem.notesOriginal(OE(:,1),[3 5]) solver.reconstructed.notes(OE(:,2),[3 5])];
+AMT_res.fn_notes_wo_oe = Problem.notesOriginal(setdiff([1:n],union(Hits(:,1),OE(:,1))),[3 5]);
+AMT_res.fp_notes_wo_oe = solver.reconstructed.notes(setdiff([1:m],union(Hits(:,2),OE(:,2))),[3 5]);
+AMT_res.TP=size(Hits,1);
+AMT_res.FN=n-AMT_res.TP;
+AMT_res.FP=m-AMT_res.TP;
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/Pierre_reconstruct.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,22 @@
+function reconstructed=Pierre_reconstruct(y, Problem)
+%%  Pierre Villars Example - reconstruction function
+%   This example is based on the experiment suggested by Professor Pierre
+%   Vandergheynst on the SMALL meeting in Villars.
+
+%   using sparse representation y in dictionary Problem.A reconstruct the
+%   patches from the target image
+
+imout=Problem.A*y;
+
+%   combine the patches into reconstructed image
+
+im=col2im(imout,Problem.blocksize,size(Problem.imageTrg),'disctint');
+
+%   bound the pixel values to [0,255] range 
+im(im<0)=0;
+im(im>255)=255;
+
+%% output structure image+psnr %%
+reconstructed.image=im;
+reconstructed.psnr = 20*log10(Problem.maxval * sqrt(numel(Problem.imageTrg(:))) / norm(Problem.imageTrg(:)-im(:)));
+end
\ No newline at end of file
--- a/util/SL_A.m	Mon Mar 22 10:47:17 2010 +0000
+++ b/util/SL_A.m	Mon Mar 22 10:56:54 2010 +0000
@@ -1,4 +1,4 @@
-  function y = SL_A(mode, m, n, x, I, dim)
+  function y = SL_A(A, mode, m, n, x, I, dim)
   % Ivan Damnjanovic 2009
   % This is auxilary function to allow implicit matrices from SPARCO 
   % to be used with SparsLab solvers
@@ -8,11 +8,11 @@
     
             u = zeros(dim, 1);
             u(I) = x;
-            y = SMALL.Problem.A(u,1);
+            y = A(u,1);
            
         elseif (mode == 2)
     
-            x2 = SMALL.Problem.A(x,2);
+            x2 = A(x,2);
             y = x2(I);
            
      end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_AMT_plot.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,21 @@
+function figAMT=SMALL_AMT_plot(SMALL, AMT_res)
+%   Ivan Damnjanovic 2010
+%   Function gets as input SMALL structure and plots  AMT
+  
+
+  figAMT=figure('Name','Automatic Music Transcription');
+  
+  m=size(AMT_res,2);
+ 
+for i =1:m
+  subplot(m,1, i);plot(AMT_res(i).tp_notes(:,2), AMT_res(i).tp_notes(:,1),'ko', ...
+      AMT_res(i).tp_notes(:,4), AMT_res(i).tp_notes(:,3),'gx', ...
+        AMT_res(i).oe_notes(:,2), AMT_res(i).oe_notes(:,1),'bo', ...
+            AMT_res(i).oe_notes(:,4), AMT_res(i).oe_notes(:,3),'bx', ...
+                AMT_res(i).fn_notes_wo_oe(:,2), AMT_res(i).fn_notes_wo_oe(:,1),'ro', ...
+                     AMT_res(i).fp_notes_wo_oe(:,2), AMT_res(i).fp_notes_wo_oe(:,1),'rx')
+        title(sprintf('%s dictionary in %.2f s - TP=%d FN=%d (Octave Errors = %d) FP=%d', SMALL.DL(i).name, SMALL.DL(i).time, AMT_res(i).TP, AMT_res(i).FN, size(AMT_res(i).oe_notes,1), AMT_res(i).FP));
+          xlabel('Time') 
+            ylabel('Note Number')
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_AudioDeNoiseResult.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,36 @@
+function SMALL_AudioDeNoiseResult(SMALL)
+
+fMain=figure('Name', sprintf('File %s (training set size- %d, sigma - %d)',SMALL.Problem.name, SMALL.Problem.n, SMALL.Problem.sigma));
+m=size(SMALL.solver,2);
+maxval=SMALL.Problem.maxval;
+au=SMALL.Problem.Original;
+aunoise=SMALL.Problem.Noisy;
+
+subplot(2, m, 1); plot(au/maxval);
+title('Original audio');
+
+subplot(2,m,2); plot(aunoise/maxval);
+title(sprintf('Noisy audio, PSNR = %.2fdB', 20*log10(maxval * sqrt(numel(au)) / norm(au(:)-aunoise(:))) ));
+
+for i=1:m
+    params=SMALL.solver(i).param;
+    sWav=subplot(2, m, m+i, 'Parent', fMain); plot(SMALL.solver(i).reconstructed.Image/maxval, 'Parent', sWav);
+    title(sprintf('%s Denoised audio, PSNR: %.2fdB', SMALL.DL(i).name, SMALL.solver(i).reconstructed.psnr),'Parent', sWav );
+    if strcmpi(SMALL.DL(i).name,'ksvds')
+        D = kron(SMALL.Problem.basedict{2},SMALL.Problem.basedict{1})*SMALL.DL(i).D;
+    else
+        D = SMALL.DL(i).D;
+    end
+    figure('Name', sprintf('%s dictionary in %.2f s', SMALL.DL(i).name, SMALL.DL(i).time));
+    imshow(D*255);
+%     n= size(D,2);
+%     sqrtn=round(sqrt(size(D,2)));
+%     for j=1:n
+%     subplot(sqrtn,sqrtn,j); plot(D(:,j));
+%     end
+%     dictimg = showdict(D,[params.blocksize 1],round(sqrt(size(D,2))),round(sqrt(size(D,2))),'lines','highcontrast');
+%     
+%     subplot(2,m,m+i);imshow(imresize(dictimg,2,'nearest'));
+%     title(sprintf('%s dictionary in %.2f s', SMALL.DL(i-1).name, SMALL.DL(i-1).time));
+    
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_ImgDeNoiseResult.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,38 @@
+function SMALL_ImgDeNoiseResult(SMALL)
+%   Ivan Damnjanovic 2010
+%   Function gets as input SMALL structure and plots  Image Denoise
+%   results: Original Image, Noisy Image and for learned dictionaries and 
+%   denoised images 
+
+
+figure('Name', sprintf('Image %s (training set size- %d, sigma - %d)',SMALL.Problem.name, SMALL.Problem.n, SMALL.Problem.sigma));
+
+m=size(SMALL.solver,2)+1;
+maxval=SMALL.Problem.maxval;
+im=SMALL.Problem.Original;
+imnoise=SMALL.Problem.Noisy;
+
+subplot(2, m, 1); imshow(im/maxval);
+title('Original image');
+
+subplot(2,m,m+1); imshow(imnoise/maxval);
+title(sprintf('Noisy image, PSNR = %.2fdB', 20*log10(maxval * sqrt(numel(im)) / norm(im(:)-imnoise(:))) ));
+
+for i=2:m
+    params=SMALL.solver(i-1).param;
+    subplot(2, m, i); imshow(SMALL.solver(i-1).reconstructed.Image/maxval);
+    title(sprintf('%s Denoised image, PSNR: %.2f dB in %.2f s',...
+        SMALL.DL(i-1).name, SMALL.solver(i-1).reconstructed.psnr, SMALL.solver(i-1).time ));
+    if strcmpi(SMALL.DL(i-1).name,'ksvds')
+        D = kron(SMALL.Problem.basedict{2},SMALL.Problem.basedict{1})*SMALL.DL(i-1).D;
+    else
+        D = SMALL.DL(i-1).D;
+    end
+    dictimg = showdict(D,params.blocksize,...
+        round(sqrt(size(D,2))),round(sqrt(size(D,2))),'lines','highcontrast');
+    
+    subplot(2,m,m+i);imshow(imresize(dictimg,2,'nearest'));
+    title(sprintf('%s dictionary in %.2f s',...
+        SMALL.DL(i-1).name, SMALL.DL(i-1).time));
+    
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_denoise.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,77 @@
+function solver=SMALL_denoise(Problem, solver)
+
+%%% SMALL denoising
+%   Ivan Damnjanovic 2009
+%   Function gets as input SMALL structure that contains SPARCO problem to
+%   be solved, name of the toolbox and solver, and parameters file for
+%   particular solver.
+%   It is based on omp/omps denoising by Ron Rubenstein (KSVD toolbox)
+%
+%   Outputs are denoised image, psnr, number of non-zero coeficients and 
+%   time spent
+%%
+  
+  %%%%%  denoise the signal  %%%%%
+  fprintf('\nStarting %s... \n', solver.name);
+  start=cputime;
+  %%
+  if strcmpi(solver.toolbox,'ompbox')
+      if (~isfield(solver.param,'lambda'))
+          solver.param.lambda = Problem.maxval/(10*Problem.sigma);
+      end
+      
+      solver.param = Problem;
+      %solver.param.memusage = 'high';
+      solver.param = rmfield(solver.param, {'Noisy' 'Original' 'b' 'm' 'n' 'p' 'initdict'});
+      solver.param.x = Problem.Noisy;
+      solver.param.dict = Problem.A;
+      p = Problem.signalDim;
+      msgdelta=5;
+      % call the appropriate ompdenoise function
+      if (p==1)
+          [y,nz] = ompdenoise1(solver.param,msgdelta);
+      elseif (p==2)
+          [y,nz] = ompdenoise2(solver.param,msgdelta);
+      elseif (p==3)
+          [y,nz] = ompdenoise3(solver.param,msgdelta);
+      else
+          [y,nz] = ompdenoise(solver.param,msgdelta);
+      end
+  elseif strcmpi(solver.toolbox,'ompsbox')
+      if (~isfield(solver.param,'lambda'))
+          solver.param.lambda = Problem.maxval/(10*Problem.sigma);
+      end
+      
+      solver.param = Problem;
+      %solver.param.memusage = 'high';
+      solver.param = rmfield(solver.param, {'Noisy' 'Original' 'b' 'm' 'n' 'p' 'initdict'});
+      solver.param.x = Problem.Noisy;
+      if issparse(Problem.A)
+        solver.param.A = Problem.A;
+      else
+        solver.param.A = sparse(Problem.A);
+      end
+      p = Problem.signalDim;
+      msgdelta=5;
+      % call the appropriate ompdenoise function
+      if (p==1)
+          [y,nz] = ompsdenoise1(solver.param,msgdelta);
+      elseif (p==2)
+          [y,nz] = ompsdenoise2(solver.param,msgdelta);
+      elseif (p==3)
+          [y,nz] = ompsdenoise3(solver.param,msgdelta);
+      else
+          [y,nz] = ompsdenoise(solver.param,msgdelta);
+      end
+  else
+      printf('\nToolbox has not been registered. Please change SMALL_learn file.\n');
+      return
+  end
+ %%
+  solver.time = cputime - start;
+  fprintf('\n%s finished task in %2f seconds. \n', solver.name, solver.time);
+  solver.reconstructed.Image=y;
+  solver.reconstructed.psnr=20*log10(Problem.maxval * sqrt(numel(Problem.Original)) / norm(Problem.Original(:)-solver.reconstructed.Image(:)));
+  solver.reconstructed.nz=nz;
+  
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_init_DL.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,15 @@
+function DL = SMALL_init_DL(varargin)
+% Ivan Damnjanovic 2010
+  % Function initialise SMALL structure for Dictionary Learning.
+  % Optional input variables:
+  %     toolbox - name of Dictionary Learning toolbox you want to use
+  %     name    - name of the algorithm from above toolbox
+  %     param   - parameters you want to set
+  %%
+  
+  DL.toolbox=[];
+  DL.name=[];
+  DL.param=[];
+  DL.D=[];
+  DL.time=[];
+  end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_init_solver.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,16 @@
+function solver = SMALL_init_solver(varargin)
+% Ivan Damnjanovic 2010
+  % Function initialise SMALL structure for Dictionary Learning.
+  % Optional input variables:
+  %     toolbox - name of Dictionary Learning toolbox you want to use
+  %     name    - name of the algorithm from above toolbox
+  %     param   - parameters you want to set
+  %%
+  
+  solver.toolbox=[];
+  solver.name=[];
+  solver.param=[];
+  solver.solution=[];
+  solver.reconstructed=[];
+  solver.time=[];
+end
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_learn.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,72 @@
+function DL = SMALL_learn(Problem,DL)
+%%% SMALL Dictionary Learning   
+%   Ivan Damnjanovic 2009
+%   Function gets as input Problem and Dictionary Learning (DL) structures 
+%   In Problem structure field b with the training set needs to be defined
+%   In DL fields with name of the toolbox and solver, and parameters file 
+%   for particular dictionary learning technique needs to be present.
+%
+%   Outputs are Learned dictionary and time spent as a part of DL structure
+%%
+ 
+  fprintf('\nStarting Dictionary Learning %s... \n', DL.name);
+  start=cputime;
+  
+  if strcmpi(DL.toolbox,'KSVD')
+    param=DL.param; 
+    param.data=Problem.b;
+ 
+    D = eval([DL.name,'(param, ''t'', 5);']);
+  elseif strcmpi(DL.toolbox,'KSVDS')
+    param=DL.param; 
+    param.data=Problem.b;
+    
+    D = eval([DL.name,'(param, ''t'', 5);']);
+  elseif strcmpi(DL.toolbox,'SPAMS')
+    
+    X  = Problem.b; 
+    param=DL.param;
+    
+    D = eval([DL.name,'(X, param);']);
+    %   As some versions of SPAMS does not produce unit norm column
+    %   dictionaries, we need to make sure that columns are normalised to
+    %   unit lenght.
+    
+    for i = 1: size(D,2)
+        D(:,i)=D(:,i)/norm(D(:,i));
+    end
+    
+%   To introduce new dictionary learning technique put the files in
+%   your Matlab path. Next, unique name <TolboxID> for your toolbox needs 
+%   to be defined and also prefferd API for toolbox functions <Preffered_API>
+%   
+% elseif strcmpi(DL.toolbox,'<ToolboxID>')
+%     % This is an example of API that can be used:
+%     % - get training set from Problem part of structure
+%     % - assign parameters defined in the main program
+%
+%     X  = Problem.b; 
+%     param=DL.param;
+%
+%     % - Evaluate the function (DL.name - defined in the main) with
+%     %   parameters given above
+%
+%     D = eval([DL.name,'(<Preffered_API>);']);
+
+  else
+    printf('\nToolbox has not been registered. Please change SMALL_learn file.\n');
+    return
+  end
+  
+%%
+%   Dictionary Learning time
+
+  DL.time = cputime - start;
+  fprintf('\n%s finished task in %2f seconds. \n', DL.name, DL.time);
+
+%   If dictionary is given as a sparse matrix change it to full  
+
+  DL.D = full(D);
+  
+end
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_midiGenerate.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,109 @@
+function reconstructed=SMALL_midiGenerate(V, Problem)
+%%% Reconstraction of midi file from representation in the given dictionary
+%   Ivan Damnjanovic 2009
+%   
+%   SMALL_midiGenerate is a part of SMALLbox and can be use to reconstruct
+%   a midi file given representation of the training set (V) in the
+%   dictionary Problem.A.
+%   Output is reconstructed structure with two fields:
+%   -   reconstructed.notes - matrix with transcribed notes
+%   -   reconstructed.midi - midi representation of transcription
+
+
+U=Problem.A;    %   Dictionary used for representation
+fs=Problem.fs;  %   Sampling rate
+f=Problem.f;    %   vector of frequencies at wihch spectrogram is computed
+
+ts=(Problem.windowSize*Problem.overlap)/fs; %size of an analysis frame in seconds
+
+%%
+% Components pitch estimation using modified SWIPE algorithm by Arthuro
+% Camacho
+% 
+% Columns of matrix U are spectrograms of the notes learned from the
+% training set. We are estimating pitches of these notes by also
+% restricting pitch values to the one of the 88 piano notes. 
+
+pitch=zeros(size(U,2),1);
+
+for i=1:size(U,2)
+    
+    pitch(i) = SMALL_swipe(U(:,i),fs, f, [27.50 8192], 1/12);
+    
+end
+
+%%
+% If some of columns of U have the same pitch, their contribution to the
+% score (matrix V) is summed.
+
+[Ps,idx]=sort(pitch);
+ndp=1;
+Pd(ndp)=Ps(1);
+Vnew(ndp,:)=V(idx(1),:);
+for i=2:88
+    if Ps(i)> Ps(i-1)
+        
+        ndp=ndp+1;
+        Vnew(ndp,:)=V(idx(i),:);
+        Pd(ndp)=Ps(i);
+        
+    else
+        Vnew(ndp,:)=Vnew(ndp,:)+V(idx(i),:);
+    end
+end
+%%
+% Generate midi matrix
+
+midx=0;
+for i=1:ndp
+    
+    %   Threshold for finding onsets and offsets of notes
+    
+    thr=mean(Vnew(i,:));%+std(Vnew(i,:));
+    
+    if(Pd(i)~=0)
+        for j=1:size(Vnew,2)
+            if Vnew(i,j)<thr
+                Vnew(i,j)=0;
+                if(j>1)
+                    if (Vnew(i,j-1)==1)
+                        try
+                            M(midx,6)=(j-1)*ts;
+                            if (M(midx,6)-M(midx,5))<2*ts
+                                midx=midx-1;
+                            end
+                        catch
+                            pause;
+                        end
+                    end
+                end
+            else
+                Vnew(i,j)=1;
+                if(j>1)
+                    if (Vnew(i,j-1)==0)
+                        midx=midx+1;
+                        M(midx,1)=1;
+                        M(midx,2)=1;
+                        M(midx,3)=69 +round( 12 *log2(Pd(i)/440));
+                        M(midx,4)=80;
+                        M(midx,5)=(j-1)*ts;
+                    end
+                else
+                    midx=midx+1;
+                    M(midx,1)=1;
+                    M(midx,2)=1;
+                    M(midx,3)=69 + round(12 *log2(Pd(i)/440));
+                    M(midx,4)=80;
+                    M(midx,5)=0;
+                end
+            end
+        end
+        if M(midx,6)==0
+            M(midx,6)=(j-1)*ts;
+        end
+    end
+end
+
+M=sortrows(M,5);
+reconstructed.notes=M;
+reconstructed.midi = matrix2midi(M);
\ No newline at end of file
--- a/util/SMALL_playAudio.m	Mon Mar 22 10:47:17 2010 +0000
+++ b/util/SMALL_playAudio.m	Mon Mar 22 10:56:54 2010 +0000
@@ -4,6 +4,7 @@
   % the reconstructed signal
 
 
+SMALL.solver.reconstructed  = SMALL.Problem.reconstruct(SMALL.solver.solution);
 ch='';
 while 1
     request = input('\nWhat do you want to hear? \n 1. Original signal \n 2. Mixed \n 3. Reconstructed signal \n 4. Quit player\n','s');
--- a/util/SMALL_plot.m	Mon Mar 22 10:47:17 2010 +0000
+++ b/util/SMALL_plot.m	Mon Mar 22 10:56:54 2010 +0000
@@ -4,20 +4,22 @@
   % reconstructed signal
 
   figure;
-
-  plot(1:length(SMALL.solver.solution), SMALL.solver.solution, 'b');
-        title(['Coefficients of the reconstructed signal using ', SMALL.solver.name, ' with parameters ', SMALL.solver.param])
+ 
+  m=size(SMALL.solver,2);
+  n=size(SMALL.solver(1).reconstructed,2)+1;
+  for i =1:m
+  
+  subplot(m,n, (i-1)*n+1); plot(1:length(SMALL.solver(i).solution), SMALL.solver(i).solution, 'b')
+        title([ SMALL.solver(i).name,'(', SMALL.solver(i).param,')'])
           xlabel('Coefficient') 
      
-  % Use SMALL.solution to reconstruct the signal.
-
   % Plot reconstructed signal against original
 
   
-  for i=1:size(SMALL.solver.reconstructed,2)
-      figure;
-      plot(1:length(SMALL.solver.reconstructed(:,i)), SMALL.solver.reconstructed(:,i)  ,'b.-',  1:length(SMALL.Problem.signal(:,i)), SMALL.Problem.signal(:,i),'r--');
-          legend(SMALL.solver.name,'Original signal');
+  for j=2:n
+      
+      subplot(m,n,(i-1)*n+j); plot(1:length(SMALL.solver(i).reconstructed(:,j-1)), SMALL.solver(i).reconstructed(:,j-1)  ,'b.-',  1:length(SMALL.Problem.signal(:,j-1)), SMALL.Problem.signal(:,j-1),'r--')
+          %legend(SMALL.solver(i).name,'Original signal',0);
               title('Reconstructed and original signals');
   end
 end
--- a/util/SMALL_solve.m	Mon Mar 22 10:47:17 2010 +0000
+++ b/util/SMALL_solve.m	Mon Mar 22 10:56:54 2010 +0000
@@ -1,32 +1,77 @@
-function SMALL = SMALL_solve(SMALL)
-  % Ivan Damnjanovic 2009
-  % Function gets as input SMALL structure that contains SPARCO problem to
-  % be solved, name of the toolbox and solver, and parameters file for particular solver
-  % Outputs are solution, reconstructed signal and time spent
-  %%
-  
-  A  = @(x) SMALL.Problem.A(x,1);  % The operator
-  AT = @(y) SMALL.Problem.A(y,2);  % and its transpose.
-  b  = SMALL.Problem.b;            % The right-hand-side vector.
-  m = SMALL.Problem.sizeA(1);      % m is the no. of rows.
-  n = SMALL.Problem.sizeA(2);      % n is the no. of columns.
-  
-  fprintf('\nStarting solver %s... \n', SMALL.solver.name);
-  start=cputime;
-  %%
-  if strcmpi(SMALL.solver.toolbox,'sparselab')
-    y = eval([SMALL.solver.name,'(''SL_A'', b, n,',SMALL.solver.param,');']);
-  elseif strcmpi(SMALL.solver.toolbox,'sparsify')
-    y = eval([SMALL.solver.name,'(b, A, n, ''P_trans'', AT,',SMALL.solver.param,');']);
-  elseif (strcmpi(SMALL.solver.toolbox,'spgl1')||strcmpi(SMALL.solver.toolbox,'gpsr'))
-    y = eval([SMALL.solver.name,'(b, A,',SMALL.solver.param,');']);
-  else
-    y = eval([SMALL.solver.name,'(A, b, n,',SMALL.solver.param,',AT);']);
-  end
-  %%
-  SMALL.solver.time = cputime - start;
-  fprintf('Solver %s finished task in %2f seconds. \n', SMALL.solver.name, SMALL.solver.time);
-  SMALL.solver.solution = full(y);
-  SMALL.solver.reconstructed  = SMALL.Problem.reconstruct(SMALL.solver.solution);
+function solver = SMALL_solve(Problem, solver)
+%%% SMALL sparse solver
+%   Ivan Damnjanovic 2009
+%   Function gets as input SMALL structure that contains SPARCO problem to
+%   be solved, name of the toolbox and solver, and parameters file for
+%   particular solver.
+%
+%   Outputs are solution, reconstructed signal and time spent
+%%
+
+if isa(Problem.A,'float')
+    A = Problem.A;
+    SparseLab_A=Problem.A;
+    m = size(Problem.A,1);      % m is the no. of rows.
+    n = size(Problem.A,2);      % n is the no. of columns.
+else
+    A  = @(x) Problem.A(x,1);  % The operator
+    AT = @(y) Problem.A(y,2);  % and its transpose.
+    SparseLab_A =@(mode, m, n, x, I, dim) SL_A(Problem.A, mode, m, n, x, I, dim);
+    m = Problem.sizeA(1);      % m is the no. of rows.
+    n = Problem.sizeA(2);      % n is the no. of columns.
+    
 end
-  
\ No newline at end of file
+b  = Problem.b;            % The right-hand-side vector.
+%%
+fprintf('\nStarting solver %s... \n', solver.name);
+start=cputime;
+
+if strcmpi(solver.toolbox,'sparselab')
+    y = eval([solver.name,'(SparseLab_A, b, n,',solver.param,');']);
+elseif strcmpi(solver.toolbox,'sparsify')
+    y = eval([solver.name,'(b, A, n, ''P_trans'', AT,',solver.param,');']);
+elseif (strcmpi(solver.toolbox,'spgl1')||strcmpi(solver.toolbox,'gpsr'))
+    y = eval([solver.name,'(b, A,',solver.param,');']);
+elseif (strcmpi(solver.toolbox,'SPAMS'))
+    y = eval([solver.name,'(b, A, solver.param);']);
+elseif (strcmpi(solver.toolbox,'SMALL'))
+    if isa(Problem.A,'float')
+        y = eval([solver.name,'(A, b, n,',solver.param,');']);
+    else
+        y = eval([solver.name,'(A, b, n,',solver.param,',AT);']);
+    end
+    
+%   To introduce new sparse representation algorithm put the files in
+%   your Matlab path. Next, unique name <TolboxID> for your toolbox and
+%   prefferd API <Preffered_API> needs to be defined.
+%
+% elseif strcmpi(solver.toolbox,'<ToolboxID>')
+%
+%     % - Evaluate the function (solver.name - defined in the main) with
+%     %   parameters given above
+%
+%     y = eval([solver.name,'(<Preffered_API>);']);
+
+else
+    printf('\nToolbox has not been registered. Please change SMALL_solver file.\n');
+    return
+end
+
+%%
+%   Sparse representation time
+
+solver.time = cputime - start;
+fprintf('Solver %s finished task in %2f seconds. \n', solver.name, solver.time);
+
+% geting around out of memory problem when converting big matrix from
+% sparse to full...
+
+if (Problem.sparse==1)
+    solver.solution = y;
+else
+    solver.solution = full(y);
+end
+
+%   Reconstruct the signal from the solution
+solver.reconstructed  = Problem.reconstruct(solver.solution);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SMALL_swipe.m	Mon Mar 22 10:56:54 2010 +0000
@@ -0,0 +1,198 @@
+function [p,s] = SMALL_swipe(X,fs, f, plim,dlog2p,dERBs,woverlap,sTHR)
+% 
+% Ivan Damnjanovic 2010
+%
+% This is modified swipep MATLAB code that is working directly in spectral
+% domain and uses only one window size. The results are suboptimal
+% comparing to original code. It is also converted to SWIPE which uses all
+% the harmonics of the signal. 
+%
+%SWIPEP Pitch estimation using SWIPE'.
+%    P = SWIPEP(X,Fs,[PMIN PMAX],DT,DLOG2P,DERBS,STHR) estimates the pitch 
+%    of the vector signal X every DT seconds. The sampling frequency of
+%    the signal is Fs (in Hertz). The spectrum is computed using a Hann
+%    window with an overlap WOVERLAP between 0 and 1. The spectrum is
+%    sampled uniformly in the ERB scale with a step size of DERBS ERBs. The
+%    pitch is searched within the range [PMIN PMAX] (in Hertz) with samples
+%    distributed every DLOG2P units on a base-2 logarithmic scale of Hertz. 
+%    The pitch is fine-tuned using parabolic interpolation with a resolution
+%    of 1 cent. Pitch estimates with a strength lower than STHR are treated
+%    as undefined.
+%    
+%    [P,T,S] = SWIPEP(X,Fs,[PMIN PMAX],DT,DLOG2P,DERBS,WOVERLAP,STHR) 
+%    returns the times T at which the pitch was estimated and the pitch 
+%    strength S of every pitch estimate.
+%
+%    P = SWIPEP(X,Fs) estimates the pitch using the default settings PMIN =
+%    30 Hz, PMAX = 5000 Hz, DT = 0.001 s, DLOG2P = 1/48 (48 steps per 
+%    octave), DERBS = 0.1 ERBs, WOVERLAP = 0.5, and STHR = -Inf.
+%
+%    P = SWIPEP(X,Fs,...,[],...) uses the default setting for the parameter
+%    replaced with the placeholder [].
+%
+%    REMARKS: (1) For better results, make DLOG2P and DERBS as small as 
+%    possible and WOVERLAP as large as possible. However, take into account
+%    that the computational complexity of the algorithm is inversely 
+%    proportional to DLOG2P, DERBS and 1-WOVERLAP, and that the  default 
+%    values have been found empirically to produce good results. Consider 
+%    also that the computational complexity is directly proportional to the
+%    number of octaves in the pitch search range, and therefore , it is 
+%    recommendable to restrict the search range to the expected range of
+%    pitch, if any. (2) This code implements SWIPE', which uses only the
+%    first and prime harmonics of the signal. To convert it into SWIPE,
+%    which uses all the harmonics of the signal, replace the word
+%    PRIMES with a colon (it is located almost at the end of the code).
+%    However, this may not be recommendable since SWIPE' is reported to 
+%    produce on average better results than SWIPE (Camacho and Harris,
+%    2008).
+%
+%    EXAMPLE: Estimate the pitch of the signal X every 10 ms within the
+%    range 75-500 Hz using the default resolution (i.e., 48 steps per
+%    octave), sampling the spectrum every 1/20th of ERB, using a window 
+%    overlap factor of 50%, and discarding samples with pitch strength 
+%    lower than 0.2. Plot the pitch trace.
+%       [x,Fs] = wavread(filename);
+%       [p,t,s] = swipep(x,Fs,[75 500],0.01,[],1/20,0.5,0.2);
+%       plot(1000*t,p)
+%       xlabel('Time (ms)')
+%       ylabel('Pitch (Hz)')
+%
+%    REFERENCES: Camacho, A., Harris, J.G, (2008) "A sawtooth waveform 
+%    inspired pitch estimator for speech and music," J. Acoust. Soc. Am.
+%    124, 1638-1652.
+if ~ exist( 'plim', 'var' ) || isempty(plim), plim = [30 5000]; end
+%if ~ exist( 'dt', 'var' ) || isempty(dt), dt = 0.001; end
+if ~ exist( 'dlog2p', 'var' ) || isempty(dlog2p), dlog2p = 1/48; end
+if ~ exist( 'dERBs', 'var' ) || isempty(dERBs), dERBs = 0.05; end
+% if ~ exist( 'woverlap', 'var' ) || isempty(woverlap)
+%     woverlap = 0.5;
+% elseif woverlap>1 || woverlap<0
+%     error('Window overlap must be between 0 and 1.')
+% end
+if ~ exist( 'sTHR', 'var' ) || isempty(sTHR), sTHR = -Inf; end
+%t = [ 0: dt: length(x)/fs ]'; % Times
+% Define pitch candidates
+log2pc = [ log2(plim(1)): dlog2p: log2(plim(2)) ]';
+pc = 2 .^ log2pc;
+S = zeros( length(pc), 1 ); % Pitch strength matrix
+% Determine P2-WSs
+%logWs = round( log2( 8*fs ./ plim ) ); 
+ws = [2822];%2.^[ logWs(1): -1: logWs(2) ]; % P2-WSs
+pO = 8 * fs ./ ws; % Optimal pitches for P2-WSs
+% Determine window sizes used by each pitch candidate
+d = 1 + log2pc - log2( 8*fs./ws(1) );
+% Create ERB-scale uniformly-spaced frequencies (in Hertz)
+fERBs = erbs2hz([ hz2erbs(min(pc)/4): dERBs: hz2erbs(fs/2) ]');
+for i = 1 : length(ws)
+    %dn = max( 1, round( 8*(1-woverlap) * fs / pO(i) ) ); % Hop size
+    % Zero pad signal
+    %xzp = [ zeros( ws(i)/2, 1 ); x(:); zeros( dn + ws(i)/2, 1 ) ];
+    % Compute spectrum
+    %w = hanning( ws(i) ); % Hann window 
+    %o = max( 0, round( ws(i) - dn ) ); % Window overlap
+    %[ X, f, ti ] = specgram( xzp, ws(i), fs, w, o );
+    % Select candidates that use this window size
+    if length(ws) == 1
+        j=[1:size(pc)]'; k = [];
+    elseif i == length(ws)
+        j=find(d-i>-1); k=find(d(j)-i<0);
+    elseif i==1
+        j=find(d-i<1); k=find(d(j)-i>0);
+    else
+        j=find(abs(d-i)<1); k=1:length(j);
+    end
+    % Compute loudness at ERBs uniformly-spaced frequencies
+    fERBs = fERBs( find( fERBs > pc(1)/4, 1, 'first' ) : end );
+    L = sqrt( max( 0, interp1( f, X, fERBs, 'spline', 0) ) );
+    % Compute pitch strength
+    Si = pitchStrengthAllCandidates( fERBs, L, pc );
+    % Interpolate pitch strength at desired times
+%     if size(Si,2) > 1
+%         warning off MATLAB:interp1:NaNinY
+%         Si = interp1( ti, Si', t, 'linear', NaN )';
+%         warning on MATLAB:interp1:NaNinY
+%     else
+%         Si = repmat( NaN, length(Si),1 );
+%     end
+    % Add pitch strength to combination
+%     lambda = d( j(k) ) - i;
+    mu = ones( size(j) );
+%     mu(k) = 1 - abs( lambda );
+    S(j,:) = S(j,:) + repmat(mu,1,size(Si,2)) .* Si;
+end
+% Fine tune pitch using parabolic interpolation
+p = repmat( NaN, size(S,2), 1 );
+s = repmat( NaN, size(S,2), 1 );
+for j = 1 : size(S,2)
+    [ s(j), i ] = max( S(:,j), [], 1 );
+    if s(j) < sTHR, continue, end
+    if i == 1 || i == length(pc)
+        p(j) = pc(i);
+    else
+        I = i-1 : i+1;
+        tc = 1 ./ pc(I);
+        ntc = ( tc/tc(2) - 1 ) * 2*pi;
+        c = polyfit( ntc, S(I,j), 2 );
+        ftc = 1 ./ 2.^[ log2(pc(I(1))): 1/12/100: log2(pc(I(3))) ];
+        nftc = ( ftc/tc(2) - 1 ) * 2*pi;
+        [s(j) k] = max( polyval( c, nftc ) );
+        p(j) = 2 ^ ( log2(pc(I(1))) + (k-1)/12/100 );
+%         if (p(j)-pc(I(1)))<0.75*abs(p(j)-pc(I(2)))
+%             p(j)=pc(I(1));
+%         elseif (pc(I(3))-p(j))<0.75*abs(p(j)-pc(I(2)))
+%             p(j)=pc(I(3));
+%         else
+            p(j)=pc(I(2));
+%         end
+    end
+end
+
+function S = pitchStrengthAllCandidates( f, L, pc )
+% Create pitch strength matrix
+S = zeros( length(pc), size(L,2) );
+% Define integration regions
+k = ones( 1, length(pc)+1 );
+for j = 1 : length(k)-1
+    k(j+1) = k(j) - 1 + find( f(k(j):end) > pc(j)/4, 1, 'first' );
+end
+k = k(2:end);
+% Create loudness normalization matrix
+N = sqrt( flipud( cumsum( flipud(L.*L) ) ) );
+for j = 1 : length(pc)
+    % Normalize loudness
+    warning off MATLAB:divideByZero
+    NL = L(k(j):end,:) ./ repmat( N(k(j),:), size(L,1)-k(j)+1, 1);
+    warning on MATLAB:divideByZero
+    % Compute pitch strength
+
+    S(j,:) = pitchStrengthOneCandidate( f(k(j):end), NL, pc(j) );
+end
+
+function S = pitchStrengthOneCandidate( f, NL, pc )
+n = fix( f(end)/pc - 0.75 ); % Number of harmonics
+if n==0, S=NaN; return, end
+k = zeros( size(f) ); % Kernel
+% Normalize frequency w.r.t. candidate
+q = f / pc;
+% Create kernel
+for i = [ 1:n] % primes(n) ]
+    a = abs( q - i );
+    % Peak's weigth
+    p = a < .25; 
+    k(p) = cos( 2*pi * q(p) );
+    % Valleys' weights
+    v = .25 < a & a < .75;
+    k(v) = k(v) + cos( 2*pi * q(v) ) / 2;
+end
+% Apply envelope
+k = k .* sqrt( 1./f  ); 
+% K+-normalize kernel
+k = k / norm( k(k>0) ); 
+% Compute pitch strength
+S = k' * NL; 
+
+function erbs = hz2erbs(hz)
+erbs = 21.4 * log10( 1 + hz/229 );
+
+function hz = erbs2hz(erbs)
+hz = ( 10 .^ (erbs./21.4) - 1 ) * 229;