function path = dtw4(key_t,sig_t) % path = dtw(key,input) % % dtw takes in a key signal, and an input signal and returns a path that % maps the indices of the input to the indices of the key. For example, if % the key had 5 (1..N) elements and input had 6 (1..M), with % path = [1 2 [3,4] 5 6], the new input would have five elements with % % new_input(1) = input(1) % new_input(2) = input(2) % new_input(3) = some function of input(3) and input(4) - avg? % new_input(4) = input(5) % new_input(5) = input(6) % % The following restriction holds: w(1) = 1, w(N) = M % % 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 global N M ldm key sig % Declare as global so don't have to pass them around key = key_t; sig = sig_t; N = length(key); M = length(sig); % Compute local distance matrix (ldm) - uses a Matlab trick K = key(ones(size(sig)),:); S = sig'; S = S(:,ones(size(key))); ldm = abs(K-S).^2; % Compute accumulative distance matrix (adm) global adm adm = zeros(M,N); adm(:,1) = ldm(:,1); for n = 2:N, col = adm(:,n-1); most = max(col) + 1; col = [most; most; col]; new = [col(1:M), col(2:M+1), col(3:M+2)]; minimums = min(new,[],2); adm(:,n) = ldm(:,n) + minimums; end % Derive best path, w, starting at w(N) = M and working back to w(1) = 1 % w(n) will be the indices of sig to use to shrink/stretch it to key length. % new_sig(1:N) = sig(w(n)); % Now using a modified Itakura algorithm -- can't go flat for 2 consecutive % times and can't use big jump 2 consecutive times w(N) = M; w(1) = 1; r = M; % r = row flatflag = 0; jumpflag = 0; for c = N-1:-1:2, % c = column % develop choices based on rows above current posn if (r >= 3) & ~jumpflag choices = [adm(r,c) adm(r-1,c) adm(r-2,c)]; elseif (r >= 3) & jumpflag choices = [adm(r,c) adm(r-1,c)]; jumpflag = 0; elseif (r == 2) choices = [adm(r,c) adm(r-1,c)]; elseif (r == 1) choices = [adm(r,c)]; end % find posn up of smallest change remove "flat choice" if just did flat % unless we're on the last row. if flatflag & (r ~= 1) choices = choices(2:length(choices)); posn = max(find(choices==min(choices))); if posn == length(choices) % we're going to use jump jumpflag == 1; end flatflag = 0; else posn = max(find(choices==min(choices))) - 1; if posn == 2 jumpflag = 1; end if posn == 0 flatflag = 1; end end % save path r = r - posn; w(c) = r; end % return path path = w;