function [model,offsets,lhood] = align_chroma(d)
% [model,offsets,lhood] = align_chroma(d)
%    d is a cell array of chroma matrices from particular songs.
%    Figure out a rotation for the rows of each matrix that 
%    gives the most compact model of the entire data.
%    model.{mean,sigma} returns a single gaussian model for the aligned data
%    offsets is a vector of the rotations applied to each cell of d.
% 2007-04-14 dpwe@ee.columbia.edu

nd = length(d);

% Assume first matrix has alignment zero
d1 = d{1};
[nr,nc] = size(d1);
model.mean = mean(d1,2);
model.sigma = cov(d1')';
model.invsigma = inv(model.sigma);
model.prior = 1;
model.ngmm = 1;
offsets = zeros(1,nd);
oldoffsets = offsets - 1;

while sum(offsets == oldoffsets) < nd

  oldoffsets = offsets;
  
  [lhood,offsets] = model_match_chroma(model,d);
%  fprintf(' %d',offsets);fprintf(' %f\n',lhood);
  
  %%%%%% FAKEOUT
  %offsets = 0*offsets;
  
  %%[mm,ss] = gaussian_rot_chroma(d, offsets);
  % Calcuate a new model using all datasets
  nsu = zeros(nr,1);
  nsp = zeros(nr,nr);
  npt = 0;

  nd = length(d);

  % cumulate 1st and 2nd order stats
  for i = 1:nd
    dt = chromrot(d{i}, offsets(i));
    npt = npt + size(dt,2);
    nsu = nsu + sum(dt,2);
    nsp = nsp + dt*dt';
  end

  % new model
  mm = nsu/npt;
  ss = (npt/(npt-1))*(nsp/npt - mm*mm');
  
end

model.mean = mm;
model.sigma = ss;
model.invsigma = inv(model.sigma);
model.nmix = 1;
