我试图在MATLAB上创建一个GUI,它会在.wav文件作为输入时自动转录钢琴音乐。在使用GUI之前,我使用MATLAB创建了整个算法,它运行得很好。
现在当我创建GUI并在那里传输编码时,我的起始(峰值)检测会产生错误的结果,因为我的信号包络不像使用matlab脚本运行时那样平滑。
正如您所看到的,当正常使用时,信封非常平滑,而不是使用GUI时。由于这些峰值也在整个斜率上被检测到,而不仅仅是在动作峰值处。
这是我用来构建算法的代码:
[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')
这就是我在GUI脚本中包含的内容:
[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]);
我在这做错了什么?真的很感激,如果有人能帮助我在这里。 Thanx提前...