function [locksig, pitch_th, mag_th] = makelock(sig1,sig2,sig3,sig4,sig5)
% 
% [locksignal,pitch_thresh,mag_thresh] = makelock(sig1,sig2,sig3,sig4,sig5)
%
% makelock - Takes in 5 signals of the same person and returns one of the 5
% to be used as the "key" (the one that matches best with the others) and it
% also returns thresholds for pitch and magnitude to be used when matching
% signals.  The thresholds are capped at a 95% match.
%
% 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

% Make a signal vector for easy reference
sig = [ sig1 sig2 sig3 sig4 sig5 ];

% Possible pairs of signals to evaluate
grid = [ 1 1 1 1 2 2 2 3 3 4;
         2 3 4 5 3 4 5 4 5 5];
       
% Generate all possible pairwise correlations for pitch and magnitude
for i = 1:10,
  pitchcorr(i) = pitchmaster(sig(:,grid(1,i)),sig(:,grid(2,i)));
  magcorr(i)   = magmaster(sig(:,grid(1,i)),sig(:,grid(2,i)));
end

% Develop Thresholds
pitch_th = findthreshold(pitchcorr);
mag_th = findthreshold(magcorr);

% Pick key signal
locksig = sig(:,findlocksig(pitchcorr,magcorr,grid));


%--------------------------------------%
function key_index = findlocksig(pcorr,mcorr,grid)

% Put correlation for each signal into a matrix where each column
% corresponds to all matches with that signal (col 2 = sig2)
for i = 1:5,
  elements = (grid(1,:) == i | grid(2,:) == i);
  mcorrmat(:,i) = mcorr(elements)';
  pcorrmat(:,i) = pcorr(elements)';
end

% Column-wise averages
mavgs = mean(mcorrmat);
pavgs = mean(pcorrmat);

% 2x5 matrix of each signals mag and pitch averages
all_avgs = [mavgs; pavgs];

% Averages of each signals mag and pitch averages
avgs_of_avgs = mean(all_avgs);

% Find the index of the biggest of these averages -- represents the signal
% that matches best (on average) with the others.
[big_val, big_index] = max(avgs_of_avgs);

% Return this index
key_index = big_index;


%--------------------------------------%
function th = findthreshold(corr)

% Remove matches below .9 = 90% in order to make lock harder to pick.
corr = corr(corr>.9);

% Compute mean and standard deviation of the correlations
avg = mean(corr);
dev = std(corr);

% Produce a threshold that's a little less than the mean
th = avg-dev;

% If threshold is above 95%, we'll cap it down to 95%
if th > .95
  th = .95;
end
