0

I'm trying to create a GUI on MATLAB that will automatically transcribe piano music when a .wav file is given as an input. Before using GUI I created the whole algorithm using MATLAB and it worked just fine.

Now when I create the GUI and transfer the codings there, my onset (peak) detection produces wrong results as the envelope of my signal is not as smooth as how it was when run using matlab script.

Onsets before using GUI

Onset Detection after when using GUI

As you can see the envelope is pretty much smooth when used normally rather than when using GUI. Due to these peaks are detected all over the slope as well and not just at the actal peaks.

This is the code I used to build the algorithm:

[song,FS] = wavread('C major.wav');

P = 20000;
N=length(song);                     % length of song
t=0:1/FS:(N-1)/FS;                  % define time period
song = sum(song,2);                        
song=abs(song);

%----------------------Finding the envelope of the signal-----------------%
% Gaussian Filter
w = linspace( -1, 1, P);                      % create a vector of P values between -1 and 1 inclusive
sigma = 0.335;                                % standard deviation used in Gaussian formula
myFilter = -w .* exp( -(w.^2)/(2*sigma.^2));  % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize

% fft convolution
myFilter = myFilter(:);                         % create a column vector
song(length(song)+length(myFilter)-1) = 0;      %zero pad song
myFilter(length(song)) = 0;                     %zero pad myFilter
edges =ifft(fft(song).*fft(myFilter));

tedges=edges(P:N+P-1);                      % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges));                 % normalize

%---------------------------Onset Detection-------------------------------%
% Finding peaks
maxtab = [];
mintab = [];
j = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN; 
max_pos = NaN;

lookformax = 1;
for i=1:length(tedges)

    peak = tedges(i:i);
  if peak > max1, 
      max1 = peak;
      max_pos = j(i); 
  end
  if peak < min1, 
      min1 = peak;
      min_pos = j(i); 
  end

  if lookformax
    if peak < max1-0.09
      maxtab = [maxtab ; max_pos max1];
      min1 = peak; 
      min_pos = j(i);
      lookformax = 0;
    end  
  else
    if peak > min1+0.08
      mintab = [mintab ; min_pos min1];
      max1 = peak; 
      max_pos = j(i);
      lookformax = 1;
    end
  end
end
% % Plot song filtered with edge detector          
         figure(4)
         plot(1/FS:1/FS:N/FS,tedges)
         title('Song Filtered With Edge Detector 1')
         xlabel('Time (s)')
         ylabel('Amplitude')
         ylim([-1 1.1])
         xlim([0 N/FS])

         hold on;

         plot(maxtab(:,1)/FS, maxtab(:,2), 'ro')
         plot(mintab(:,1)/FS, mintab(:,2), 'ko')

And this is what I included in the GUI script:

[FileName,PathName] = uigetfile({'*.wav'},'Load Wav File');
[x,Fs] = wavread([PathName '/' FileName]);

N = length(x);
handles.x = sum(x,2);
handles.x = x./max(abs(x));
handles.Fs = Fs;

%Gaussian Edge detection filter
P = 20000;
w = linspace( -1, 1, P);                      % create a vector of P values between -1 and 1 inclusive
sigma = 0.335;                                % standard deviation used in Gaussian formula
myFilter = -w .* exp( -(w.^2)/(2*sigma.^2));  % compute first derivative, but leave constants out
myFilter = myFilter / sum( abs( myFilter ) ); % normalize
axes(handles.axes3);
plot(myFilter)

%Peak detection
myFilter = myFilter(:);                         % create a column vector
x(length(x)+length(myFilter)-1) = 0;      %zero pad song
myFilter(length(x)) = 0;                     %zero pad myFilter
edges =ifft(fft(x).*fft(myFilter));

tedges=edges(P:N+P-1);                      % shift by P/2 so peaks line up w/ edges
tedges=tedges/max(abs(tedges));                 % normalize

maxtab = [];
mintab = [];
j = (1:length(tedges));
min1 = Inf;
max1 = -Inf;
min_pos = NaN; 
max_pos = NaN;

lookformax = 1;
for i=1:length(tedges)

    peak = tedges(i:i);
  if peak > max1, 
      max1 = peak;
      max_pos = j(i); 
  end
  if peak < min1, 
      min1 = peak;
      min_pos = j(i); 
  end

  if lookformax
    if peak < max1-0.09
      maxtab = [maxtab ; max_pos max1];
      min1 = peak; 
      min_pos = j(i);
      lookformax = 0;
    end  
  else
    if peak > min1+0.08
      mintab = [mintab ; min_pos min1];
      max1 = peak; 
      max_pos = j(i);
      lookformax = 1;
    end
  end
end

axes(handles.axes4);
plot(1/Fs:1/Fs:N/Fs,tedges)
axis([0 N/Fs -1 1.1]);

What am I doing wrong here?? Really appreciate if someone could help me out here. Thanx in advance...

4

0 回答 0