www.pudn.com > audioProcessingtoolbox.rar > endpoint.m


function out = endpoint(y, fs, plotOpt, epdParam) 
% ENDPOINT End point detection(最舊的版本) 
 
if nargin==0, selfdemo; return; end 
if nargin<4, 
	epdParam.frameSize = 256; 
	epdParam.overlap = 86; 
	epdParam.deltaEnergyLevel1 = -30; 
	epdParam.deltaEnergyLevel2 = -20; 
	epdParam.zcrRatio = 0.1; 
end 
if nargin<3, plotOpt=0; end 
if nargin<2, fs=8000; end 
 
frameSize=epdParam.frameSize; 
overlap=epdParam.overlap; 
deltaEnergyLevel1=epdParam.deltaEnergyLevel1; 
deltaEnergyLevel2=epdParam.deltaEnergyLevel2; 
zcrRatio=epdParam.zcrRatio; 
 
% ====== Zero adjusted 
y = y-mean(y); 
%wavplay(y, fs, 'sync'); 
 
% ====== Take frames 
framedY  = buffer(y, frameSize, overlap); 
frameNum = size(framedY, 2);	% Number of frames 
 
% ====== Compute log energy 
meanFrame = (mean(framedY.^2)); 
meanFrame(meanFrame==0) = eps; 
energy = 10*log10(meanFrame); 
time = (1:frameNum)*(frameSize-overlap)/fs; 
energyLevel1 = max(energy)+deltaEnergyLevel1; 
energyLevel2 = max(energy)+deltaEnergyLevel2; 
 
% ====== Compute zero crossing rate 
zcr = zcratemex(framedY); 
 
% ====== Find initial end points according energy level2 (upper level) 
voicedIndex = find(energy>=energyLevel2); 
zcrThreshold = max(zcr)*zcrRatio; 
sound = []; 
k = 1; 
sound(k).begin = voicedIndex(1); 
for i=2:length(voicedIndex)-1, 
	if voicedIndex(i+1)-voicedIndex(i)>1, 
		sound(k).end = voicedIndex(i); 
		sound(k+1).begin = voicedIndex(i+1); 
		k = k+1; 
	end 
end 
sound(k).end = voicedIndex(end); 
 
% ====== Delete short sound clips 
index = []; 
for i=1:length(sound), 
	if (sound(i).end-sound(i).begin)<5 
		index = [index, i]; 
	end 
end 
sound(index) = []; 
 
%minIndex = localmax(-energy);	% Find index of local minima 
% ====== Expand end points to energy level1 (lower level) 
for i=1:length(sound), 
	head = sound(i).begin; 
%	while (head-1)>=1 & energy(head-1)>energyLevel1 & ~minIndex(head-1), 
	while (head-1)>=1 & energy(head-1)>energyLevel1, 
		head=head-1; 
	end 
	sound(i).begin = head; 
	tail = sound(i).end; 
%	while (tail+1)<=length(energy) & energy(tail+1)>energyLevel1 & ~minIndex(tail+1), 
	while (tail+1)<=length(energy) & energy(tail+1)>energyLevel1, 
		tail=tail+1; 
	end 
	sound(i).end = tail; 
end 
 
% ====== Expand end points to include high zcr region 
for i=1:length(sound), 
	head = sound(i).begin; 
	while (head-1)>=1 & zcr(head-1)>zcrThreshold, 
		head=head-1; 
	end 
	sound(i).begin = head; 
end 
 
% ====== Delete repeated sound segments 
if length(sound) ~=0, 
	index = []; 
	for i=1:length(sound)-1, 
		if sound(i).begin==sound(i+1).begin & sound(i).end==sound(i+1).end, 
			index=[index, i]; 
		end 
	end 
	sound(index) = []; 
end; 
 
% ====== Transform sample-point-based index 
if length(sound) ~=0, 
	for i=1:length(sound), 
		out(i).begin = sound(i).begin*(frameSize-overlap); 
		out(i).end   = min(length(y), sound(i).end*(frameSize-overlap)); 
	end 
else 
   out = []; 
end; 
 
if plotOpt, 
 
subplot(3,1,1); 
plot((1:length(y))/fs, y); 
axis([-inf inf -1 1]); 
ylabel('Amplitude'); 
title('Wave form'); 
 
subplot(3,1,2); 
plot(time, energy); 
line([min(time), max(time)], energyLevel1*[1 1], 'color', 'c'); 
line([min(time), max(time)], energyLevel2*[1 1], 'color', 'c'); 
axis tight 
ylabel('Log energy (dB)'); 
title('Log energy'); 
 
subplot(3,1,3); 
plot(time, zcr); 
line([min(time), max(time)], zcrThreshold*[1 1], 'color', 'c'); 
axis([-inf inf 0 inf]); 
ylabel('ZCR'); 
title('Zero crossing rate'); 
 
% Plot end points 
subplot(3,1,1); 
yBound = [-1 1]; 
for i=1:length(sound), 
	line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r'); 
	line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g'); 
end 
% Plot end points 
subplot(3,1,2); 
yBound = [min(energy) max(energy)]; 
for i=1:length(sound), 
	line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r'); 
	line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g'); 
end 
 
% Plot end points 
subplot(3,1,3); 
yBound = [0 max(zcr)]; 
for i=1:length(sound), 
	line(sound(i).begin*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'r'); 
	line(  sound(i).end*(frameSize-overlap)/fs*[1,1], yBound, 'color', 'g'); 
end 
 
% Play the segmented sound 
head = sound(1).begin*(frameSize-overlap); 
tail = min(length(y), sound(end).end*(frameSize-overlap)); 
thisY = y(head:tail); 
fprintf('His return to hear the cutted sound %g:', i); 
pause; 
fprintf('\n'); 
wavplay(thisY, fs, 'sync'); 
fprintf('\n'); 
end 
 
% ====== Self demo 
function selfdemo 
epdParam.frameSize = 256; 
epdParam.overlap = 86; 
epdParam.deltaEnergyLevel1 = -28; 
epdParam.deltaEnergyLevel2 = -14; 
epdParam.zcrRatio = 0.5; 
fs = 8000; 
duration = 3; 
plotOpt = 1; 
%y = recsound('test.wav', duration, fs); 
[y, fs] = wavreadc('wavefile/1Roger/金門王與李炳輝.wav'); 
out = feval(mfilename, y, fs, plotOpt, epdParam);