%% 1) File Input and preprocessing
clc
clear all
close all

SNRs = [30, 20, 10, 5, 0, -5];

audioPath = strcat(pwd, '/audio/');          
audioFiles = dir(strcat(audioPath, '*.wav'));

fs = 8000;                                  % Desired sampling frequency
NumWords = 10;
NumRecordings = 5;

ConditionLabels = {'Clean', '30dB Car', '20dB Car', '10dB Car', '5dB Car', '0dB Car', '-5dB Car', ...
                    '30dB Babble', '20dB Babble', '10dB Babble', '5dB Babble', '0dB Babble', '-5dB Babble'};
                
ConditionFileNames = {'Clean', '30dB Car', '20dB Car', '10dB Car', '5dB Car', '0dB Car', 'minus5dB Car', ...
                    '30dB Babble', '20dB Babble', '10dB Babble', '5dB Babble', '0dB Babble', 'minus5dB Babble'};
          
AllConditions = cell(1, size(ConditionLabels,2));
for i = 1:size(ConditionLabels,2)
    AllConditions{i} = cell(1, NumWords);
    for j = 1:NumWords
        AllConditions{i}{j} = cell(1, NumRecordings);
    end
end

audioFileIndex = 1;                     % # of audio files in directory
curWord = 1;                           % Index representing the test word
curRecording = 1;                       % Index representing the test recording

while curWord < NumWords
    
    while curRecording < NumRecordings
        
        curWord = str2double(audioFiles(audioFileIndex).name(1)) + 1;
        curRecording = str2double(audioFiles(audioFileIndex).name(2));
        
        [wordAudio, fs0] = audioread([audioPath, audioFiles(audioFileIndex).name]);  % Resample to 8K fs
        wordAudio = resample(wordAudio, fs, fs0);          % resampled raw signal
        
        wordAudio_babble = zeros(length(wordAudio), length(SNRs));
        wordAudio_volvo = zeros(length(wordAudio), length(SNRs));
        
        for k = 1:length(SNRs)
            wordAudio_babble(:,k) = AddNoise(wordAudio, 2, SNRs(k));
            wordAudio_volvo(:, k) = AddNoise(wordAudio, 3, SNRs(k));
        end
        
        AllFeaturesForWord = cell(size(ConditionLabels, 2),1);
        
        % 2) Extract features
        [energyVec, numFrames] = ExtractFeatures(wordAudio(:,1), fs, 0.030, 0.50);
        AllFeaturesForWord{1} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:, 1), fs, 0.030, 0.50);
        AllFeaturesForWord{2} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:,2), fs, 0.030, 0.50);
        AllFeaturesForWord{3} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:,3), fs, 0.030, 0.50);
        AllFeaturesForWord{4} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:,4), fs, 0.030, 0.50);
        AllFeaturesForWord{5} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:,5), fs, 0.030, 0.50);
        AllFeaturesForWord{6} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_volvo(:,6), fs, 0.030, 0.50);
        AllFeaturesForWord{7} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,1), fs, 0.030, 0.50);
        AllFeaturesForWord{8} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,2), fs, 0.030, 0.50);
        AllFeaturesForWord{9} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,3), fs, 0.030, 0.50);
        AllFeaturesForWord{10} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,4), fs, 0.030, 0.50);
        AllFeaturesForWord{11} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,5), fs, 0.030, 0.50);
        AllFeaturesForWord{12} = energyVec;
        
        [energyVec, ~] = ExtractFeatures(wordAudio_babble(:,6), fs, 0.030, 0.50);
        AllFeaturesForWord{13} = energyVec;
%         M13{curRecording} = energyVec;
        
        audioFileIndex = audioFileIndex + 1;
        
        for i = 1:size(AllConditions,2)
            AllConditions{i}{curWord}{curRecording} = AllFeaturesForWord{i};
        end
    end
    
    curRecording = 1;                  
end

%% Classification & Evaluation
% ConditionLabels = {'Clean', '30dB Car', '20dB Car', '10dB Car', '5dB Car', '0dB Car', '-5dB Car', ...
%                     '30dB Babble', '20dB Babble', '10dB Babble', '5dB Babble', '0dB Babble', '-5dB Babble'};
                
for conditionNum = 1:size(AllConditions,2)
    
    % Find Euclidean Distance measure for each frame of each word
    for TestCount = 1:5
        
        ADMTest = cell(1,10);       
        recordingNumbersToTest = randi(NumRecordings,1,10);            % Select a random recording # to test for each word
        
        for testWord = 1:10
            
            testWordRecordingNum = recordingNumbersToTest(testWord);    % Get the randomly selected ith word to test

            TestWordFeatureMatrix = AllConditions{conditionNum}{testWord}{testWordRecordingNum}; % Get the Feature Matrix for this word
            ADMTestWord = cell(1,10);
            
            for referenceWord = 1:10
                ADMReferenceWord = cell(1,NumRecordings-1);
                
                i = 0;
                
                for referenceWordRecordingNum = 1:NumRecordings
                    
                    if referenceWordRecordingNum ~= testWordRecordingNum
                        i = i+1;
                        ReferenceWordFeatureMatrix = AllConditions{conditionNum}{referenceWord}{referenceWordRecordingNum};
                        E = EuclideanDistanceMatrix(TestWordFeatureMatrix, ReferenceWordFeatureMatrix);
                        ADMReferenceWord{i} = AccumulatedDistanceMatrix(E);
                    end
                    
                end
                
                ADMTestWord{referenceWord} = ADMReferenceWord;
            end
            
            ADMTest{testWord} = ADMTestWord;
            testWord;
        end
        
        % Create confusion matrix of comparison results
        confusionMatrix = zeros(10,10);
        
        for i = 1:10
            for j = 1:10
                distances = zeros(1,4);
                
                for k = 1:4
                    ADM = ADMTest{1,i}{1,j}{1,k};
                    Row = size(ADM,1);
                    Col = size(ADM,2);
                    distances(1,k) = ADM(Row,Col);
                end
                
                confusionMatrix(i,j) = mean(distances);
            end
        end
        
        % Calculate error
        err = zeros(1,10);
        
        for audioFileIndex = 1:10
            if confusionMatrix(audioFileIndex,audioFileIndex) == min(confusionMatrix(:,audioFileIndex))
                err(i) = 1;
            else
                err(i) = 0;
            end
        end
        
        err(TestCount, conditionNum) =  sum(err)/length(err);
        
        
        % Plot results
        fignum = TestCount + 5 * (conditionNum-1);
        fig = figure(fignum);
        set(fig, 'Position', [100 100 600 600]);
        imagesc(confusionMatrix);
        title({['Confusion Matrix for ', ConditionLabels{conditionNum}], ['Random Recording Test no. ', num2str(TestCount)]});
        xlabel('Test Word');
        ylabel('Reference Word');
        saveas(fig, [ConditionFileNames{conditionNum} '_' num2str(TestCount) '_cm'], 'png');
    end
end


error = (err(1, :) + err(2, :)) ./ 2;
e_volvo = err(2:7).*100;
e_babble = err(8:13).*100;