function [mag,pts] = locatespeech(sig,N,step,fs) % [magnitude,points] = locatespeech(signal, window, step, samplingfreq) % % locatespeech - returns cut magnitude and a vector of endpoints (pts) of speech signal. % % To find the enpoints, locatespeech does the following: % 1) Removes any DC offset in the signal % 2) Computes magnitude and zero-crossing rate of the signal % 3) Computes magnitude and zero-crossing rate of noise at 1st 100 ms. % 4) Set thresholds based on these values of noise % 5) For start point: % a) Find pt. where mag consistently tops upper mag threshold % b) Work backwards to see where it goes below lower mag threshold % c) Look in the previous 25 frames of zeroxing to see if it is still % above the zero-xing threshold. If so, move it back to where it % first drops below this threshold. % 6) For end point, follow the same procedure as in (5) except reverse % everything % % ELEC 301 Project - "Mars Lander the Theologian", aka, "Speaker Verification" % Sara MacAlpine, Aamir Virani, Nipul Bharani, JP Slavinsky % WRC (OCEE) Class of 2001 - Fall '99 % 1) Remove DC offset sig_no_dc = removedc(sig); % 2) Compute Avg. Mag and Zero-X rate of sig m = avgmag(sig_no_dc,N,step); z = zeroxing(sig_no_dc,N,step); % 3) Compute mag and zero-crossing of noise (first 100 msec of sig) - already computed, % just cut it out of m and z above hundredmsec_rel = round((fs*.2)/step); % # samples that equals 100ms % Ends of these may be corrupted due to zero padding -- chop off N/step % samples from each side chop = ceil((N/2-step)/step); % round up for safety noise_m = m(2+chop:hundredmsec_rel-chop); noise_z = z(2+chop:hundredmsec_rel-chop); % Compute means and st. deviations of each, so we can develop thresholds. noise_m_mean = mean(noise_m); noise_m_std = std(noise_m); noise_z_mean = mean(noise_z); noise_z_std = std(noise_z); % Set lower thresholds fudge = 5; ITL = noise_m_mean + fudge*noise_m_std; IZCT = noise_z_mean + fudge*noise_z_std; % Define upper threshold for avg mag. ITU = 3.2*noise_m_mean; % since std << mean, twice the mean should cover it % find place where sig consistently tops ITU. start = 3; % since window goes back two spots, start at 3rd sample avg_last3pts = 0; % ITU won't be topped in the first 3 pts, so initialize to 0 while avg_last3pts < ITU, start = start + 1; avg_last3pts = (m(start) + m(start-1) + m(start-2))/3; end % move backwards to find where we first go under ITL while m(start) > ITL, start = start - 1; end % See if need to move start back due to zero-crossing below_izct_count = 0; first_below = -999; if start > 25 for i = start:-1:start-25, if z(i) < IZCT below_izct_count = below_izct_count + 1; if first_below == -999 first_below = i; end end end if below_izct_count >= 3 start = first_below; end end % Now do the same process backwards for the end; endpt = length(m)-2; avg_last3pts = 0; % threshhold won't occur in first 3 pts, so initialize to 0 while avg_last3pts < ITU, endpt = endpt - 1; avg_last3pts = (m(endpt) + m(endpt+1) + m(endpt+2))/3; end % move forwards to find where we first go under ITL while m(start) > ITL, endpt = endpt + 1; end % See if need to move start back due to zero-crossing below_izct_count = 0; first_below = -999; if (endpt-length(z)) > 25 for i = endpt:1:endpt+25, if z(i) < IZCT below_izct_count = below_izct_count + 1; if first_below == -999 first_below = i; end end end if below_izct_count >= 3 endpt = first_below; end end % Return values (multiply endpoints by step so that it is scaled % appropriately for the actual signal mag = m(start:endpt); pts = [start*step endpt*step];