//  Logistic Regression Analysis of motorcycle data
//  Ver. 1.0, 2013 May 22

////clear all;
//KF=0;

//WindowLocation;
//wloc = wloc9;
//KF=0;

//PaperUnit = 'centimeters';

//GraphMode = 'NONE';		% EPS, JPEG, PNG or NONE
//GraphHeader = 'LogisticRegression';   % First half of file name

//GraphDirectory = 'Graph';
//PaperPosition = [0 0 8 8];

//---------------------------
//  Parameter
//---------------------------
//NFFT = 2048;
int NFFT = 512;

int QuefrencyRange[2] = {3, 8}; // [ms]

int FrameLength = NFFT;
//FrameShift = NFFT/2;
int FrameShift = 160;

w = hamming(NFFT);

int flag_CepstrumNormalize = 1;

//---------------------------
//  Read data
//---------------------------

DataDirectory = '../../MotorCycle2013Jun';
LabelDirectory = 'Label';
DataFile = 'F5_60km_suzuki_16k';

File = [DataDirectory,'/',DataFile,'.wav'];
fprintf( 'File: %s\n', File );
[x,Fs,Nb] = wavread(File);

DataLength = length(x);
NumberOfFrame = floor((DataLength-FrameLength)/FrameShift);

//---------------------------
//  Read label
//---------------------------
File = [LabelDirectory,'/',DataFile,'.xlsx'];
TimeLabel = xlsread(File);
[NTimeLabel,dummy] = size(TimeLabel);

int flag_SpeechLabel[ARY_NUM_FRAMES]; // ARY_NUM_FRAMES :: 既知区間定位データのフレーム取得数の上限
//for(frame=0; frame<NumberOfFrame; frame++){
//    m1 = FrameShift*frame + 1;            // frame_start_sample
//    m2 = FrameShift*frame + FrameLength;  // frame_end_sample
//    //for(k=0; k<NTimeLabel; k++){ // ラベル数（発話数）だけ回す（フレーム単位の発話情報があればいらない）
//    //    flag_SpeechLabel[frame] = 0;
//    //    //L1 = TimeLabel(k,1); // 発話開始時間を取得しているだけ（いらない）
//    //    //L2 = TimeLabel(k,2); // 発話終了時間を取得しているだけ（いらない）
//    //    //t1 = floor(L1)*60 + (L1-floor(L1))*100; // 独自形式から秒数に変換しているだけ（いらない）
//    //    //t2 = floor(L2)*60 + (L2-floor(L2))*100; // 独自形式から秒数に変換しているだけ（いらない）
//    //    n1 = round(Fs*t1); // n1 == speech_start_sample
//    //    n2 = round(Fs*t2); // n2 == speech_end_sample
//    //    if(n1 < m1 && m1 < n2){
//    //        flag_SpeechLabel[frame] = 1;
//    //        break;
//    //    }
//    //    if(n1 < m2 && m2 < n2)
//    //        flag_SpeechLabel[frame] = 1;
//    //        break;
//    //    }
//    //}
//    ////flag_SpeechLabel[frame] = 0 or 1;
//    //Power[frame] = x(m1:m2)'*x(m1:m2); // グラフ表示以外にパワーの結果を使っていないからいらない
//    //for(i=0; i<ADVANCE; i++){
//    //    Power[frame][i] = x[i]*x[i];
//    //}
//}

//KF = 1;
//fig = figure(KF);
//GraphTitle = 'PowerLabel';
//set(fig,'Name',GraphTitle,'Position',[0 0 160 160],...
//    'PaperUnits',PaperUnit,'PaperPosition', PaperPosition );
//tm = [0:NumberOfFrame-1]*FrameShift/Fs;
//subplot(2,1,1),plot(tm,Power);
//title('(a) Power')
//axis([min(tm) max(tm) 0 max(Power)]);
//subplot(2,1,2),plot(tm,Label);
//title('(b) Label')
//axis([min(tm) max(tm) 0 1.1]);
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);


//---------------------------
//  Cepstrum analysis
//---------------------------
int cn[2];
float ms2sample = Fs/1000;
cn[0] = (int)(QuefrencyRange[0]*ms2sample + 0.5f) + 1;
cn[1] = (int)(QuefrencyRange[1]*ms2sample + 0.5f) + 1;

C1 = [];
C2 = [];

for(frame=0; frame<NumberOfFrame; frame++){
    t1 = FrameShift*frame + 1;
    t2 = FrameShift*frame + FrameLength;
    Z = fft(w.*x(t1:t2));
    ZZ = log(abs(Z));
    CC = real(ifft(ZZ));
    if(flag_CepstrumNormalize){
        Feature(frame) = max(abs(CC(cn[0]:cn[1])))/abs(CC[0]);
    }
    else{
        Feature(frame) = max(abs(CC(cn[0]:cn[1])));
    }        
    CEP0[frame] = CC[0];
    if(flag_SpeechLabel(frame)){
        C1 = [C1 Feature(frame)];
    }
    else{
        C2 = [C2 Feature(frame)];
    }
}

dmax = max(Feature);
int num_bin = 100;
float coef = 1.1f / (float) num_bin;
float Bin[num_bin];
for(i=0; i<=num_bin; i++){
    Bin[i] = dmax * i * coef;
}

