function [results, info] = chromamatthias(filename, prod, maxx)

%---------------------------------------------------------------
%   Part of the matthiasmISMIR08 project
%   Written by Christopher Harte, modified by Matthias Mauch 
%   @ Queen Mary, University of London
%   2008
%---------------------------------------------------------------


% Set up info structure (initialise variables to 0 if we don't have values
% now...

info = {};
%%
info.filename = filename;
% info.filename = '/Volumes/Music/Music/Beatles/12_-_Let_It_Be/wav/06_-_Let_It_Be.wav';
% info.filename = '/Volumes/Music/Music/Beatles/unrevised/01wave/01_-_I_Saw_Her_Standing_There.wav';
info.undertest = '';            % which algorithms are run

% Signal Parameters:
info.fs = 44100;                % Sampling freq of audio file
info.downsample  = 4;           % downsampling factor
info.fsdownsampled = ...
    info.fs / info.downsample;   % fs after downsampling
info.preprocessing = 'downsample'; % What kind of preprocessing?
info.numberframes = 0;          % number of frames calculated
info.windowlength = 0;          % window length in samples
info.overlap = ...
    1/8;                        % window overlap factor
info.overl = ...
    1 - info.overlap;
info.hopsize = 0;               % window overlap in samples
info.framespersecond = 0;       % effective frames per second

% Constant Q parameters:
info.binsperoctave = 36;        % bins per octave for const q
info.fmax = 1760;              % top frequency for const q
info.fmin = 110;                % bottom frequency for const q
info.numcqbins = 0;             % number of bins in a Constant Q vector
info.sparkernelfile = '';       % mat file containing sparse spectral kernels matrix 
info.sparsethreshold =  0.0054; % sparsekernel threshold
info.maxx = maxx;
% Get constant Q parameters - need to do this first to set window length
info = getcqparameters(info);

% Prepare chunking
info.chunkoverlap = 2 * 1/info.overlap;         % frames
info.audiofilesize = wavread(info.filename,'size');
info.chunksize =  500;          % frames
info.samplechunksize = (info.chunksize - 1) * ...
    info.hopsize * info.downsample; % chunk length in original samples
info.samplechunkhopsize = (info.chunksize - 1 - info.chunkoverlap) * ...
    info.hopsize * info.downsample;
info.framespersecond = info.fsdownsampled/info.hopsize;
%%
nChunk = ceil(info.audiofilesize / info.samplechunkhopsize);
results = {};
iChunk = 0;
for iChunk = 1:nChunk  
%
    info.startsample = (iChunk - 1) * info.samplechunkhopsize + 1;
    info.endsample = min(...
        info.startsample + info.samplechunksize -1, ...
        info.audiofilesize(1));
%
    [audiodata, info] = readaudiochunk(info);

    % Perform downsampling here if required

    [audiodata, info] = preprocessing(audiodata,info);

    % Perform FFT
    [fftframes,info] = bigframefft(audiodata,info);

    % Harmonics adjustment
    if prod
        [fftframes] = prodfft(fftframes, 3);
    end


    % Perform Constant Q
    [constqframes, info] = constq(fftframes,info);
    
    % Smooth constqframes for transient removal (time direction)
    constqframes = medfilt1(constqframes,round(info.framespersecond/2),[],2);

    % 'Normalise' Constant Q
    % constqframes = constqframes ./ repmat(sum(abs(constqframes),1),size(constqframes,1),1);

    % fftframes = 10 * log10(abs(fftframes).^2);

    % Calculate HPCP
    [hpcpframes,info] = hpcp(constqframes,info);

    % Peakpick HPCP
    % [peakpickframes,info] = framepeakpick(hpcpframes,info);


    % Calculate Tuning
    % [tuningframes,info] = tuning(peakpickframes,info);

    % Calculate slightly adjusted chromagram
    [chromaframes, info] = tunebyshift(hpcpframes, info);
    % figure,
    % imagesc(info.t,[],(chromaframes')), axis xy

    % put results in output structure
    if iChunk == 1
%         results.fftframes = fftframes;
%         results.constqframes = constqframes;
%         results.hpcpframes = hpcpframes;
        results.chromaframes = chromaframes;
    else
%         results.fftframes = ...
%             [results.fftframes(:,1:end-info.frameoverlap),...
%              results.fftframes(:,end-info.frameoverlap+1:end) ...
%              + fftframes(:,1:info.frameoverlap),...
%              fftframes(:,info.frameoverlap+1:end)];
%         results.constqframes = ...
%             [results.constqframes(:,1:end-info.frameoverlap),...
%              results.constqframes(:,end-info.frameoverlap+1:end) ...
%              + constqframes(:,1:info.frameoverlap),...
%              constqframes(:,info.frameoverlap+1:end)];
%         results.hpcpframes = ...
%             [results.hpcpframes(1:end-info.frameoverlap,:);...
%              results.hpcpframes(end-info.frameoverlap+1:end,:) ...
%              + hpcpframes(1:info.frameoverlap,:);...
%              hpcpframes(info.frameoverlap+1:end,:)];
        x = round(info.chunkoverlap/2);
%         results.chromaframes = chromaframes;
        results.chromaframes = ...
            [results.chromaframes(1:end-info.chunkoverlap+x,:);...
             chromaframes(2+x:end,:)];
    end
end
info.numberframes = size(results.chromaframes,1);
info.t = ((0:info.numberframes-1) * info.hopsize) / info.fsdownsampled;