%\| Summer Semester 2014
%\| AudioLabs Lab Course
%===============================
%\| MODULE: Speech enhancement
%\| Prof. Dr.-Ing Emanuel Habets
%\| Module supervsors:
%\|     - Soumitro Chakrabarty
%\|     - Maja Taseska
%===============================
%\| Authors:
%\|     - Maja Taseska
%\|     - Affan Hasan Khan
%===============================
%===============================


function varargout = GUI_SE_Lab_Simple(varargin)
% GUI_SE_LAB_SIMPLE MATLAB code for GUI_SE_Lab_Simple.fig
%      GUI_SE_LAB_SIMPLE, by itself, creates a new GUI_SE_LAB_SIMPLE or raises the existing
%      singleton*.
%
%      H = GUI_SE_LAB_SIMPLE returns the handle to a new GUI_SE_LAB_SIMPLE or the handle to
%      the existing singleton*.
%
%      GUI_SE_LAB_SIMPLE('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUI_SE_LAB_SIMPLE.M with the given input arguments.
%
%      GUI_SE_LAB_SIMPLE('Property','Value',...) creates a new GUI_SE_LAB_SIMPLE or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before GUI_SE_Lab_Simple_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to GUI_SE_Lab_Simple_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help GUI_SE_Lab_Simple

% Last Modified by GUIDE v2.5 04-Jun-2014 16:39:45

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @GUI_SE_Lab_Simple_OpeningFcn, ...
    'gui_OutputFcn',  @GUI_SE_Lab_Simple_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before GUI_SE_Lab_Simple is made visible.
function GUI_SE_Lab_Simple_OpeningFcn(hObject, eventdata, handles, varargin)
addPaths
global settings
global FLAGS
global main

handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
FLAGS_define;
FLAGS_initialize;
disp('Flags initialized');


settings.num_mics = 4;
settings.mic_dist = 0.05;
settings.beam_orientation = 1; % 1: Broadside  2: Endfire
settings.arrcenter = [-0.5 -0.7 1.2].';
settings.source_dist = [1.8 1.8];
settings.source_angle = [90 0];
settings.room_size = [7.5 5.5 3];
settings.Fs = 16000;
settings.T60 = 0;
settings.maxApperture = 1;
main.STFT = init_STFT(settings.Fs, 1024);


[settings.mic_pos, settings.sourcePos] = room_simulator(settings.num_mics, settings.arrcenter, settings.mic_dist, settings.source_dist, settings.source_angle);
plotRoomSchematic(settings.mic_pos, settings.sourcePos, settings.room_size, handles);

%add the logo
axes(handles.axes_logo);
im1 = imread('ALABS@1000_logo.png');
image(flipdim(permute(im1,[2,1,3]),2));
axis image
axis off

% Setting the initial values in the GUI elements, from the settings
set(handles.edit_mic_dist,'string',num2str(settings.mic_dist));
set(handles.T60,'string',num2str(settings.T60));


% --- Outputs from this function are returned to the command line.
function varargout = GUI_SE_Lab_Simple_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;

function edit_num_mics_Callback(hObject, eventdata, handles)

global settings
global FLAGS
global main
FLAGS_define

maxMic = floor(settings.maxApperture/settings.mic_dist + 1);

test = 0;
if str2double(get(hObject,'String'))>maxMic
    set(hObject,'String',num2str(maxMic));
    test = 1;
end

if isequal(settings.beam_orientation,1)
    tmp = [90 0];
else
    tmp = [0 90];
end
settings.num_mics = str2double(get(hObject,'String'));
cla(handles.axes_room_plot,'reset');
[mic_pos, sourcePos] = room_simulator(settings.num_mics, settings.arrcenter, settings.mic_dist, settings.source_dist, tmp);
plotRoomSchematic(mic_pos, sourcePos, settings.room_size, handles);
update_fig_DSB
if test
    h = msgbox('The maximum allowed array size was exceeded. Microphone distance was set to the largest possible value','Info');
end

% --- Executes during object creation, after setting all properties.
function edit_num_mics_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in save_num_mic.
function save_num_mic_Callback(hObject, eventdata, handles)

function edit_mic_dist_Callback(hObject, eventdata, handles)
%
global settings
global FLAGS
global main
FLAGS_define

maxDist = settings.maxApperture/(settings.num_mics-1);
test = 0
if str2double(get(hObject,'String'))>maxDist
    set(hObject,'String',num2str(maxDist));
    test = 1;
end

if isequal(settings.beam_orientation,1)
    tmp = [90 0];
else
    tmp = [0 90];
end

settings.mic_dist = str2double(get(hObject,'String'));
cla(handles.axes_room_plot,'reset');
[mic_pos, sourcePos] = room_simulator(settings.num_mics, settings.arrcenter, settings.mic_dist, settings.source_dist, tmp);
plotRoomSchematic(mic_pos, sourcePos, settings.room_size, handles);
update_fig_DSB
if test
    h = msgbox('The maximum allowed array size was exceeded. The number of microphones was set to the largest possible value','Info');
end

% --- Executes during object creation, after setting all properties.
function edit_mic_dist_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in save_mic_dist.
function save_mic_dist_Callback(hObject, eventdata, handles)

function edit3_Callback(hObject, eventdata, handles)

% --- Executes during object creation, after setting all properties.
function edit3_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end

% --- Executes on button press in save_beam_orientation.
function save_beam_orientation_Callback(hObject, eventdata, handles)

% --- Executes on button press in push_run.
function push_run_Callback(hObject, eventdata, handles)
global FLAGS
global main
FLAGS_define
if FLAGS(flag_fig_spectra)
    FLAGS(flag_fig_spectra) = 0;
    delete(main.fig_handles.spectra);
end

script_generateSignals

% Enable Buttons
set(handles.h_push_plotSpectra, 'enable','on');
set(handles.h_push_estimateSOS, 'enable','on');
set(handles.push_applyDSB, 'enable','on');
set(handles.push_listenMix, 'enable','on');

% Reset performance values
set(handles.h_text_IRdsb,'string','');
set(handles.h_text_IRmvdrSV,'string','');
set(handles.h_text_IRmvdrATF,'string','');
set(handles.h_text_NRdsb,'string','');
set(handles.h_text_NRmvdrSV,'string','');
set(handles.h_text_NRmvdrATF,'string','');
set(handles.h_text_SDdsb,'string','');
set(handles.h_text_SDmvdrSV,'string','');
set(handles.h_text_SDmvdrATF,'string','');

% Disable Buttons
set(handles.push_applyMVDRstv,'enable','off');
set(handles.push_applyMVDR_atf,'enable','off');
set(handles.pushbutton14,'enable','off') % listen to DSB
set(handles.push_MVDRstvOut,'enable','off');
set(handles.push_MVDRatfOut,'enable','off');
set(handles.h_push_listenCombined,'enable','off');

if isfield(main.spectra,'Ydsb')
    main.spectra = rmfield(main.spectra,{'Ydsb','Xdsb','Vdsb'});
end
if isfield(main.spectra,'Ymvdr_FF')
    main.spectra = rmfield(main.spectra,{'Ymvdr_FF','Xmvdr_FF','Vmvdr_FF'});
end
if isfield(main.spectra,'Ymvdr_RF')
    main.spectra = rmfield(main.spectra,{'Ymvdr_RF','Xmvdr_RF','Vmvdr_RF'});
end

% Disable buttons on the spectrogram plot
if FLAGS(flag_fig_spectra)
   set(main.fig_spectra.h_radioMVDR_FF,'enable','off');
   set(main.fig_spectra.h_radioMVDR_RF,'enable','off');
   set(main.fig_spectra.h_radioDSB,'enable','off');
end


% --- Executes on selection change in popup_beam_orientation.
function popup_beam_orientation_Callback(hObject, eventdata, handles)

global settings
global main
global FLAGS
FLAGS_define


choice = questdlg('Changing the beam orientation will erase any performance evaluation and filtered signals in the workspace. Do you want to proceed?', ...
    'Warning', ...
    'Proceed','Cancel','Cancel');

if strcmp(choice,'Proceed')
    
    settings.beam_orientation = get(hObject,'Value');
    if isequal(settings.beam_orientation,1)
        tmp = [90 0];
    else
        tmp = [0 90];
    end
    cla(handles.axes_room_plot,'reset');
    [mic_pos, sourcePos] = room_simulator(settings.num_mics, settings.arrcenter, settings.mic_dist, settings.source_dist, tmp);
    plotRoomSchematic(mic_pos, sourcePos, settings.room_size, handles);
    update_fig_DSB
    
    % Reset performance values
    set(handles.h_text_IRdsb,'string','');
    set(handles.h_text_IRmvdrSV,'string','');
    set(handles.h_text_IRmvdrATF,'string','');
    set(handles.h_text_NRdsb,'string','');
    set(handles.h_text_NRmvdrSV,'string','');
    set(handles.h_text_NRmvdrATF,'string','');
    set(handles.h_text_SDdsb,'string','');
    set(handles.h_text_SDmvdrSV,'string','');
    set(handles.h_text_SDmvdrATF,'string','');
    
    % Disable Buttons
    set(handles.pushbutton14,'enable','off') % listen to DSB
    set(handles.push_MVDRstvOut,'enable','off');
    set(handles.push_MVDRatfOut,'enable','off');
    set(handles.h_push_listenCombined,'enable','off');
    
    if isfield(main.spectra,'Ydsb')
        main.spectra = rmfield(main.spectra,{'Ydsb','Xdsb','Vdsb'});
    end
    if isfield(main.spectra,'Ymvdr_FF')
        main.spectra = rmfield(main.spectra,{'Ymvdr_FF','Xmvdr_FF','Vmvdr_FF'});
    end
    if isfield(main.spectra,'Ymvdr_RF')
        main.spectra = rmfield(main.spectra,{'Ymvdr_RF','Xmvdr_RF','Vmvdr_RF'});
    end
    
    % Disable buttons on the spectrogram plot
    if FLAGS(flag_fig_spectra)
        set(main.fig_spectra.h_radioMVDR_FF,'enable','off');
        set(main.fig_spectra.h_radioMVDR_RF,'enable','off');
        set(main.fig_spectra.h_radioDSB,'enable','off');
    end
    
else
    if get(handles.popup_beam_orientation,'Value') == 1;
        set(handles.popup_beam_orientation,'Value',2);
    else
        set(handles.popup_beam_orientation,'Value',1);
    end
end



% --- Executes during object creation, after setting all properties.
function popup_beam_orientation_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function axes_room_plot_CreateFcn(hObject, eventdata, handles)

% --- Executes on button press in push_DSBfig.
function push_DSBfig_Callback(hObject, eventdata, handles)

global FLAGS
global main
global settings

FLAGS_define

if ~FLAGS(flag_fig_DSB)
    initialize_fig_DSB
    FLAGS(flag_fig_DSB) = 1;
else
    FLAGS(flag_fig_DSB) = 0;
    delete(main.fig_handles.DSB);
end

% --- Executes during object creation, after setting all properties.
function axes_logo_CreateFcn(hObject, eventdata, handles)



function T60_Callback(hObject, eventdata, handles)

global settings
settings.T60 = str2double(get(hObject,'String'));

% --- Executes during object creation, after setting all properties.
function T60_CreateFcn(hObject, eventdata, handles)
%
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in push_listenMix.
function push_listenMix_Callback(hObject, eventdata, handles)
global main
global settings
soundsc(main.signals.Y(:,1),settings.Fs);


% --- Executes on button press in push_applyDSB.
function push_applyDSB_Callback(hObject, eventdata, handles)
global FLAGS
global main
FLAGS_define

set(handles.h_text_IRdsb,'string','');
set(handles.h_text_SDdsb,'string','');
set(handles.h_text_NRdsb,'string','');

script_processDSB

str1 = num2str(-tmpIR);
str2 = num2str(tmpSD);
str3 = num2str(-tmpNR);
set(handles.h_text_IRdsb,'string',str1);
set(handles.h_text_SDdsb,'string',str2);
set(handles.h_text_NRdsb,'string',str3);

set(handles.pushbutton14 , 'enable','on');

test1 = get(handles.push_MVDRstvOut,'enable');
test2 = get(handles.push_MVDRatfOut,'enable');

if strcmp(test1,'on') && strcmp(test2,'on')
    set(handles.h_push_listenCombined,'enable','on')
end

% Enable the radio button on the spectra, if available
if FLAGS(flag_fig_spectra)
   set(main.fig_spectra.h_radioDSB,'enable','on');
end


% --- Executes on button press in pushbutton14.
function pushbutton14_Callback(hObject, eventdata, handles)
global main
global settings
soundsc(main.signals.Ydsb,settings.Fs);

% --- Executes on button press in push_applyMVDRstv.
function push_applyMVDRstv_Callback(hObject, eventdata, handles)
global main
global FLAGS
FLAGS_define

set(handles.h_text_IRmvdrSV,'string','');
set(handles.h_text_SDmvdrSV,'string','');
set(handles.h_text_NRmvdrSV,'string','');

script_processMVDR_FF

str1 = num2str(-tmpIR);
str2 = num2str(tmpSD);
str3 = num2str(-tmpNR);
set(handles.h_text_IRmvdrSV,'string',str1);
set(handles.h_text_SDmvdrSV,'string',str2);
set(handles.h_text_NRmvdrSV,'string',str3);

set(handles.push_MVDRstvOut,'enable','on');

test1 = get(handles.pushbutton14,'enable');
test2 = get(handles.push_MVDRatfOut,'enable');

if strcmp(test1,'on') && strcmp(test2,'on')
    set(handles.h_push_listenCombined,'enable','on')
end

if FLAGS(flag_fig_spectra)
   set(main.fig_spectra.h_radioMVDR_FF,'enable','on');
end


% --- Executes on button press in push_applyMVDR_atf.
function push_applyMVDR_atf_Callback(hObject, eventdata, handles)
global main
global FLAGS
FLAGS_define

set(handles.h_text_IRmvdrATF,'string','');
set(handles.h_text_SDmvdrATF,'string','');
set(handles.h_text_NRmvdrATF,'string','');

script_processMVDR_RF

str1 = num2str(-tmpIR);
str2 = num2str(tmpSD);
str3 = num2str(-tmpNR);

set(handles.h_text_IRmvdrATF,'string',str1);
set(handles.h_text_SDmvdrATF,'string',str2);
set(handles.h_text_NRmvdrATF,'string',str3);

set(handles.push_MVDRatfOut,'enable','on');

test1 = get(handles.push_MVDRstvOut,'enable');
test2 = get(handles.pushbutton14,'enable');

if strcmp(test1,'on') && strcmp(test2,'on')
    set(handles.h_push_listenCombined,'enable','on')
end

if FLAGS(flag_fig_spectra)
   set(main.fig_spectra.h_radioMVDR_RF,'enable','on');
end

% --- Executes on button press in push_MVDRstvOut.
function push_MVDRstvOut_Callback(hObject, eventdata, handles)
global main
global settings
soundsc(main.signals.Ymvdr_FF,settings.Fs);


% --- Executes on button press in push_MVDRatfOut.
function push_MVDRatfOut_Callback(hObject, eventdata, handles)
global main
global settings
soundsc(main.signals.Ymvdr_RF,settings.Fs);



% --- Executes on button press in push_panic.
function push_panic_Callback(hObject, eventdata, handles)
global main
global settings
FLAGS_define;
keyboard


% --- Executes on button press in h_push_plotSpectra.
function h_push_plotSpectra_Callback(hObject, eventdata, handles)
global FLAGS
global main
global settings

FLAGS_define

if ~FLAGS(flag_fig_spectra)
    initialize_fig_spectra
    FLAGS(flag_fig_spectra) = 1;
else
    FLAGS(flag_fig_spectra) = 0;
    delete(main.fig_handles.spectra);
end


% --- Executes on button press in h_push_save.
function h_push_save_Callback(hObject, eventdata, handles)
% hObject    handle to h_push_save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in h_push_listenCombined.
function h_push_listenCombined_Callback(hObject, eventdata, handles)

global main
global settings
lens = round(316000/4);
sig_to_play(1:lens) = main.signals.Y(1:lens,1);
sig_to_play(lens+1:2*lens) = main.signals.Ydsb(lens+1:2*lens);
sig_to_play(2*lens+1:3*lens) = main.signals.Ymvdr_FF(2*lens+1:3*lens);
sig_to_play(3*lens+1:4*lens) = main.signals.Ymvdr_RF(3*lens+1:4*lens);
soundsc(sig_to_play,settings.Fs);


% --- Executes on button press in h_push_estimateSOS.
function h_push_estimateSOS_Callback(hObject, eventdata, handles)

script_estimateSOS
set(handles.push_applyMVDRstv, 'enable','on');
set(handles.push_applyMVDR_atf, 'enable','on');


% --- Executes when user attempts to close figure1.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject    handle to figure1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: delete(hObject) closes the figure
delete(hObject);
clear all


% --- Executes on button press in h_closeAll.
function h_closeAll_Callback(hObject, eventdata, handles)
global main
global FLAGS
FLAGS_define;

if isfield(main, 'fig_handles')
    if isfield(main.fig_handles,'DSB')
        delete(main.fig_handles.DSB);
        FLAGS(flag_fig_DSB) = 0;
    end
    if isfield(main.fig_handles,'spectra')
        delete(main.fig_handles.spectra);
        FLAGS(flag_fig_spectra) = 0;
    end
    
end