//KF = 2;
//fig = figure(KF);
//GraphTitle = 'Histgram';
//set(fig,'Name',GraphTitle,'Position',[0 0 160 160],...
//    'PaperUnits',PaperUnit,'PaperPosition', PaperPosition );
//H1 = hist(C1,Bin);
//H2 = hist(C2,Bin);
//subplot(2,1,1),bar(Bin,H1);
//title('(a) Speech');
//subplot(2,1,2),bar(Bin,H2);
//title('(b) Blank');
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);

//---------------------------
//  Logistic Regression
//---------------------------
mu1 = mean(C1);
sigma1 = std(C1);
mu2 = mean(C2);
sigma2 = std(C2);

dmax = max(Feature);
XV = [0:(dmax*1.1)/100:dmax*1.1];
%P1 = pdf('norm',XV,mu1,sigma1);
phat = gamfit(C1);
P1 = pdf('Gamma',XV,phat[0],phat[1]);
P2 = pdf('norm',XV,mu2,sigma2);

//KF = 3;
//fig = figure(KF);
//GraphTitle = 'Likelihood';
//set(fig,'Name',GraphTitle,'Position',[0 0 160 160],...
//    'PaperUnits',PaperUnit,'PaperPosition', PaperPosition );
//plot(XV,P1,'r',XV,P2,'b');
//legend('Speech','Blank');
//title('Likelihood');
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);


//KF = 4;
//fig = figure(KF);
//GraphTitle = 'Posterior';
//set(fig,'Name',GraphTitle,'Position',[0 0 160 160],...
//    'PaperUnits',PaperUnit,'PaperPosition', PaperPosition );
float tmp;
for(i=0; i<length(XV); i++){ // length(XV) == 1x101
    tmp = P1[i] + P2[i];
    LG1[i] = P1[i] / tmp;
    LG2[i] = P2[i] / tmp;
}
//plot(XV,LG1,'r',XV,LG2,'b');
//legend('Speech','Blank');
//title('Posterior');
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);


//KF = 5;
//fig = figure(KF);
//GraphTitle = 'Feature';
//set(fig,'Name',GraphTitle,'Position',[0 0 160 160],...
//    'PaperUnits',PaperUnit,'PaperPosition', PaperPosition );
//tm = [0:NumberOfFrame-1]*FrameShift/Fs;
//plot(tm,Feature);
//title('Feature');
//axis([min(tm) max(tm) min(Feature) max(Feature)]);

//---------------------------
//  Evaluation
//---------------------------
TargetProbability = 0.95;
fprintf( 'Target Probability:%f\n', TargetProbability );

for(i=0; i<length(XV); i++){
    if((LG1[i+1]>LG2[i+1]) && (LG1[i]<=LG2[i]) && (XV[i]>0.005)){ break; } // クロスポイントの次要素まで移動
}
for(; i<length(XV); i++){
    if(LG1[i] > TargetProbability){ break; } // ターゲットの確率を超える要素をサーチ
}
Threshold = XV[i]; // 要素に対応する閾値を取得
fprintf( 'Threshold:%f\n', Threshold );
//figure(4);
//LineX = Threshold*ones(1,2);
//LineY = [LG1(n) 0];
//hold on;
//plot(LineX,LineY,'--g');
//hold off;
//GraphTitle = 'Posterior';
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);



//figure(5);
//LineX = [0 NumberOfFrame];
//LineY = Threshold*ones(1,2);
//hold on;
//plot(LineX,LineY,'--g');
//hold off;
//GraphTitle = 'Feature';
//SaveGraphics(GraphTitle,GraphHeader,GraphDirectory,GraphMode);

location_fid = fopen('loc.txt', 'w+');

detect_idx         = 0;
detect_cont_flag   = 0;
detect_start_frame = 0;
detect_end_frame   = 0;

CorrectSpeech = 0;
NDetect = 0;
NSpeech = 0;
for(frame=0; frame<NumberOfFrame; frame++){
    if(Label(frame) && Feature(frame) >= Threshold){
        CorrectSpeech = CorrectSpeech + 1;

        if(detect_cont_flag == 0){
        //    detect_start_frame = frame;
            detect_cont_flag = 1;
        }
        fprintf(location_fid, '%d %d 1 0 0 \n', frame, detect_idx);
    }
    else{
        if(detect_cont_flag == 1){
        //    detect_end_frame = frame - 1;
            detect_cont_flag = 0;
            detect_idx = detect_idx + 1;
        }
        fprintf(location_fid, '%d \n', frame);
    }
    //
    if(Feature(frame) >= Threshold){
        NDetect = NDetect + 1;
    }
    //
    if(Label(frame)){
        NSpeech = NSpeech + 1;
    }
}
Precision = CorrectSpeech/NDetect;
Recall = CorrectSpeech/NSpeech;

fclose(location_fid);

SpeechEvent = 0;
for(k=0; k<NTimeLabel; k++){
    //L1 = TimeLabel(k,1);
    //L2 = TimeLabel(k,2);
    //t1 = floor(L1)*60 + (L1-floor(L1))*100;
    //t2 = floor(L2)*60 + (L2-floor(L2))*100;
    n1 = round(Fs*t1); // 開始サンプル
    n2 = round(Fs*t2); // 終了サンプル
    for(n=n1; n<=n2; n++){
        frame = floor(n/FrameShift) + 1;
        if(Feature(frame) >= Threshold){
            SpeechEvent = SpeechEvent + 1;
            break;
        }
    }
}
EventDetection = SpeechEvent/NTimeLabel;

fprintf( 'Precision: %f\n', Precision );
fprintf( 'Recall:%f\n', Recall );
fprintf( 'Event Detection: %f\n', EventDetection);





