function [net,U]=SpDetectTrain(filelist,T,fs,pc,flag)
% function [net,HOSVD]=SpDetectTrain(filelist,T,fs,[pcf pcr pcs],[flag1 flag2 flag3 flag4])
%
% this function is used to train the speech detector. Name of file samples
% are given in filelist variable and the system returns and save to the
% disk the svm weights and HOSVD (U).
%
% filelist: The structure array that contains the following fields:
%   name: full name of the wave file to be used, eg. 'si1387.wav'
%   start: in milisecond, is the starting point of the file for traning,
%           eg. 1000
%   class: label of the file, eg. 'Speech'  or 'Music' or 'Animal'.
%           anything but 'Speech' will be in non-speech class
%   path: the full path of the file, e.g. 'c:\files\Timit'
%   istrain: if 1, the sample will be used for training
%            if 0, the sample will be used for testing (with flag4=1)
% T: in milisecond is the length of the time duration used for training, eg.
%   250. The default is 1000 milisecond.
% fs: sampling frequency of the system. All files with different sampling
%   frequencies will be resampled at fs
% pc: a structure in the form of [pcf pcr pcs], number of retained principal components in subspaces of
%   frequency, rate and scale. The default is [7 5 4]
% flag: a structure in the form of [flag1 flag2 flag3 flag4], default: [1 1 1 1]
%   flag1: 1 make the rate-scale-frequency representation, 0 load it from
%       current directory (for faster development)
%   flag2: 1 make the HOSVD, 0 load it from the current directory
%   flag3: 1 train the SVM, 0 load it from the current directory
%   flag4: 1 test the classifier on the test set, 0 do nothing

% Nima Mesgarani, NSL, mnima@glue.umd.edu
if nargin<5 flag1=1;flag2=1;flag3=1;flag4=1;
elseif isempty(flag) flag1=1;flag2=1;flag3=1;flag4=1;
else flag1=flag(1);flag2=flag(2);flag3=flag(3);flag4=flag(4);end

if nargin<4 pcf=7;pcr=5;pcs=4;
elseif isempty(pc) pcf=7;pcr=5;pcs=4;
else pcf=pc(1);pcr=pc(2);pcs=pc(3);end
if nargin<3 fs=16000;end
if nargin<2 T=1000;end
if flag1==1 % making rate-scale-frequency
    figure;loadload;close all;
    rv=2.^(0:5);
    sv=2.^(-1:3);
    frame=8;
    paras=[frame frame -2 log2(fs/16000)];
    for cnt1=1:length(filelist)
        disp([num2str(cnt1) ' out of ' num2str(length(filelist))]);
        fname=[filelist(cnt1).path filesep filelist(cnt1).name];
        [siz f]=wavread(fname,'size');
        temp=filelist(cnt1).start;
        N1=1+f*temp/1000;N2=min(f*(temp+T)/1000, siz(1));
        [wav,f]=wavread(fname,floor([N1 N2]));
        if f~=fs wav=resample(wav,fs,f);end
        if strcmpi(computer,'pcwin')
            aud=cochlear_filt(unitseq(wav),paras);
            cor=c_aud2cor_calling_matlab_gencort(aud,[paras],rv,sv);
            cor=double(permute(cor,[3 4 2 1 ]));
        else
            aud = wav2aud(unitseq(wav),paras);
            cor = aud2cor(aud,[paras 0 0 1],rv,sv,'tmp');
        end
        rsf=squeeze(mean(abs(cor),3));
        rsf(isnan(rsf))=0;
        rsfs(cnt1).rsf=rsf;
        rsfs(cnt1).name=filelist(cnt1).name;
        rsfs(cnt1).start=filelist(cnt1).start;
        rsfs(cnt1).class=filelist(cnt1).class;
        rsfs(cnt1).path=filelist(cnt1).path;
        rsfs(cnt1).istrain=filelist(cnt1).istrain;
    end
    save (['rsfs' num2str(T)],'rsfs');
else
    load (['rsfs' num2str(T)]);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% HOSVD
if flag2==1
    ind=1;
    for cnt1=1:length(rsfs)
        if filelist(cnt1).istrain==1
            allrsf(:,:,:,ind)=(rsfs(cnt1).rsf-mean2(rsfs(cnt1).rsf))/std2(rsfs(cnt1).rsf);
            ind=ind+1;
        end
    end
    [U,La]=tsvd(allrsf);
    U{4}=[];La{4}=[];
    HOSVDname = ['HOSVD' num2str(T)];
    if exist([HOSVDname '.mat'],'file')
        temp = input('The file already exists, enter a new name (enter to overwrite): ','s');
    end
    if ~isempty(temp)
        HOSVDname = temp;
    end
    save(HOSVDname,'U','La');
else
    load(['HOSVD' num2str(T)]);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TRAINING
if flag3==1
    ind=1;
    for cnt1=1:length(rsfs)
        if filelist(cnt1).istrain==1
            A=(rsfs(cnt1).rsf-mean2(rsfs(cnt1).rsf))/std2(rsfs(cnt1).rsf);
            A=tmuln(A,U{1}(:,1:pcs)',1);
            A=tmuln(A,U{2}(:,1:pcr)',2);
            if length(size(A))<3 A=reshape(A,[1 size(A,1) size(A,2)]);end
            A=tmuln(A,U{3}(:,1:pcf)',3);
            A=(A-mean2(A))/std2(A);
            train(:,ind)=A(:);
            if filelist(cnt1).class(1)=='S' y(ind)=1; else y(ind)=-1; end
            ind=ind+1;
        end
    end
    % for a linear classfier use the following line:
%      net=svm(size(train,1),'linear');
    net=svm(size(train,1),'rbf',1,10);
    % for optimization of the SVM, uncomment the following line:
%         net=svmcv(net,train',y',[0.5 10]);
    net=svmtrain(net,train',y');
    netname = ['net' num2str(T)];
    if exist([netname '.mat'],'file')
        temp = input('The file already exists, enter a new name (enter to overwrite): ','s');
    end
    if ~isempty(temp)
        netname = temp;
    end
    save(netname,'net');
else
    load (['net' num2str(T)],'net');
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CLASSIFICATION
if flag4==1
    ind=1;
    clear y;
    for cnt1=1:length(rsfs)
        if filelist(cnt1).istrain==0
            A=(rsfs(cnt1).rsf-mean2(rsfs(cnt1).rsf))/std2(rsfs(cnt1).rsf);
            A=tmuln(A,U{1}(:,1:pcs)',1);
            A=tmuln(A,U{2}(:,1:pcr)',2);
            if length(size(A))<3 A=reshape(A,[1 size(A,1) size(A,2)]);end
            A=tmuln(A,U{3}(:,1:pcf)',3);
            A=(A-mean2(A))/std2(A);
            test(:,ind)=A(:);
            if rsfs(cnt1).class(1)=='S' y(ind)=1; else y(ind)=-1; end
            ind=ind+1;
        end
    end
    r=svmfwd(net,test');
    plot(y,'.-');
    hold on;
    plot(r,'g.-');
    legend('True','Classified');
    spind=find(y==1);
    npind=find(y==-1);
    conf(1,1)=100*length(find(r(spind)==1))/length(spind);
    conf(2,1)=100*length(find(r(npind)==1))/length(npind);
    conf(1,2)=100*length(find(r(spind)==-1))/length(spind);
    conf(2,2)=100*length(find(r(npind)==-1))/length(npind);
    figure;bar(conf);
    legend('detected as speech','detected as non-speech');
    set(gca,'XTickLabel',{'speech', 'nonspeech'});
    ylabel('Percentage');
    xlabel('actual');
end

