% KAIST CS891 Special Lecture on Music Information Retrieval (MIR)
% Lab4.2: Key estimation
% Kyogu Lee (August 2008)

clear all;
close all;

% read audio file
%[x,fs] = wavread('../wav/8dayssegment.wav'); % vowel 'ooh'
[x,fs] = wavread('../wav/prelude_cmaj_seg.wav'); % vowel 'ooh'
%[x,fs] = wavread('../wav/T39-piano.wav'); % vowel 'ooh'
%[x,fs] = wavread('../wav/T08-violin.wav'); % vowel 'ooh'
if size(x,2) > size(x,1)
    x = x'; % make a column vector
end
x = mean(x,2); % make mono
%x = x(1:2*fs); % first two seconds

% perform chroma analysis
% there are three different types of chroma analyses (by Dan Ellis)

% analysis parameters
fftlen = 2048; % FFT length
hs = fftlen/4; % hop size
nbin = 12; % # of bins in an octave (usually 12)
f_ctr = 1000; % center frquency for weighting
f_sd = 1; % gaussian standard deviation for weighting

% (1) compute chromagram
ch_e = chromagram_E(x,fs,fftlen,nbin,f_ctr,f_sd);
ch_e2 = circshift(ch_e,-3); % shift from A to C
ch_avg = mean(ch_e2,2);

% key profiles
Cmaj_key_prof = [6.35;2.23;3.48;2.33;4.38;4.09;2.52;5.19;2.39;3.66;2.29;2.88];
Cmin_key_prof = [6.33;2.68;3.52;5.38;2.60;3.53;2.54;4.75;3.98;2.69;3.34;3.17];
maj_prof = []; % major key profile
min_prof = []; % minor key profile

for i=1:12 % for each key
  maj_prof = [maj_prof,circshift(Cmaj_key_prof,i-1)];
  min_prof = [min_prof,circshift(Cmin_key_prof,i-1)];
end

key_prof = [maj_prof,min_prof]; % 12x24 key profile matrix

% compute correlation
% $$$ cor = corr(ch_avg,key_prof);
% $$$ for k=1:24
% $$$   tmp = corrcoef(ch_avg,key_prof(:,k));
% $$$   cor(k) = tmp(1,2);
% $$$ end
cor = corrcoef([ch_avg,key_prof]);
cor = cor(1,2:end);
key = find(cor==max(cor)); % select maximum correlation profile

% display
key_label = {'C','C#','D','Eb','E','F','F#','G','Ab','A','Bb','B',...
             'c','c#','d','eb','e','f','f#','g','ab','a','bb','b'};

plot(cor,'bo-'); hold on; plot(key,cor(key),'rx','MarkerSize',16,...
                               'LineWidth',3); grid;
set(gca,'XTick',1:24);
set(gca,'XTickLabel',key_label);
vline(key,'g');